-*- mode: outline; outline-regexp: " *\\[" -*- [Current difficulties] [Non-static object manager problem] CE uses non-static object manager. However, there seems to be another global object manager hanging somewhere and it gets deleted when a windows program is shutting down. As the real object manager has already been destructed when the ACE worker thread exits, this causes Access Violations. So far, this doesn't really affect my work so I'll defer it to a later point. [Bugs in cross compiler for SH series CPU] [Inline functions] are not supported at least for debug build for DLL. I have to un-inline _all_ inline functions in ACE to get it to work. Not sure if inlining works for Release version or other CPUs (namely, MIPS series.) It appears to work fine for x86 emulator. [Lost string literals] The following format string in ACE_OS::ctime_r was misteriously replaced with garbage by SH compiler: ACE_OS::sprintf (buf, __TEXT ("%3s %3s %02d %02d:%02d:%02d %04d\n"),..... The solution for this is to define the format string in global namespace as: static const ASYS_TCHAR *fmtstr = __TEXT ("%3s %3s %02d %02d:%02d:%02d %04d\n"); And call the sprintf as: ACE_OS::sprintf (buf, fmtstr,....); There doesn't seem to be any recognizable pattern on how this will happen (otherwise, I'll call this a feature.) [Hints on writing portable code using ACE] [Testing Non-Window based ACE programs] Rumor has it that Microsoft will provide a DOS shell in their next release of CE. Oh well, I made it up and there'll probably no DOS prompt in the future CE. All current ACE programs are text-based. They all need a shell to start from. [Dialog Based] This is a collection of files that combined with any ACE program to run on CE. To use this template, compile your main project with all the cpp and rc files under $ACE_ROOT/windoezCE/. The program will start by asking you the command line argument that you want to pass to the original ACE program. We should be able to get this infomation automatically if we execute the program from "Start -> Run...". However, that'll require us to implement this window using Win32 API (it's written with MFC classes now.) Notice that GetCommandLine is not available on CE. [Future Improvement] Get the command line argument automatically. Buffered keyboard input (stdin.) Scrollable output. [Unicode Trivia] Since most APIs take wide char strings as their arguments when strings are needed, some pre-cautions must be taken... Here are some macros that help converting string types back and forth based on your platform settings. Here, under CE is equivalent to have ACE_HAS_MOSTLY_UNICODE_APIS defined. [ASYS_TCHAR] Defined as wchar_t under CE, but as char under all other paltforms. [ASYS_TEXT] A macro that converts a char text to a wchar text only under CE. [ASYS_WIDE_STRING] A macro that converts char strings to wchar strings using ACE_WString only when ACE_HAS_MOSTLY_UNICODE_APIS is defined. [ASYS_MULTIBYTE_STRING] A macro that converts wchar strings to char strings using ACE_WString while ACE_HAS_MOSTLY_UNICODE_APIS is not defined but UNICODE is defined. [ASYS_ONLY_MULTIBYTE_STRING] Like ASYS_MULTIBYTE_STRING but only convert a string when ACE_HAS_MOSTLY_UNICODE_APIS defined and UNICODE not defined. [ACE_TRACE] When using ACE_TRACE macros, you don't need to use wide char string in it. ACE converts the char string to wchar string for you. [CE Toolkit issues] [CE Toolkit] Using CE toolkit for C++ is simply a pain in the ass. It takes around 30 seconds to start up a debug session and 5+ seconds to single step thru a statement. It only allows remote debugging using the serial link but not the network. (BTW, currently, CE only support NE2000 compatible PCMCIA ethernet card.) [SH3 compiler] * The SH3 compiler does not generate string literals when they are used inside a function and when a precompiled header is also used. This problem can be seen when a variable inside a function is defined by initializing it to a string literal. Two solutions are available: - Use a global variable, if you want to initialize it to a string literal, or - Do not use precompiled headers if you initialize a variable, defined inside a function, with a string literal. * The SH3 compiler generates a fatal internal error, when __declspec(dllimport) is used for a class with a virtual function in it. To avoid the internal error, change the imported class to not use any virtual functions. [Tidbits] [FILETIME] Win32's FILETIME format can be converted to struct timeval thru a simple conversion. However, the tricky part here is, FILETIME is the total 100ns elapse since _1601_ (why the heck did Microsoft choose this time?) whereas POSIX timeval gives you the accumulated time in us since 1970. This leads to data overflow in timeval struture which ACE uses internally for its ACE_Time_Value. This also confuses ACE_OS::ctime, which, under CE, is a home-brewed implementation, and corrupt the whole program image. I don't know of a way to deal with this yet except adjusting for the time difference between the two everytime a conversion is necessary. This, of course, doesn't seem to be a good choice. [Status of one-button tests] [Convention of project files settings] Procedures: * Create a new "Win32 Application" project file. It should support the following platforms: WCE x86em, WCE MIPS, and WCE SH3. Notice the project location should Be under $ACE_ROOT/tests/WinCE. * Add the cpp file(s) along with all .cpp and .rc files under $ACE_ROOT/WindozeCE. * Open Project settings. * General Settings are: "Using MFC in a Shared DLL" for all platforms. Both "Intermediate files" and "Output files" should be the same path. They should be one of "x86emDbg", "WMIPSDbg", and "WCESHDbg" depend on the target platform. * "C/C++" Settings: Add "ACE_HAS_DLL=1", "ACE_HAS_WINCE" to preprocessor definitions for all target platforms. Set "Code Generation" -> "Use run-time library" to "Debug Multithreaded". Add to "Preprocessor" -> "Additional include directories" the following: "..\,..\..\,..\..\WindozeCE\". * "Link" Settings: Added "aced.lib" into "Input" -> "Object/library modules". Set "Input" -> "Additional library path" according to the target platform. It should one of the following: "..\..\ace\WCE\x86em", "..\..\ace\WCE\MIPS", or, "..\..\ace\WCE\SH". * You are all done. [Legend:] X - test working properly F - compile but doesn't work correctly. C - compilation trouble . - work pending (deferred) N - Not supported by CE [N] Aio_Platform_Test Asynch I/O is not supported on CE. [X] Atomic_Op_Test [X] Barrier_Test [X] Basic_Types_Test [F] Buffer_Stream_Test [F] Conn_Test [X] Enum_Interfaces_Test Sort of working right. (Report get_ip_interface error ;-) [N] Env_Value_Test [X] Future_Test This test seems to run to completion without error but the display hangs before printing out the ending message [X] Handle_Set_Test [X] Hash_Map_Manager_Test [N] IOStream_Test ??? [N] MM_Shared_Memory_Test ??? [F] MT_Reactor_Timer_Test ??? [F] MT_SOCK_Test Hang [X] Map_Manager_Test [F] Mem_Map_Test [X] Message_Block_Test inline functions in auto-generated ctors. [F] Message_Queue_Notifications_Test Hang at termination. [X] Message_Queue_Test [.] Naming_Test Registry is not added into CE yet. [F] Notify_Performance_Test [X] OrdMultiSet_Test [N] Pipe_Test This test will have to rewriten in ACE. [X] Priority_Buffer_Test [N] Priority_Reactor_Test Not supported yet. [X] Priority_Task_Test [N] Process_Mutex_Test Don't know how to start a process as a console application. [N] Process_Strategy_Test Let's skip process related tests for now. [N] Reactor_Exceptions_Test Exceptions are not support on CE. [F] Reactor_Notify_Test Hang at limited notifications test. [F] Reactor_Performance_Test [X] Reactor_Timer_Test [F] Reactors_Test Hang after done_count reaches 0. Reactors were not shutting down. [x] Reader_Writer_Test Seems working. Need to redo the test [F] Recursive_Mutex_Test Looks fine but hang before run to completion [F] SOCK_Connector_Test Hang at program startup [F] SOCK_Test Hang at program startup [N] SPIPE_Test SPIPE is not supported yet. [F] SString_Test [N] SV_Shared_Memory_Test [X] Semaphore_Test Test runs fine but gets Access Violation at program exit [.] Service_Config_Test I don't have confidence on this test.... [X] Sigset_Ops_Test [X] Simple_Message_Block_Test [F] TSS_Test Hang halfway. [X] Task_Test Test runs successfully but hang after the ending messge. [F] Thread_Manager_Test Doesn't terminate (no ending string) [X] Thread_Mutex_Test [X] Thread_Pool_Test [.] Time_Service_Test [X] Time_Value_Test [F] Timer_Queue_Test Hang midway. [.] Tokens_Test [N] UPIPE_SAP_Test [ACE File list] Here is a trace of ACE files about their status on CE. [Legend] (.) Defered. (x) Compiled successfully. (Doesn't mean it will run. ;-) (@) Not compile yet. (T) Template codes. (N) Not planning to support ( ) ??? [ACE] [CORBA] (.) CORBA_Handler.cpp (.) CORBA_Handler.h (.) CORBA_Handler.i (.) CORBA_Ref.cpp (.) CORBA_Ref.h (.) CORBA_Ref.i [Collections] (x) Array.cpp (x) Array.h (x) Array.i (T) Containers.cpp (T) Containers.i (T) Containers.h (T) Hash_Map_Manager.cpp (T) Hash_Map_Manager.h (T) Filecache.cpp (T) Filecache.h (T) Free_List.cpp (T) Free_List.i (T) Free_List.h (T) Managed_Object.cpp (T) Managed_Object.h (T) Managed_Object.i (T) Map_Manager.cpp (T) Map_Manager.h (T) Map_Manager.i (x) Object_Manager.cpp (x) Object_Manager.i (x) Object_Manager.h (x) SString.cpp (x) SString.h (x) SString.i [Concurrency] (x) Activation_Queue.h (x) Activation_Queue.cpp (x) Atomic_Op.i (.) Future.h (.) Future.cpp (x) Method_Object.h (x) Method_Object.cpp (x) Process.cpp (x) Process.h (x) Process.i (x) Process_Manager.cpp (x) Process_Manager.h (x) Process_Manager.i (x) Sched_Params.cpp (x) Sched_Params.h (x) Sched_Params.i (x) Synch.cpp (x) Synch.h (x) Synch.i (x) Synch_Options.cpp (x) Synch_Options.h (x) Synch_Options.i (T) Synch_T.cpp (T) Synch_T.h (T) Synch_T.i (x) Thread.cpp (x) Thread.h (x) Thread.i (x) Thread_Manager.cpp (x) Thread_Manager.h (x) Thread_Manager.i (x) Token.cpp (x) Token.h (x) Token.i [Config] (x) config.h (x) Basic_Types.cpp (x) Basic_Types.h (x) Basic_Types.i (x) Version.h [Connection] (T) Acceptor.cpp (T) Acceptor.h (T) Acceptor.i (.) Asynch_Acceptor.cpp (.) Asynch_Acceptor.h (.) Asynch_Acceptor.i (x) Asynch_IO.cpp (x) Asynch_IO.h (x) Asynch_IO.i (T) Connector.cpp (T) Connector.h (T) Connector.i (T) Dynamic_Service.cpp (T) Dynamic_Service.h (T) Dynamic_Service.i (x) Strategies.cpp (x) Strategies.h (x) Strategies.i (T) Strategies_T.cpp (T) Strategies_T.h (T) Strategies_T.i (T) Svc_Handler.cpp (T) Svc_Handler.h (T) Svc_Handler.i [IPC] [IO_SAP] (x) IO_SAP.cpp (x) IO_SAP.h (x) IO_SAP.i [DEV_SAP] (N) DEV.cpp (N) DEV.h (N) DEV.i (N) DEV_Connector.cpp (N) DEV_Connector.h (N) DEV_Connector.i (N) DEV_IO.cpp (N) DEV_IO.h (N) DEV_IO.i (N) TTY_IO.cpp (N) TTY_IO.h [FILE_SAP] (.) FILE.cpp (.) FILE.h (.) FILE.i (.) FILE_Connector.cpp (.) FILE_Connector.h (.) FILE_Connector.i (.) FILE_IO.cpp (.) FILE_IO.h (.) FILE_IO.i [IPC_SAP] (x) IPC_SAP.cpp (x) IPC_SAP.h (x) IPC_SAP.i [Addr] (x) Addr.cpp (x) Addr.h (x) Addr.i (N) DEV_Addr.cpp (N) DEV_Addr.h (N) DEV_Addr.i (.) FILE_Addr.cpp (.) FILE_Addr.h (.) FILE_Addr.i (x) INET_Addr.cpp (x) INET_Addr.h (x) INET_Addr.i (.) SPIPE_Addr.cpp (.) SPIPE_Addr.h (.) SPIPE_Addr.i (N) UNIX_Addr.cpp (N) UNIX_Addr.h (N) UNIX_Addr.i (.) UPIPE_Addr.h [FIFO_SAP] (.) FIFO.cpp (.) FIFO.h (.) FIFO.i (.) FIFO_Recv.cpp (.) FIFO_Recv.h (.) FIFO_Recv.i (.) FIFO_Recv_Msg.cpp (.) FIFO_Recv_Msg.h (.) FIFO_Recv_Msg.i (.) FIFO_Send.cpp (.) FIFO_Send.h (.) FIFO_Send.i (.) FIFO_Send_Msg.cpp (.) FIFO_Send_Msg.h (.) FIFO_Send_Msg.i [SOCK_SAP] ( ) LOCK_SOCK_Acceptor.cpp ( ) LOCK_SOCK_Acceptor.h ( ) LSOCK.cpp ( ) LSOCK.h ( ) LSOCK.i ( ) LSOCK_Acceptor.cpp ( ) LSOCK_Acceptor.h ( ) LSOCK_Acceptor.i ( ) LSOCK_CODgram.cpp ( ) LSOCK_CODgram.h ( ) LSOCK_CODgram.i ( ) LSOCK_Connector.cpp ( ) LSOCK_Connector.h ( ) LSOCK_Connector.i ( ) LSOCK_Dgram.cpp ( ) LSOCK_Dgram.h ( ) LSOCK_Dgram.i ( ) LSOCK_Stream.cpp ( ) LSOCK_Stream.h ( ) LSOCK_Stream.i (x) SOCK.cpp (x) SOCK.h (x) SOCK.i (x) SOCK_Acceptor.cpp (x) SOCK_Acceptor.h (x) SOCK_Acceptor.i (x) SOCK_CODgram.cpp (x) SOCK_CODgram.h (x) SOCK_CODgram.i (x) SOCK_Connector.cpp (x) SOCK_Connector.h (x) SOCK_Connector.i (x) SOCK_Dgram.cpp (x) SOCK_Dgram.h (x) SOCK_Dgram.i (x) SOCK_Dgram_Bcast.cpp (x) SOCK_Dgram_Bcast.h (x) SOCK_Dgram_Bcast.i (x) SOCK_Dgram_Mcast.cpp (x) SOCK_Dgram_Mcast.h (x) SOCK_Dgram_Mcast.i (x) SOCK_IO.cpp (x) SOCK_IO.h (x) SOCK_IO.i (x) SOCK_Stream.cpp (x) SOCK_Stream.h (x) SOCK_Stream.i [SPIPE_SAP] (.) SPIPE.cpp (.) SPIPE.h (.) SPIPE.i (.) SPIPE_Acceptor.cpp (.) SPIPE_Acceptor.h (.) SPIPE_Acceptor.i (.) SPIPE_Connector.cpp (.) SPIPE_Connector.h (.) SPIPE_Connector.i (.) SPIPE_Stream.cpp (.) SPIPE_Stream.h (.) SPIPE_Stream.i [TLI_SAP] (N) TLI.cpp (N) TLI.h (N) TLI.i (N) TLI_Acceptor.cpp (N) TLI_Acceptor.h (N) TLI_Acceptor.i (N) TLI_Connector.cpp (N) TLI_Connector.h (N) TLI_Connector.i (N) TLI_Stream.cpp (N) TLI_Stream.h (N) TLI_Stream.i [UPIPE_SAP] (N) UPIPE_Acceptor.cpp (N) UPIPE_Acceptor.h (N) UPIPE_Acceptor.i (N) UPIPE_Connector.cpp (N) UPIPE_Connector.h (N) UPIPE_Connector.i (N) UPIPE_Stream.cpp (N) UPIPE_Stream.h (N) UPIPE_Stream.i [Utils] (N) IOStream.cpp // CE doesn't have iostream stuff (N) IOStream.h (N) IOStream_T.cpp (N) IOStream_T.h (N) IOStream_T.i (x) Pipe.cpp (x) Pipe.h (x) Pipe.i (x) Signal.cpp (x) Signal.h (x) Signal.i [Logging and Tracing] (x) Dump.cpp (x) Dump.h (x) Dump_T.cpp (T) Dump_T.h (T) Log_Msg.cpp (x) Log_Msg.h (x) Log_Msg.i (x) Log_Priority.h (x) Log_Record.cpp (x) Log_Record.h (x) Log_Record.i (x) Trace.cpp (x) Trace.h (x) Trace.i [Memory] [Mem_Map] (x) Mem_Map.cpp (x) Mem_Map.h (x) Mem_Map.i [Shared_Malloc] (x) Malloc.cpp (x) Malloc.h (x) Malloc.i (T) Malloc_T.cpp (T) Malloc_T.h (T) Malloc_T.i (x) Memory_Pool.cpp (x) Memory_Pool.h (x) Memory_Pool.i [Shared_Memory] ( ) Shared_Memory.h ( ) Shared_Memory_MM.cpp ( ) Shared_Memory_MM.h ( ) Shared_Memory_MM.i ( ) Shared_Memory_SV.cpp ( ) Shared_Memory_SV.h ( ) Shared_Memory_SV.i [Utils] (x) Obstack.cpp (x) Obstack.h (@) Read_Buffer.cpp (@) Read_Buffer.h (@) Read_Buffer.i [Misc] (x) ARGV.cpp (x) ARGV.h (x) ARGV.i (T) Auto_Ptr.cpp (T) Auto_Ptr.h (T) Auto_Ptr.i (x) Dynamic.cpp (x) Dynamic.h (x) Dynamic.i (x) Get_Opt.cpp (x) Get_Opt.h (x) Get_Opt.i (.) Registry.cpp (.) Registry.h (T) Singleton.cpp (T) Singleton.h (T) Singleton.i (x) System_Time.cpp (x) System_Time.h [Name_Service] (.) Local_Name_Space.cpp (.) Local_Name_Space.h (.) Local_Name_Space_T.cpp (.) Local_Name_Space_T.h (.) Name_Options.cpp (.) Name_Options.h (.) Name_Proxy.cpp (.) Name_Proxy.h (.) Name_Request_Reply.cpp (.) Name_Request_Reply.h (.) Name_Space.cpp (.) Name_Space.h (.) Naming_Context.cpp (.) Naming_Context.h (.) Registry_Name_Space.cpp (.) Registry_Name_Space.h (.) Remote_Name_Space.cpp (.) Remote_Name_Space.h [OS Adapters] (x) ACE.cpp (x) ACE.h (x) ACE.i (x) OS.cpp (x) OS.h (x) OS.i [Reactor] (x) Event_Handler.cpp (x) Event_Handler.h (x) Event_Handler.i (T) Event_Handler_T.cpp (T) Event_Handler_T.h (T) Event_Handler_T.i (x) Handle_Set.cpp (x) Handle_Set.h (x) Handle_Set.i ( ) Priority_Reactor.cpp ( ) Priority_Reactor.i ( ) Priority_Reactor.h ( ) Proactor.h ( ) Proactor.i ( ) Proactor.cpp (x) Reactor.cpp (x) Reactor.h (x) Reactor.i (x) Reactor_Impl.h (x) Select_Reactor.cpp (x) Select_Reactor.h (x) Select_Reactor.i (@) WFMO_Reactor.cpp (@) WFMO_Reactor.h (@) WFMO_Reactor.i (x) XtReactor.cpp (x) XtReactor.h [Service_Configurator] (x) Parse_Node.cpp (x) Parse_Node.h (x) Parse_Node.i (x) Service_Config.cpp (x) Service_Config.h (x) Service_Config.i ( ) Service_Main.cpp (x) Service_Manager.cpp (x) Service_Manager.h (x) Service_Manager.i (x) Service_Object.cpp (x) Service_Object.h (x) Service_Object.i (x) Service_Repository.cpp (x) Service_Repository.h (x) Service_Repository.i (x) Service_Types.cpp (x) Service_Types.i (x) Service_Types.h (x) Shared_Object.cpp (x) Shared_Object.h (x) Shared_Object.i (x) Svc_Conf.h (x) Svc_Conf_l.cpp (x) Svc_Conf_y.cpp [Streams] (x) IO_Cntl_Msg.cpp (x) IO_Cntl_Msg.h (x) IO_Cntl_Msg.i (x) Message_Block.cpp (x) Message_Block.h (x) Message_Block.i (T) Message_Queue.cpp (T) Message_Queue.h (T) Message_Queue.i (T) Module.cpp (T) Module.h (T) Module.i (.) Multiplexor.cpp (.) Multiplexor.h (.) Multiplexor.i (T) Stream.cpp (T) Stream.h (T) Stream.i (T) Stream_Modules.cpp (T) Stream_Modules.h (T) Stream_Modules.i (x) Task.cpp (x) Task.h (x) Task.i (T) Task_T.cpp (T) Task_T.h (T) Task_T.i [System_V_IPC] [System_V_Message_Queues] ( ) SV_Message.cpp ( ) SV_Message.h ( ) SV_Message.i ( ) SV_Message_Queue.cpp ( ) SV_Message_Queue.h ( ) SV_Message_Queue.i ( ) Typed_SV_Message.cpp ( ) Typed_SV_Message.h ( ) Typed_SV_Message.i ( ) Typed_SV_Message_Queue.cpp ( ) Typed_SV_Message_Queue.h ( ) Typed_SV_Message_Queue.i [System_V_Semaphores] ( ) SV_Semaphore_Complex.cpp ( ) SV_Semaphore_Complex.h ( ) SV_Semaphore_Complex.i ( ) SV_Semaphore_Simple.cpp ( ) SV_Semaphore_Simple.h ( ) SV_Semaphore_Simple.i [System_V_Shared_Memory] ( ) SV_Shared_Memory.cpp ( ) SV_Shared_Memory.h ( ) SV_Shared_Memory.i [Timers] (x) High_Res_Timer.cpp (x) High_Res_Timer.h (x) High_Res_Timer.i (x) Profile_Timer.cpp (x) Profile_Timer.h (x) Profile_Timer.i (.) Time_Request_Reply.cpp (.) Time_Request_Reply.h (x) Time_Value.h (x) Timer_Hash.cpp (x) Timer_Hash.h (T) Timer_Hash_T.cpp (T) Timer_Hash_T.h (x) Timer_Heap.cpp (x) Timer_Heap.h (x) Timer_Heap.i (T) Timer_Heap_T.cpp (T) Timer_Heap_T.h (T) Timer_Heap_T.i (x) Timer_List.cpp (x) Timer_List.h (x) Timer_List.i (T) Timer_List_T.cpp (T) Timer_List_T.h (T) Timer_List_T.i (x) Timer_Queue.cpp (x) Timer_Queue.h (x) Timer_Queue.i (T) Timer_Queue_Adapters.cpp (T) Timer_Queue_Adapters.h (T) Timer_Queue_Adapters.i (T) Timer_Queue_T.cpp (T) Timer_Queue_T.h (T) Timer_Queue_T.i (x) Timer_Wheel.cpp (x) Timer_Wheel.h (x) Timer_Wheel.i (T) Timer_Wheel_T.cpp (T) Timer_Wheel_T.h (T) Timer_Wheel_T.i [Token_Service] (x) Local_Tokens.cpp (x) Local_Tokens.h (x) Local_Tokens.i (.) Remote_Tokens.cpp (.) Remote_Tokens.h (.) Remote_Tokens.i (.) Token_Collection.cpp (.) Token_Collection.h (.) Token_Collection.i (x) Token_Manager.cpp (x) Token_Manager.h (x) Token_Manager.i (.) Token_Request_Reply.cpp (.) Token_Request_Reply.h (.) Token_Request_Reply.i (.) Token_Invariants.h (.) Token_Invariants.i (.) Token_Invariants.cpp