diff options
57 files changed, 1820 insertions, 894 deletions
diff --git a/ChangeLog-96b b/ChangeLog-96b index 494205f2eca..f491bb000b4 100644 --- a/ChangeLog-96b +++ b/ChangeLog-96b @@ -1,158 +1,270 @@ +Sun Dec 22 12:22:59 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> + + * ace/OS.i (thr_setprio): I forgot to define int policy = 0; + + * ace/SV_Semaphore_Simple.i: Removed the frigging LUSED macro and + updated the ACE_SV_Semaphore_Simple::name_2_key() method to + consider *all* the characters in the name. This will help avoid + nasty bugs when different lock names have a common prefix. + + * ace/Local_Name_Space_T.cpp (ACE_Local_Name_Space): Added a call + to "delete this->lock_" since we now allocate it dynamically. + + * apps/Gateway/Gateway/gatewayd.cpp: Changed call to + ACE_SVC_INVOKE from ACE_Gateway to Gateway. + + * ace/OS.i: In function thr_sigsetmask changed the line: + + #if defined (ACE_HAS_IRIX62_THREADS) + + to + + #if defined (ACE_HAS_IRIX62_THREADS) || defined (ACE_HAS_PTHREADS_XAVIER) + + Thanks to James CE Johnson <jcej@lads.com> for this. + + * ace/config-linux-[lx]pthreads.h: Added a #define for the + ACE_HAS_THREAD_SPECIFIC_STORAGE symbol. Thanks to James CE + Johnson <jcej@lads.com> for this. + + * ace: created a new config file called config-linux-lxpthreads.h. + This contains the ACE #defines necessary to use L. Xavier's + threading package on Linux. Thanks to James CE Johnson + <jcej@lads.com> for this. + + * build/gcc/ace/Synch: Moved the definition of the ACE_*Event + classes *outside* of ACE_HAS_THREADS so that the Proactor will + compile correctly even when there's no threading defined. + + * ace/config-linux-pthread.h: Added #define ACE_MT_SAFE, which + seems to have been missing. Thanks to James Johnson for + suggesting this. + + * tests/TSS_Test.cpp: Now that we've got Chris Lahey's fixes for + AIX we can run this test on AIX. + + * ace/OS.cpp (thr_create): Added a #ifdef for + pthread_attr_setstacksize() for Linux pthreads, which doesn't + seem to support this. Thanks to James CE Johnson + <jcej@lads.com> for this fix. + + * ace/OS.i: Added DCE pthreads fixes for OSF/1 3.2. Thanks to + Harry Gunnarsson <hg@carmenta.se> for these. + +Sat Dec 21 13:54:45 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> + + * ace/Synch_T: Integrated a solution that will allow MVS to use + ACE_TSS. The problem is that the MVS C++ compiler requires an + extern "C" destructor function for pthread_key_delete and the + ACE_TSS stuff uses a paramatized C++ destructor function + (ACE_TSS<TYPE>::cleanup). To solve this, a new class + (ACE_TSS_Adapter) was created that encapsulates a thread + specific object and it's associated C++ destructor. The ACE_TSS + methods were then modified so that they provide access to the + thread specific object through the ACE_TSS_Adapter. Also added + a generic extern "C" cleanup routine that takes an + ACE_TSS_Adapter as an argument. It then calls the adapters + cleanup method passing it the saved address of the thread + specific object. Thanks to Chuck Gehr <gehr@sweng.stortek.com> + for all of this. + + * ace/OS: Updated the code so that it will work with MFC and + AfxBeginThread(). Thanks to Detlef for these changes. + + * ace/README: Added two new #defines for ACE_LACKS_COND_T and + ACE_LACKS_RWLOCK_T to make it possible to define these in a + fine-grained manner for various platforms. + + * ace/OS.h: Restructured the ACE_HAS_THREADS section so that we + factor out the code for ACE_cond_t and ACE_rwlock_t so that it + is only defined if we don't support these features natively. + + * ace/ReactorEx: Added a new "alertable" parameter to the + handle_events() method. If alertable is true, then + WaitForMultipleObjectsEx is used as the demultiplexing call, + otherwise WaitForMultipleObjects is used. + + * ace/Signal.cpp: Had to move a few things around so that the code + would compile for HP/UX. Thanks to Neil B. Cohen + <nbc@metsci.com> for reporting this. + + * ace/Acceptor.cpp: Updated the handle_close() method so that the + Acceptor shuts down the listen socket and prevents handle leaks. + Thanks to Irfan for reporting this. + +Thu Dec 19th 03:48:26 1996 Irfan Pyarali <irfan@flamenco.cs.wustl.edu> + + * ace/Local_Name_Space_T.cpp: Made sure that the mutexes are + getting named properly (both the mutex owned by the + Local_Name_space and the lock owned by the backing + store). For the time being I named these two to be the + extensions of the backing store file name. + + * ace/Local_Name_Space_T.cpp: Replaced the create_manager code + such that we use the double check pattern. This is simpiler + and easy to understand compared to the current code. + + * ace/Naming_Context.cpp: Gave the database name a default value. + + * ace/Malloc_T.cpp: The lock_name should never be 0. This will + cause all instances of the same pool to get different + mutexes. + Sat Dec 21 09:43:35 1996 David L. Levine <levine@cs.wustl.edu> - * ace/OS.{h,i}: fixes for VxWorks introduced in 4.1, and for - inlining: moved #include of OS.i after #defines but before - other ace #includes OS.h OS.i + * ace/OS.{h,i}: fixes for VxWorks introduced in 4.1, and for + inlining: moved #include of OS.i after #defines but before + other ace #includes OS.h OS.i Thu Dec 19 15:58:09 1996 David L. Levine <levine@cs.wustl.edu> - * ace/config-vxworks*.h, include/makeinclude/platform_vxworks*.GNU: - enable inlining on VxWorks by default + * ace/config-vxworks*.h, include/makeinclude/platform_vxworks*.GNU: + enable inlining on VxWorks by default Wed Dec 18 16:44:47 1996 Tim H. Harrison <harrison@lambada.cs.wustl.edu> - * ace/Proactor.cpp (dispatch): Changed this method to take an - int error parameter to set errno just before dispatching. This - allows us to better propagate overlapped I/O errors to the - handlers. + * ace/Proactor.cpp (dispatch): Changed this method to take an + int error parameter to set errno just before dispatching. + This allows us to better propagate overlapped I/O errors to the + handlers. Wed Dec 18 16:21:36 1996 David L. Levine <levine@cs.wustl.edu> - * ace/OS.{h,i} and ace/INET_Addr.cpp: more VxWorks - gethostbyname () tweaks + * ace/OS.{h,i} and ace/INET_Addr.cpp: more VxWorks + gethostbyname () tweaks Wed Dec 18 15:24:13 1996 Tim H. Harrison <harrison@lambada.cs.wustl.edu> - * ace/Proactor.cpp (ACE_Proactor): Initialize completion_port_ to - 0. This is the only way that CreateIoCompletionPort works first - time in. ACE_INVALID_HANDLE makes it break. + * ace/Proactor.cpp (ACE_Proactor): Initialize completion_port_ to + 0. This is the only way that CreateIoCompletionPort works + first time in. ACE_INVALID_HANDLE makes it break. - * (ACE_Proactor): Added a call to CreateIoCompletionPort in the - constructor so that GetQueuedCompletionStatus can be called - before ACE_Proactor::initiate is called. This is necessary if - an application is using the Proactor as a timer mechanism only. + * (ACE_Proactor): Added a call to CreateIoCompletionPort in the + constructor so that GetQueuedCompletionStatus can be called + before ACE_Proactor::initiate is called. This is necessary if + an application is using the Proactor as a timer mechanism only. Tue Dec 18 7:58:07 1996 Tim H. Harrison <harrison@lambada.cs.wustl.edu> - * ace/Proactor.i (get_handle): Changed this to return - ACE_INVALID_HANDLE on non Win32 platforms. Also changed - shared_event_ from an ACE_Manual_Event to an ACE_Auto_Event. - This allows us to remove the call to reset from handle_signal. + * ace/Proactor.i (get_handle): Changed this to return + ACE_INVALID_HANDLE on non Win32 platforms. Also changed + shared_event_ from an ACE_Manual_Event to an ACE_Auto_Event. + This allows us to remove the call to reset from handle_signal. - * examples/Reactor/Proactor/test_timeout.cpp: Added a new example - application to the Proactor example suite. Check the README for - more details. + * examples/Reactor/Proactor/test_timeout.cpp: Added a new example + application to the Proactor example suite. Check the README for + more details. - * examples/Reactor/ReactorEx/test_timeout.cpp: Added a new example - application to the ReactorEx example suite. Check the README for - more details. + * examples/Reactor/ReactorEx/test_timeout.cpp: Added a new example + application to the ReactorEx example suite. Check the README for + more details. - * ace/Service_Config.cpp: Fixed a bug in run_reactorEx_event_loop - (ACE_Time_Value &) so that it doesn't return on timeout. + * ace/Service_Config.cpp: Fixed a bug in run_reactorEx_event_loop + (ACE_Time_Value &) so that it doesn't return on timeout. Tue Dec 18 7:06:32 1996 <harrison@samba.cs.wustl.edu> - * ace/Proactor.cpp (handle_events): Once again removed the - timer_skew_ code. Changed the ACE_HANDLE global_handle_ to - ACE_Manual_Event shared_event_. Added a constructor that takes - an ACE_Timer_Queue *. Changed the implementation to use an - ACE_OS::sleep if only timers are registered. We need to figure - out a better approach than the sleep. + * ace/Proactor.cpp (handle_events): Once again removed the + timer_skew_ code. Changed the ACE_HANDLE global_handle_ to + ACE_Manual_Event shared_event_. Added a constructor that takes + an ACE_Timer_Queue *. Changed the implementation to use an + ACE_OS::sleep if only timers are registered. We need to figure + out a better approach than the sleep. - * ace/Service_Config.cpp (run_proactor_event_loop): Changed this - to only return when an error occurs. If handle_events returns a - 0, then a timeout occurred, and we can continue to dispatch - events. We only return when all of the time has expired. + * ace/Service_Config.cpp (run_proactor_event_loop): Changed this + to only return when an error occurs. If handle_events returns a + 0, then a timeout occurred, and we can continue to dispatch + events. We only return when all of the time has expired. - * ace/Registry_Name_Space.h (ACE_Registry_Name_Space): Moved the - include statements below the ACE_WIN32 and UNICODE directives. + * ace/Registry_Name_Space.h (ACE_Registry_Name_Space): Moved the + include statements below the ACE_WIN32 and UNICODE directives. - * ace/OS.h (siginfo_t): Added siginfo_t (ACE_HANDLE *handle) - constructor prototype. + * ace/OS.h (siginfo_t): Added siginfo_t (ACE_HANDLE *handle) + constructor prototype. Wed Dec 18 06:37:22 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - * ace/OS.i (cond_wait): Added the new algorithm for condition - variable emulation on Win32. (and VxWorks). This should fix the - nasty problems we had with earlier version (which weren't - "fair"). Thanks to James Mansion, Karlheinz, Detlef, and Irfan - for helping with this. + * ace/OS.i (cond_wait): Added the new algorithm for condition + variable emulation on Win32. (and VxWorks). This should fix the + nasty problems we had with earlier version (which weren't + "fair"). Thanks to James Mansion, Karlheinz, Detlef, and Irfan + for helping with this. - * ace/Registry.h: Removed the "ACE_TURN_NOMINMAX_OFF" stuff - in order to simplify the code. Thanks to Irfan for this. + * ace/Registry.h: Removed the "ACE_TURN_NOMINMAX_OFF" stuff + in order to simplify the code. Thanks to Irfan for this. - * ace/OS.i (sema_post): Added a new overloaded version of - ACE_OS::sema_post(), which takes a "release count." This is the - number of times to release the semaphore. Note that Win32 - supports this natively, whereas on POSIX we need to loop... + * ace/OS.i (sema_post): Added a new overloaded version of + ACE_OS::sema_post(), which takes a "release count." This is the + number of times to release the semaphore. Note that Win32 + supports this natively, whereas on POSIX we need to loop... - * ace/Proactor.cpp (handle_events): Changed the Proactor logic so - that it will correctly propagate any errors that occur to the - handle_{input,output}_complete callback. + * ace/Proactor.cpp (handle_events): Changed the Proactor logic so + that it will correctly propagate any errors that occur to the + handle_{input,output}_complete callback. Tue Dec 17 20:56:56 1996 David L. Levine <levine@cs.wustl.edu> - * ace/OS.{h,i}: on VxWorks: implemented ACE_OS::gethostbyname (), - and fixed inet_ntoa () to return -1 on failure + * ace/OS.{h,i}: on VxWorks: implemented ACE_OS::gethostbyname (), + and fixed inet_ntoa () to return -1 on failure - * ace/OS.cpp: in ::spa () for VxWorks, zero out unused argv[] - slots to overwrite args from previous invocations OS.cpp + * ace/OS.cpp: in ::spa () for VxWorks, zero out unused argv[] + slots to overwrite args from previous invocations OS.cpp Tue Dec 17 04:27:07 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - * ace/ReactorEx: Added a new feature to the ReactorEx. If we - enable the wait_all flag when calling - ACE_ReactorEx::handle_events() *and* we give an - ACE_Event_Handler (this is a new final param to the call) then - the handle_signal() call will be invoked on this - "wait_all_callback" object when all the handles become signaled. - Moreover, we pass in the array of signaled handled to through - the siginfo_t parameter (see the following ChangeLog entry for - details). If there is no wait_all_callback param, then all the - handle_signal() methods are invoked on all the handles. - - * ace/OS.h (siginfo_t): Augmented the siginfo_t interface so that - we can pass an array of signaled Win32 HANDLEs, in addition to - just a single HANDLE. This is used in the ReactorEx. - - * examples/Reactor/ReactorEx/test_reactorEx.cpp: Added a number of - enhancements to this test program based on discussions with - Irfan, Karlheinz, Dieter, and Detlef. - - * ace/Task_T.i (msg_queue): If we override the existing definition - of the Message_Queue in an ACE_Task then we need to delete the - existing Message_queue (if necessary and mark the Message_Queue - as no longer being a candidate for deletion (since we have - supplied our own definition). Irfan had added this earlier, but - it seemed to get lost... - - * examples/Reactor/Proactor/test_proactor.cpp: The class called - STDIN_HANDLEr is misnamed since we don't read from stdin, we - read from a file. Therefore, I've changed this to be - Input_File_Handler. - - * examples/Reactor/ReactorEx/test_{proactor,reactorEx}.cpp: - Changed misspellings of transfered to transferred. - - * ace/Memory_Pool.cpp (ACE_MMAP_Memory_Pool): Since NT doesn't support - SIGSEGV thre's no point in even trying to register for this - signal! - - * ace/OS.i: Reverted some lost UNICODE fixes -- thanks to Irfan - for finding these. - - * ace/Local_Name_Space_T.cpp (create_manager_i): Removed a - debug statement since it may be causing problems with printing - UNICODE. + * ace/ReactorEx: Added a new feature to the ReactorEx. If we + enable the wait_all flag when calling + ACE_ReactorEx::handle_events() *and* we give an + ACE_Event_Handler (this is a new final param to the call) then + the handle_signal() call will be invoked on this + "wait_all_callback" object when all the handles become signaled. + Moreover, we pass in the array of signaled handled to through + the siginfo_t parameter (see the following ChangeLog entry for + details). If there is no wait_all_callback param, then all the + handle_signal() methods are invoked on all the handles. + + * ace/OS.h (siginfo_t): Augmented the siginfo_t interface so that + we can pass an array of signaled Win32 HANDLEs, in addition to + just a single HANDLE. This is used in the ReactorEx. + + * examples/Reactor/ReactorEx/test_reactorEx.cpp: Added a number of + enhancements to this test program based on discussions with + Irfan, Karlheinz, Dieter, and Detlef. + + * ace/Task_T.i (msg_queue): If we override the existing definition + of the Message_Queue in an ACE_Task then we need to delete the + existing Message_queue (if necessary and mark the Message_Queue + as no longer being a candidate for deletion (since we have + supplied our own definition). Irfan had added this earlier, but + it seemed to get lost... + + * examples/Reactor/Proactor/test_proactor.cpp: The class called + STDIN_HANDLEr is misnamed since we don't read from stdin, we + read from a file. Therefore, I've changed this to be + Input_File_Handler. + + * examples/Reactor/ReactorEx/test_{proactor,reactorEx}.cpp: + Changed misspellings of transfered to transferred. + + * ace/Memory_Pool.cpp (ACE_MMAP_Memory_Pool): Since NT doesn't support + SIGSEGV thre's no point in even trying to register for this + signal! + + * ace/OS.i: Reverted some lost UNICODE fixes -- thanks to Irfan + for finding these. + + * ace/Local_Name_Space_T.cpp (create_manager_i): Removed a + debug statement since it may be causing problems with printing + UNICODE. Mon Dec 16 11:25:55 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - * ace/OS.i (cuserid): Fixed the definition to ACE_OS::cuserid() so - that it uses LPTSTR. Thanks to Irfan for this fix. + * ace/OS.i (cuserid): Fixed the definition to ACE_OS::cuserid() so + that it uses LPTSTR. Thanks to Irfan for this fix. - * ace/Task.cpp (activate): In ACE_Task::activate() there is a possibility to actually - "reactivate" the task using the <force_activate> flag. The following - illustrates that ability: + * ace/Task.cpp (activate): In ACE_Task::activate() there is a possibility to actually + "reactivate" the task using the <force_activate> flag. The following + illustrates that ability: if (this->thr_count_ > 0 && force_active == 0) return 1; // Already active. @@ -160,7 +272,7 @@ Mon Dec 16 11:25:55 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> this->thr_count_ = n_threads; The thing is that, when the task is running and we reactivate it - (actually we add threads) the command should be: + (actually we add threads) the command should be: this->thr_count_ += n_threads; @@ -169,358 +281,358 @@ Mon Dec 16 11:25:55 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> this->thr_count_ = n_threads; That way <this->thr_count_> holds the new number of threads currently - associated with the task. Thanks to Hamual for this fix. + associated with the task. Thanks to Hamual for this fix. - * ace/OS.i (inet_aton): Placed the return 1 within the curly - braces to make the HP/UX compiler happy. Thanks to Kenny Want - for reporting this. + * ace/OS.i (inet_aton): Placed the return 1 within the curly + braces to make the HP/UX compiler happy. Thanks to Kenny Want + for reporting this. Mon Dec 16 12:56:43 1996 David L. Levine <levine@cs.wustl.edu> - * ace/OS.i: removed spurious "*/" after an #endif. Thanks to - Harry Gunnarsson <hg@carmenta.se> for reporting this. + * ace/OS.i: removed spurious "*/" after an #endif. Thanks to + Harry Gunnarsson <hg@carmenta.se> for reporting this. - * ace/Svc_Conf_l.cpp: #ifdef'ed out ace_yyunput () and - ace_yy_{push,pop,top}_state () because they're not used, - and commented out a few "break"s after "return"s in switch - statements to prevent compiler warnings. + * ace/Svc_Conf_l.cpp: #ifdef'ed out ace_yyunput () and + ace_yy_{push,pop,top}_state () because they're not used, + and commented out a few "break"s after "return"s in switch + statements to prevent compiler warnings. - * ace/Typed_SV_Message.i: reordered initializations in ctor to - match declaration order. + * ace/Typed_SV_Message.i: reordered initializations in ctor to + match declaration order. - * examples/Threads/Makefile, performance-tests/Misc/Makefile, - tests/Makefile: - Removed "LIBS += -lm" from these Makefiles because it doesn't - appear to be necessary, and not all platforms have a libm. + * examples/Threads/Makefile, performance-tests/Misc/Makefile, + tests/Makefile: + Removed "LIBS += -lm" from these Makefiles because it doesn't + appear to be necessary, and not all platforms have a libm. - * include/makeinclude/platform_sunos4_g++.GNU, platform_sunos5_g++.GNU, - platform_sunos5_x86_g++.GNU, platform_unixware_g++.GNU: - added -lm to LIBS because it was removed from the Makefiles, and - it's needed with g++. + * include/makeinclude/platform_sunos4_g++.GNU, platform_sunos5_g++.GNU, + platform_sunos5_x86_g++.GNU, platform_unixware_g++.GNU: + added -lm to LIBS because it was removed from the Makefiles, and + it's needed with g++. - * netsvcs/lib/Makefile: removed /pkg/gnu/lib dependencies. Thanks - to Per Andersson <Per.Andersson@hfera.ericsson.se> for pointing - this out. + * netsvcs/lib/Makefile: removed /pkg/gnu/lib dependencies. Thanks + to Per Andersson <Per.Andersson@hfera.ericsson.se> for pointing + this out. - * netsvcs/servers/svc.conf: changed _make_ACE_Logger() to - _make_ACE_Logging_Strategy() svc.conf. Thanks to Per Andersson - <Per.Andersson@hfera.ericsson.se> for reporting this. + * netsvcs/servers/svc.conf: changed _make_ACE_Logger() to + _make_ACE_Logging_Strategy() svc.conf. Thanks to Per Andersson + <Per.Andersson@hfera.ericsson.se> for reporting this. Sun Dec 15 13:01:17 1996 David L. Levine <levine@cs.wustl.edu> - * ace/Naming_Context.cpp: reordered initializations in default ctor - to match declaration order. + * ace/Naming_Context.cpp: reordered initializations in default ctor + to match declaration order. - * ace/Svc_Conf_y.cpp: added parens to a couple of combined - assignments/conditionals to avoid compiler warnings. + * ace/Svc_Conf_y.cpp: added parens to a couple of combined + assignments/conditionals to avoid compiler warnings. - * include/makeinclude/platform_sunos5_sunc++*.GNU: reverted - SOLINK step back to creating real .so files, because it - seems to be necessary, sometimes, for template instantiation. + * include/makeinclude/platform_sunos5_sunc++*.GNU: reverted + SOLINK step back to creating real .so files, because it + seems to be necessary, sometimes, for template instantiation. - * netsvcs/lib/Server_Logging_Handler.cpp: removed ACE_INLINE's. + * netsvcs/lib/Server_Logging_Handler.cpp: removed ACE_INLINE's. - * tests/MM_Shared_Memory_Test.cpp: declare shm_key as char[] - instead of char *, so that the string gets put into the data - segment rather than the text segment. The string gets modified, - which causes a core dump with the g++/SunOS5.5 build if the string - is in the text segment. + * tests/MM_Shared_Memory_Test.cpp: declare shm_key as char[] + instead of char *, so that the string gets put into the data + segment rather than the text segment. The string gets modified, + which causes a core dump with the g++/SunOS5.5 build if the string + is in the text segment. Sun Dec 15 10:29:20 1996 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> - * netsvcs/servers/svc.conf: Removed the "lib" prefix for the - netsvcs DLL. This is now added automatically by the - ACE::ldfind() operation. + * netsvcs/servers/svc.conf: Removed the "lib" prefix for the + netsvcs DLL. This is now added automatically by the + ACE::ldfind() operation. - * ace/SString.cpp (ACE_CString): Removed the #pragmas for Win32. - They aren't necessary since we should replace the ACE_USHORT16 - cast with a char cast. Thanks to Amos Shapira <amos@dsi.co.il> - for reporting this. + * ace/SString.cpp (ACE_CString): Removed the #pragmas for Win32. + They aren't necessary since we should replace the ACE_USHORT16 + cast with a char cast. Thanks to Amos Shapira <amos@dsi.co.il> + for reporting this. Sat Dec 14 14:25:38 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - * build/SunOS5.5/tests/UPIPE_SAP_Test.cpp (main): Fixed several - minor bugs with UPIPE_SAP_Test.cpp. + * build/SunOS5.5/tests/UPIPE_SAP_Test.cpp (main): Fixed several + minor bugs with UPIPE_SAP_Test.cpp. - * ace/OS.i (thr_join): Added implementations for Solaris threads - and most versions of POSIX pthreads where ACE_hthread_t and - ACE_thread_t are the same type! + * ace/OS.i (thr_join): Added implementations for Solaris threads + and most versions of POSIX pthreads where ACE_hthread_t and + ACE_thread_t are the same type! - * ace/OS: Began adding hooks so that we can eventually move away - from the current split between ACE_thread_t and ACE_hthread_t - and unify them via ACE_Thread_ID. + * ace/OS: Began adding hooks so that we can eventually move away + from the current split between ACE_thread_t and ACE_hthread_t + and unify them via ACE_Thread_ID. - * ace/{OS,Thread}.h: Changed the interface of thr_getprio() so - that it takes an int & rather than an int *. + * ace/{OS,Thread}.h: Changed the interface of thr_getprio() so + that it takes an int & rather than an int *. - * ace/OS.i (thr_getprio): Fixed a minor bug for Win32 where we - weren't depositing the thread priority into the return value! + * ace/OS.i (thr_getprio): Fixed a minor bug for Win32 where we + weren't depositing the thread priority into the return value! - * Makefile: Changed the order in which things are built so that - netsvcs are built right after libACE, followed by the tests. + * Makefile: Changed the order in which things are built so that + netsvcs are built right after libACE, followed by the tests. Sat Dec 14 11:54:22 1996 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> - * apps/Gateway/Gateway/Consumer_Map: Change the Consumer_Map class - so that it was no longer templatized. There isn't any point in - doing this since we aren't going to be changing these types for - this application. + * apps/Gateway/Gateway/Consumer_Map: Change the Consumer_Map class + so that it was no longer templatized. There isn't any point in + doing this since we aren't going to be changing these types for + this application. - * apps/Gateway/Gateway: Factored out the code for selecting the - concurrency strategy into a separate *.h file called - Concurrency_Strategy.h. + * apps/Gateway/Gateway: Factored out the code for selecting the + concurrency strategy into a separate *.h file called + Concurrency_Strategy.h. - * apps/Gateway/Gateway: Began revising the Gateway application to - use the new ACE Event Channel. + * apps/Gateway/Gateway: Began revising the Gateway application to + use the new ACE Event Channel. - * ace/Svc_Handler: Now that we've got put() and svc() with no-op - defaults in class ACE_Task_Base, we don't need them in - ACE_Svc_Handler anymore, so I removed them! + * ace/Svc_Handler: Now that we've got put() and svc() with no-op + defaults in class ACE_Task_Base, we don't need them in + ACE_Svc_Handler anymore, so I removed them! - * ace/Task: Finally got sick of having to provide no-op - open()/put()/close() routines in all ACE_Task subclasses, so I - changed these methods from pure virtual to virtual with default - no-op behavior. Updated all the tests, as well. + * ace/Task: Finally got sick of having to provide no-op + open()/put()/close() routines in all ACE_Task subclasses, so I + changed these methods from pure virtual to virtual with default + no-op behavior. Updated all the tests, as well. Sat Dec 14 11:39:15 1996 David L. Levine <levine@cs.wustl.edu> - * ace/{Module,Stream,Svc_Handler,Synch_T,Task_T}.cpp and Synch_T.i: - removed ACE_INLINE qualifier from functions in .cpp files; in - the case of Synch_T, moved ACE_INLINE functions from .cpp to .i file + * ace/{Module,Stream,Svc_Handler,Synch_T,Task_T}.cpp and Synch_T.i: + removed ACE_INLINE qualifier from functions in .cpp files; in + the case of Synch_T, moved ACE_INLINE functions from .cpp to .i file - * apps/Gateway/Gateway/Routing_Table.cpp, - examples/ASX/Event_Server/Event_Server/Peer_Router.cpp, - examples/ASX/UPIPE_Event_Server/Peer_Router.cpp: - removed ACE_INLINEs from .cpp files + * apps/Gateway/Gateway/Routing_Table.cpp, + examples/ASX/Event_Server/Event_Server/Peer_Router.cpp, + examples/ASX/UPIPE_Event_Server/Peer_Router.cpp: + removed ACE_INLINEs from .cpp files - * ace/CORBA_Handler.h and ace/Token_Collection.{h,cpp}: - changed __INLINE__ to __ACE_INLINE__ + * ace/CORBA_Handler.h and ace/Token_Collection.{h,cpp}: + changed __INLINE__ to __ACE_INLINE__ - * ace/Svc_Conf_y.cpp: commented out unused arguments to - suppress compiler complaints + * ace/Svc_Conf_y.cpp: commented out unused arguments to + suppress compiler complaints Fri Dec 13 22:07:11 1996 David L. Levine <levine@cs.wustl.edu> - * include/makeinclude/platform_sunos5_sunc++*.GNU: replaced - SOLINK step in build of shared objects for SunOS5 with SunC++ - with symlink from .so to .o file. + * include/makeinclude/platform_sunos5_sunc++*.GNU: replaced + SOLINK step in build of shared objects for SunOS5 with SunC++ + with symlink from .so to .o file. - * ace/config-vxworks*.h: added ACE_NEEDS_SYSTIME_H to VxWorks - configs because it's needed with inlining + * ace/config-vxworks*.h: added ACE_NEEDS_SYSTIME_H to VxWorks + configs because it's needed with inlining - * include/makeinclude/platform_vxworks*.GNU: cleaned up VxWorks - config files + * include/makeinclude/platform_vxworks*.GNU: cleaned up VxWorks + config files Fri Dec 13 00:53:34 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - * ace: Replaced all uses of - - #if defined (.....) // .... - - with - - #if defined (.....) /* ... */ + * ace: Replaced all uses of + + #if defined (.....) // .... + + with + + #if defined (.....) /* ... */ - so that broken C++ compilers won't complain. Thanks to - John Cosby <John.D.Cosby@cpmx.saic.com> for reporting this. + so that broken C++ compilers won't complain. Thanks to + John Cosby <John.D.Cosby@cpmx.saic.com> for reporting this. - * ace/Thread.i: Updated the signature of getprio() and setprio() - so that they take ACE_hthread_t. Thanks to Wayne Vucenic - <wvucenic@netgate.net> for finding this. + * ace/Thread.i: Updated the signature of getprio() and setprio() + so that they take ACE_hthread_t. Thanks to Wayne Vucenic + <wvucenic@netgate.net> for finding this. - * Reran all the tests on NT and Solaris. Everything seems to - work. Therefore, incremented the version number to 4.1 and put - it out for ftp and http. + * Reran all the tests on NT and Solaris. Everything seems to + work. Therefore, incremented the version number to 4.1 and put + it out for ftp and http. Thu Dec 12 18:51:04 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - * tests/Priority_Task_Test.cpp (svc): Added a new test to exercise - the new "priority" feature of ACE_OS::thr_create() - (which is also available to ACE_Task). + * tests/Priority_Task_Test.cpp (svc): Added a new test to exercise + the new "priority" feature of ACE_OS::thr_create() + (which is also available to ACE_Task). - * ace/Thread: Added getprio() and setprio() methods to ACE_Thread. + * ace/Thread: Added getprio() and setprio() methods to ACE_Thread. Fri Dec 13 13:44:12 1996 David L. Levine <levine@cs.wustl.edu> - * ace/config-vxworks*.h: added ACE_NEEDS_SYSTIME_H to VxWorks - configs because it's needed with inlining + * ace/config-vxworks*.h: added ACE_NEEDS_SYSTIME_H to VxWorks + configs because it's needed with inlining - * include/makeinclude/platform_vxworks*.GNU: cleaned up VxWorks - config files + * include/makeinclude/platform_vxworks*.GNU: cleaned up VxWorks + config files Thu Dec 12 18:51:04 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - * ace: Added a new macro called ACE_UNUSED_ARG() to keep - the compiler from outputting warnings about unused - arguments. So far, this is mostly done for Win32, but it - should be easy to do it for other compilers. Thanks - to Matthias for these changes. + * ace: Added a new macro called ACE_UNUSED_ARG() to keep + the compiler from outputting warnings about unused + arguments. So far, this is mostly done for Win32, but it + should be easy to do it for other compilers. Thanks + to Matthias for these changes. - * ace/OS.cpp: Added support so that thread priorities will - automatically be set when we spawn threads using - ACE_OS::thr_create(). + * ace/OS.cpp: Added support so that thread priorities will + automatically be set when we spawn threads using + ACE_OS::thr_create(). - * ace/OS.cpp: Simplified the logic for handling NULL thr_handles - and thr_ids. Now, we set all this stuff in one place at the - beginning of the function, rather than recomputing it all over - the place. + * ace/OS.cpp: Simplified the logic for handling NULL thr_handles + and thr_ids. Now, we set all this stuff in one place at the + beginning of the function, rather than recomputing it all over + the place. - * ace/config-aix-{3.2.5,4.1.x}.h: Added the - ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS flag. + * ace/config-aix-{3.2.5,4.1.x}.h: Added the + ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS flag. - * ace/Thread_Manager.cpp (ACE_Thread_Control): Conditionally - compiled the logic for calling this->exit() in the destructor - for ACE_Thread_Control so that we only make this call if - ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS is *not* set. This will - prevent infinite recursion on platforms like AIX. Thanks to - Chris Lahey for reporting this. + * ace/Thread_Manager.cpp (ACE_Thread_Control): Conditionally + compiled the logic for calling this->exit() in the destructor + for ACE_Thread_Control so that we only make this call if + ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS is *not* set. This will + prevent infinite recursion on platforms like AIX. Thanks to + Chris Lahey for reporting this. - * apps/Gateway/Gateway/Channel.cpp (recv_peer): Added the logic - that makes sure we don't get screwed up by partial headers. - Thanks to Chris Cleeland for this. + * apps/Gateway/Gateway/Channel.cpp (recv_peer): Added the logic + that makes sure we don't get screwed up by partial headers. + Thanks to Chris Cleeland for this. Thu Dec 12 20:55:02 1996 David L. Levine <levine@cs.wustl.edu> - * include/makeinclude/platform_sunos5_sunc++*.GNU: removed - SOLINK step in build of shared objects for SunOS5 with SunC++: - it's not necessary. + * include/makeinclude/platform_sunos5_sunc++*.GNU: removed + SOLINK step in build of shared objects for SunOS5 with SunC++: + it's not necessary. Thu Dec 12 03:48:26 1996 Irfan Pyarali <irfan@flamenco.cs.wustl.edu> - * ace/Naming_Context: Modified ACE_Naming such that on Win32, you - can use ACE_Registry_Name_Space. - - * ace/Registry_Name_Space: ACE_Registry_Name_Space is a Name_Space - which uses ACE_Registry as the persistence mechanism. Win32 - clients of ACE_Naming can now start using (the more robust and - reliable) Registry persistence without any major code changes. + * ace/Naming_Context: Modified ACE_Naming such that on Win32, you + can use ACE_Registry_Name_Space. + + * ace/Registry_Name_Space: ACE_Registry_Name_Space is a Name_Space + which uses ACE_Registry as the persistence mechanism. Win32 + clients of ACE_Naming can now start using (the more robust and + reliable) Registry persistence without any major code changes. - * tests/Naming_Test.cpp: Added the use of Registry_Name_Space to - the test if we are on Win32 and UNICODE is turned on. + * tests/Naming_Test.cpp: Added the use of Registry_Name_Space to + the test if we are on Win32 and UNICODE is turned on. - * examples/Registry: Fixed UNICODE behavior of the tests + * examples/Registry: Fixed UNICODE behavior of the tests Wed Dec 11 20:33:28 1996 Douglas C. Schmidt <schmidt@lindy.cs.wustl.edu> - * ace/Synch_T.h: Added a warning that indicates why it isn't - possible to use ACE_Process_Condition<ACE_Process_Mutex> on - Win32... + * ace/Synch_T.h: Added a warning that indicates why it isn't + possible to use ACE_Process_Condition<ACE_Process_Mutex> on + Win32... - * tests/TSS_Test.cpp: Moved the Errno class to a file - TSS_Test_Errno.h and replaced the Errno class with the #include - "TSS_Test_Errno.h" to work around "features" with AIX C++'s - template instantiation scheme. + * tests/TSS_Test.cpp: Moved the Errno class to a file + TSS_Test_Errno.h and replaced the Errno class with the #include + "TSS_Test_Errno.h" to work around "features" with AIX C++'s + template instantiation scheme. - * ace/OS.i (inet_aton): Replaced the use of ((ACE_UINT32) -1) with - ((ACE_UINT32) ~0). I expect this is more portable... + * ace/OS.i (inet_aton): Replaced the use of ((ACE_UINT32) -1) with + ((ACE_UINT32) ~0). I expect this is more portable... - * tests/run_tests.bat: Added "Service_Config_Test" to the - run_tests.bat file. + * tests/run_tests.bat: Added "Service_Config_Test" to the + run_tests.bat file. Tue Dec 10 22:59:26 1996 Irfan Pyarali <irfan@flamenco.cs.wustl.edu> - * tests: Added Service_Config_Test to Win32 makefiles. + * tests: Added Service_Config_Test to Win32 makefiles. - * ace/OS.i (inet_aton): We need to cast htonl to (long) + * ace/OS.i (inet_aton): We need to cast htonl to (long) - * tests: Added/Fixed UNICODE behavior of the following: + * tests: Added/Fixed UNICODE behavior of the following: - MM_Shared_Memory_Test.cpp - Mem_Map_Test.cpp - Mutex_Test.cpp - Naming_Test.cpp - Process_Mutex_Test.cpp - SPIPE_Test.cpp - Time_Service_Test.cpp - Tokens_Test.cpp - UPIPE_SAP_Test.cpp + MM_Shared_Memory_Test.cpp + Mem_Map_Test.cpp + Mutex_Test.cpp + Naming_Test.cpp + Process_Mutex_Test.cpp + SPIPE_Test.cpp + Time_Service_Test.cpp + Tokens_Test.cpp + UPIPE_SAP_Test.cpp - * netsvcs/lib: Added/Fixed UNICODE behavior of the following: - ACE_TS_Clerk_Processor::poolname_ - + * netsvcs/lib: Added/Fixed UNICODE behavior of the following: + ACE_TS_Clerk_Processor::poolname_ + Tue Dec 10 00:33:08 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> - * tests/Service_Config_Test.cpp (main): Added a new method called - run_test() to ensure that ACE_Service_Config daemon is destroyed - before we try to end the test. + * tests/Service_Config_Test.cpp (main): Added a new method called + run_test() to ensure that ACE_Service_Config daemon is destroyed + before we try to end the test. - * ace/OS.i (inet_aton): We need to cast -1 to (ACE_UINT32). + * ace/OS.i (inet_aton): We need to cast -1 to (ACE_UINT32). - * tests/Process_Mutex_Test.cpp (main): Added a minor change to - make gcc happy by moving the definition of int i *outside* the - loop. Thanks to Thilo Kielmann - <kielmann@informatik.uni-siegen.de> for reporting this. + * tests/Process_Mutex_Test.cpp (main): Added a minor change to + make gcc happy by moving the definition of int i *outside* the + loop. Thanks to Thilo Kielmann + <kielmann@informatik.uni-siegen.de> for reporting this. - * ace/OS.h: gcc complains about memcmp, memcpy, strcmp, and strcpy - (from ACE_OS::) being used before defined inline. This is due - to the include of SString.h at the end of OS.h. So I reordered - things in accordance to the changes from Thilo Kielmann - <kielmann@informatik.uni-siegen.de>. + * ace/OS.h: gcc complains about memcmp, memcpy, strcmp, and strcpy + (from ACE_OS::) being used before defined inline. This is due + to the include of SString.h at the end of OS.h. So I reordered + things in accordance to the changes from Thilo Kielmann + <kielmann@informatik.uni-siegen.de>. - * build/SunOS5.5/examples/Shared_Malloc/test_multiple_mallocs.cpp: - Changed the definition of char *base_addr to void *base_addr. + * build/SunOS5.5/examples/Shared_Malloc/test_multiple_mallocs.cpp: + Changed the definition of char *base_addr to void *base_addr. - * ace/Memory_Pool.cpp (ACE_MMAP_Memory_Pool_Options): Changed the - definition of char *base_addr to void *base_addr. + * ace/Memory_Pool.cpp (ACE_MMAP_Memory_Pool_Options): Changed the + definition of char *base_addr to void *base_addr. - * Put out what is hopefully the final beta release of 4.0.33. + * Put out what is hopefully the final beta release of 4.0.33. - * ace/Message_Queue: Added the enqueue() method again to maintain - backwards compatibility. Thanks to Karlheinz for pointing out - the need for this. + * ace/Message_Queue: Added the enqueue() method again to maintain + backwards compatibility. Thanks to Karlheinz for pointing out + the need for this. - * ace/Service_Config.h: The svc.conf factory functions were - begin defined as extern "C", but the function pointer defined in - the ACE_Static_Svc_Descriptor struct is not declared as extern - "C", therefore, there was a mismatch. Here's how to fix this: + * ace/Service_Config.h: The svc.conf factory functions were + begin defined as extern "C", but the function pointer defined in + the ACE_Static_Svc_Descriptor struct is not declared as extern + "C", therefore, there was a mismatch. Here's how to fix this: - In Service_Config.h, before the struct ACE_Static_Svc_Descriptor - add: + In Service_Config.h, before the struct ACE_Static_Svc_Descriptor + add: extern "C" { - typedef ACE_Service_Object *(*ACE_SERVICE_ALLOCATOR)(void); - } + typedef ACE_Service_Object *(*ACE_SERVICE_ALLOCATOR)(void); + } Then in the struct alloc_ field was changed as follows: from: ACE_Service_Object *(*alloc_)(void); - to: ACE_SERVICE_ALLOCATOR alloc_; + to: ACE_SERVICE_ALLOCATOR alloc_; Thanks to Chuck Gehr for this. - * ace/Memory_Pool.cpp (commit_backing_store_name): Changed uses of - "counter" from int to size_t to remove warnings. + * ace/Memory_Pool.cpp (commit_backing_store_name): Changed uses of + "counter" from int to size_t to remove warnings. - * ace/ACE.cpp: Reimplemented the ACE::daemonize() method to - conform to the latest version in Richard Steven's new UNP book. + * ace/ACE.cpp: Reimplemented the ACE::daemonize() method to + conform to the latest version in Richard Steven's new UNP book. - * ace/INET_Addr.cpp (set): Replaced the use of ACE_OS::inet_addr() - with ACE_OS::inet_aton(). Thanks to W. Richard Stevens for this - idea ;-). + * ace/INET_Addr.cpp (set): Replaced the use of ACE_OS::inet_addr() + with ACE_OS::inet_aton(). Thanks to W. Richard Stevens for this + idea ;-). - * ace/OS: Added a new function called inet_aton(), which is based - on a new POSIX socket addressing function that is non-ambiguous - in its return value (unlike inet_addr). + * ace/OS: Added a new function called inet_aton(), which is based + on a new POSIX socket addressing function that is non-ambiguous + in its return value (unlike inet_addr). - * tests: Added a new Service_Config_Test.cpp to make sure that the - timeout features mentioned below work. + * tests: Added a new Service_Config_Test.cpp to make sure that the + timeout features mentioned below work. - * ace/Service_Config.cpp: Changed the implementation of - run_{reactor,proactor,reactorEx}_event_loop so that it returns - if the corresponding handle_events() method times out. - Thanks to Phil Logan <phill@in.ot.com.au> for reporting - this. + * ace/Service_Config.cpp: Changed the implementation of + run_{reactor,proactor,reactorEx}_event_loop so that it returns + if the corresponding handle_events() method times out. + Thanks to Phil Logan <phill@in.ot.com.au> for reporting + this. - * ace/LSOCK_Stream: Moved get_remote_addr() from the private part - of the class and implemented it using get_local_addr(). This - fixes problems that previously occurred when using the - ACE_Connector with ACE_LSOCK_Stream. Thanks to Stuart Powell - <stuartp@in.ot.com.au> for this suggestion. + * ace/LSOCK_Stream: Moved get_remote_addr() from the private part + of the class and implemented it using get_local_addr(). This + fixes problems that previously occurred when using the + ACE_Connector with ACE_LSOCK_Stream. Thanks to Stuart Powell + <stuartp@in.ot.com.au> for this suggestion. Mon Dec 9 22:03:30 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> * examples/Threads: Updated the test.mak and test.mdp files to - reflect the new name changes. Thanks to Matthias for this. + reflect the new name changes. Thanks to Matthias for this. * ace/ACE.cpp (ldfind): Added new code that will work if the "base" part of the filename to look for is the same on both UNIX @@ -591,106 +703,106 @@ Mon Dec 9 22:03:30 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> Mon Dec 9 02:06:48 1996 Irfan Pyarali <irfan@flamenco.cs.wustl.edu> - * ace/SString: Made accessors return const references. - - * ace/OS.h: Added macro ACE_WIDE_STRING which allows the - conversion of char* to wchar_t* when UNICODE is turned on. - - * ace: Added/Fixed UNICODE behavior of the following: - - /* Local_Name_Space */ - ACE_Local_Name_Space_T::context_file_ - - /* ACE */ - ACE::basename - - /* Token */ - ACE_Token::ACE_Token - - /* Synch */ - ACE_File_Lock::ACE_File_Lock - - /* SPIPE_Addr */ - ACE_SPIPE_Addr::addr_to_string - ACE_SPIPE_Addr::set - - /* FILE_Addr */ - ACE_FILE_Addr::addr_to_string - - /* DEV_Addr */ - ACE_DEV_Addr::addr_to_string - - /* Addr */ - ACE_Addr::addr_to_string - ACE_Addr::string_to_addr - Note: These two were removed from the base class since they are - not common to all Address classes. - - /* Malloc */ - ACE_Allocator_Adapter::ACE_Allocator_Adapter - ACE_Malloc::ACE_Malloc - - /* Process */ - ACE_Process::start - - /* Shared_Memory_MM */ - ACE_Shared_Memory_MM::ACE_Shared_Memory_MM - ACE_Shared_Memory_MM::open - - /* Proactor */ - ACE_Overlapped_File::ACE_Overlapped_File - ACE_Overlapped_File::open - - /* Log_msg */ - ACE_Log_Msg::open - - /* Naming_Context */ - ACE_Name_Options::namespace_dir - ACE_Name_Options::process_dir - ACE_Name_Options::database - - /* Registry */ - ACE_Predefined_Naming_Contexts::connect - ACE_Predefined_Naming_Contexts::is_local_host - - /* SString */ - ACE_CString::ACE_CString - - /* Mem_Map */ - ACE_Mem_Map::ACE_Mem_Map - ACE_Mem_Map::map - - /* Service_Config */ - ACE_Service_Config::logger_key_ - - /* System_Time */ - ACE_System_Time::ACE_System_Time - - /* Memory_Pool */ - ACE_Sbrk_Memory_Pool::ACE_Sbrk_Memory_Pool - ACE_Shared_Memory_Pool::ACE_Shared_Memory_Pool - ACE_Local_Memory_Pool::ACE_Local_Memory_Pool - ACE_MMAP_Memory_Pool::ACE_MMAP_Memory_Pool - ACE_Lite_MMAP_Memory_Pool::ACE_Lite_MMAP_Memory_Pool - - /* OS */ - ACE_OS::strstr - ACE_OS::strdup - ACE_OS::hostname - ACE_OS::open - ACE_OS::unlink - ACE_OS::dlopen - ACE_OS::dlsym - ACE_OS::cuserid - ACE_OS::fork_exec - ACE_OS::sprintf - ACE_OS::access - ACE_OS::fopen - ACE_OS::getenv - ACE_OS::system - ACE_OS::mkdir - ACE_OS::mktemp - + * ace/SString: Made accessors return const references. + + * ace/OS.h: Added macro ACE_WIDE_STRING which allows the + conversion of char* to wchar_t* when UNICODE is turned on. + + * ace: Added/Fixed UNICODE behavior of the following: + + /* Local_Name_Space */ + ACE_Local_Name_Space_T::context_file_ + + /* ACE */ + ACE::basename + + /* Token */ + ACE_Token::ACE_Token + + /* Synch */ + ACE_File_Lock::ACE_File_Lock + + /* SPIPE_Addr */ + ACE_SPIPE_Addr::addr_to_string + ACE_SPIPE_Addr::set + + /* FILE_Addr */ + ACE_FILE_Addr::addr_to_string + + /* DEV_Addr */ + ACE_DEV_Addr::addr_to_string + + /* Addr */ + ACE_Addr::addr_to_string + ACE_Addr::string_to_addr + Note: These two were removed from the base class since they are + not common to all Address classes. + + /* Malloc */ + ACE_Allocator_Adapter::ACE_Allocator_Adapter + ACE_Malloc::ACE_Malloc + + /* Process */ + ACE_Process::start + + /* Shared_Memory_MM */ + ACE_Shared_Memory_MM::ACE_Shared_Memory_MM + ACE_Shared_Memory_MM::open + + /* Proactor */ + ACE_Overlapped_File::ACE_Overlapped_File + ACE_Overlapped_File::open + + /* Log_msg */ + ACE_Log_Msg::open + + /* Naming_Context */ + ACE_Name_Options::namespace_dir + ACE_Name_Options::process_dir + ACE_Name_Options::database + + /* Registry */ + ACE_Predefined_Naming_Contexts::connect + ACE_Predefined_Naming_Contexts::is_local_host + + /* SString */ + ACE_CString::ACE_CString + + /* Mem_Map */ + ACE_Mem_Map::ACE_Mem_Map + ACE_Mem_Map::map + + /* Service_Config */ + ACE_Service_Config::logger_key_ + + /* System_Time */ + ACE_System_Time::ACE_System_Time + + /* Memory_Pool */ + ACE_Sbrk_Memory_Pool::ACE_Sbrk_Memory_Pool + ACE_Shared_Memory_Pool::ACE_Shared_Memory_Pool + ACE_Local_Memory_Pool::ACE_Local_Memory_Pool + ACE_MMAP_Memory_Pool::ACE_MMAP_Memory_Pool + ACE_Lite_MMAP_Memory_Pool::ACE_Lite_MMAP_Memory_Pool + + /* OS */ + ACE_OS::strstr + ACE_OS::strdup + ACE_OS::hostname + ACE_OS::open + ACE_OS::unlink + ACE_OS::dlopen + ACE_OS::dlsym + ACE_OS::cuserid + ACE_OS::fork_exec + ACE_OS::sprintf + ACE_OS::access + ACE_OS::fopen + ACE_OS::getenv + ACE_OS::system + ACE_OS::mkdir + ACE_OS::mktemp + Sun Dec 8 19:00:45 1996 Tim H. Harrison <harrison@lambada.cs.wustl.edu> * ace/Reactor.cpp (handle_events): Updated this method to use the @@ -669,6 +669,8 @@ Robert Lyng <RLyng@msmail.hsii.ccare.com> Phil Logan <phill@in.ot.com.au> John Cosby <John.D.Cosby@cpmx.saic.com> Wayne Vucenic <wvucenic@netgate.net> +Harry Gunnarsson <hg@carmenta.se> +James CE Johnson <jcej@lads.com> I would particularly like to thank Paul Stephenson, who worked with me at Ericsson and is now at ObjectSpace. Paul devised the recursive @@ -1,4 +1,4 @@ -This is version 4.1 +This is version 4.1.1 If you have any problems with ACE, please send email to Douglas C. Schmidt (schmidt@cs.wustl.edu). diff --git a/ace/Acceptor.cpp b/ace/Acceptor.cpp index d770af37146..79ad80fd9ae 100644 --- a/ace/Acceptor.cpp +++ b/ace/Acceptor.cpp @@ -170,6 +170,14 @@ ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close (ACE_HANDLE, this->reactor_->remove_handler (handle, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL); + + // Shut down the listen socket to recycle the handles. + if (this->peer_acceptor_.close () == -1) + ACE_ERROR ((LM_ERROR, "close\n")); + + // Set the Reactor to 0 so that we don't try to close down + // again. + this->reactor (0); } return 0; } @@ -484,7 +492,7 @@ ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close (ACE_HANDL { ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close"); // Guard against multiple closes. - if (this->creation_strategy_ != 0) + if (this->reactor () != 0) { ACE_HANDLE handle = this->get_handle (); @@ -513,6 +521,10 @@ ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close (ACE_HANDL this->reactor ()->remove_handler (handle, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL); + + // Set the Reactor to 0 so that we don't try to close down + // again. + this->reactor (0); } return 0; } diff --git a/ace/Local_Name_Space_T.cpp b/ace/Local_Name_Space_T.cpp index 0f6c66f651b..821ee3797d6 100644 --- a/ace/Local_Name_Space_T.cpp +++ b/ace/Local_Name_Space_T.cpp @@ -211,7 +211,7 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::unbind_i (const ACE_WString &name) { ACE_TRACE ("ACE_Local_Name_Space::unbind"); - ACE_WRITE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + ACE_WRITE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1); ACE_NS_String ns_name (name); ACE_NS_Internal ns_internal; if (this->name_space_map_->unbind (ns_name, ns_internal, this->allocator_) != 0) @@ -233,7 +233,7 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::bind (const ACE_WString &name, const char *type) { ACE_TRACE ("ACE_Local_Name_Space::bind"); - ACE_WRITE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + ACE_WRITE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1); return this->shared_bind (name, value, type, 0); } @@ -244,7 +244,7 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::rebind (const ACE_WString &name, const char *type) { ACE_TRACE ("ACE_Local_Name_Space::rebind"); - ACE_WRITE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + ACE_WRITE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1); return this->shared_bind (name, value, type, 1); } @@ -273,7 +273,7 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::resolve_i (const ACE_WString &name, char *&type) { ACE_TRACE ("ACE_Local_Name_Space::resolve"); - ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1); ACE_NS_String ns_name (name); ACE_NS_Internal ns_internal; @@ -337,8 +337,9 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::~ACE_Local_Name_Space (void) { ACE_TRACE ("ACE_Local_Name_Space::~ACE_Local_Name_Space"); - // Remove the map + // Remove the map. delete this->allocator_; + delete this->lock_; } template <ACE_MEM_POOL_1, class LOCK> int @@ -378,15 +379,29 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::create_manager_i (void) ACE_OS::strcat (this->context_file_, ACE_DIRECTORY_SEPARATOR_STR); ACE_OS::strcat (this->context_file_, this->name_options_->database ()); - // ACE_DEBUG ((LM_DEBUG, "contextfile is %s\n", this->context_file_)); - ACE_MEM_POOL_OPTIONS options (this->name_options_->base_address ()); + TCHAR lock_name_for_local_name_space [MAXNAMELEN]; + TCHAR lock_name_for_backing_store [MAXNAMELEN]; + LPCTSTR prefix = ACE::basename (this->context_file_, + ACE_DIRECTORY_SEPARATOR_CHAR); + + ACE_OS::strcpy (lock_name_for_local_name_space , prefix); + ACE_OS::strcat (lock_name_for_local_name_space, "_name_space"); + + ACE_OS::strcpy (lock_name_for_backing_store, prefix); + ACE_OS::strcat (lock_name_for_backing_store, "_backing_store"); + // Create the allocator with the appropriate options. - ACE_NEW_RETURN (this->allocator_, ALLOCATOR (this->context_file_, 0, &options), -1); + ACE_NEW_RETURN (this->allocator_, + ALLOCATOR (this->context_file_, + lock_name_for_backing_store, + &options), -1); if (ACE_LOG_MSG->op_status ()) ACE_ERROR_RETURN ((LM_ERROR, "Allocator::Allocator\n"), -1); + + ACE_NEW_RETURN (this->lock_, LOCK (lock_name_for_local_name_space), -1); // Now check if the backing store has been created successfully if (ACE_OS::access (this->context_file_, F_OK) != 0) @@ -404,31 +419,33 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::create_manager_i (void) } // This is the hard part since we have to avoid potential race - // conditions... + // conditions... We will use the double check here else { - size_t map_size = sizeof *this->name_space_map_; - ns_map = this->allocator_->malloc (map_size); - - // Initialize the map into its memory location (e.g., shared memory). - ACE_NEW_RETURN (this->name_space_map_, - (ns_map) ACE_Name_Space_Map <ALLOCATOR> (this->allocator_), - -1); + ACE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1); - // Don't allow duplicates (atomically return existing int_id, if - // there is one). - if (this->allocator_->trybind (ACE_NAME_SERVER_MAP, ns_map) == 1) + // This is the easy case since if we find the Name Server Map + // Manager we know it's already initialized. + if (this->allocator_->find (ACE_NAME_SERVER_MAP, ns_map) == 0) { - // We're not the first one in, so free up the map and assign - // the map to the pointer that was allocated by the caller - // that was the first time in! - this->name_space_map_->close (this->allocator_); - - // Note that we can't free <map> since that was overwritten - // in the call to bind()! - this->allocator_->free ((void *) this->name_space_map_); this->name_space_map_ = (ACE_Name_Space_Map <ALLOCATOR> *) ns_map; + ACE_DEBUG ((LM_DEBUG, "name_space_map_ = %d, ns_map = %d\n", + this->name_space_map_, ns_map)); + } + else + { + size_t map_size = sizeof *this->name_space_map_; + ns_map = this->allocator_->malloc (map_size); + + // Initialize the map into its memory location (e.g., shared memory). + ACE_NEW_RETURN (this->name_space_map_, + (ns_map) ACE_Name_Space_Map <ALLOCATOR> (this->allocator_), + -1); + + if (this->allocator_->bind (ACE_NAME_SERVER_MAP, ns_map) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "create_manager\n"), -1); } + ACE_DEBUG ((LM_DEBUG, "name_space_map_ = %d, ns_map = %d\n", this->name_space_map_, ns_map)); } @@ -436,12 +453,13 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::create_manager_i (void) return 0; } + template <ACE_MEM_POOL_1, class LOCK> int ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::list_names (ACE_PWSTRING_SET &set, const ACE_WString &pattern) { ACE_TRACE ("ACE_Local_Name_Space::list_names"); - ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1); MAP_ITERATOR map_iterator (*this->name_space_map_); MAP_ENTRY *map_entry; @@ -474,7 +492,7 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::list_values (ACE_PWSTRING_SET &set, const ACE_WString &pattern) { ACE_TRACE ("ACE_Local_Name_Space::list_values"); - ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1); MAP_ITERATOR map_iterator (*this->name_space_map_); MAP_ENTRY *map_entry; @@ -507,7 +525,7 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::list_types (ACE_PWSTRING_SET &set, const ACE_WString &pattern) { ACE_TRACE ("ACE_Local_Name_Space::list_types"); - ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1); MAP_ITERATOR map_iterator (*this->name_space_map_); MAP_ENTRY *map_entry; @@ -569,7 +587,7 @@ ACE_Local_Name_Space <ACE_MEM_POOL_2, LOCK>::list_name_entries (ACE_BINDING_SET const ACE_WString &pattern) { ACE_TRACE ("ACE_Local_Name_Space::list_name_entries"); - ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1); MAP_ITERATOR map_iterator (*this->name_space_map_); MAP_ENTRY *map_entry; @@ -597,7 +615,7 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::list_value_entries (ACE_BINDING_SET const ACE_WString &pattern) { ACE_TRACE ("ACE_Local_Name_Space::list_value_entries"); - ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1); MAP_ITERATOR map_iterator (*this->name_space_map_); MAP_ENTRY *map_entry; @@ -624,7 +642,7 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::list_type_entries (ACE_BINDING_SET & const ACE_WString &pattern) { ACE_TRACE ("ACE_Local_Name_Space::list_type_entries"); - ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1); MAP_ITERATOR map_iterator (*this->name_space_map_); MAP_ENTRY *map_entry; @@ -703,6 +721,3 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::dump (void) const } #endif /* ACE_LOCAL_NAME_SPACE_T_C */ - - - diff --git a/ace/Local_Name_Space_T.h b/ace/Local_Name_Space_T.h index 6745738e044..616019884a9 100644 --- a/ace/Local_Name_Space_T.h +++ b/ace/Local_Name_Space_T.h @@ -212,7 +212,7 @@ private: TCHAR context_file_[MAXNAMELEN]; // Name of the file used as the backing store. - LOCK lock_; + LOCK *lock_; // Synchronization variable. }; diff --git a/ace/Malloc_T.cpp b/ace/Malloc_T.cpp index 3685c4a42ac..4a45dbcb3cb 100644 --- a/ace/Malloc_T.cpp +++ b/ace/Malloc_T.cpp @@ -164,7 +164,8 @@ ACE_Malloc<ACE_MEM_POOL_2, LOCK>::ACE_Malloc (LPCTSTR pool_name, LPCTSTR lock_name, const ACE_MEM_POOL_OPTIONS *options) : memory_pool_ (pool_name, options), - lock_ (lock_name) + lock_ (lock_name != 0 ? lock_name : ACE::basename (pool_name, + ACE_DIRECTORY_SEPARATOR_CHAR)) { ACE_TRACE ("ACE_Malloc<ACE_MEM_POOL_2, LOCK>::ACE_Malloc"); this->open (); diff --git a/ace/Naming_Context.cpp b/ace/Naming_Context.cpp index 90048ca5353..12779536a7d 100644 --- a/ace/Naming_Context.cpp +++ b/ace/Naming_Context.cpp @@ -347,7 +347,7 @@ ACE_Name_Options::ACE_Name_Options (void) nameserver_host_ (ACE_OS::strdup (ACE_DEFAULT_SERVER_HOST)), namespace_dir_ (ACE_OS::strdup (ACE_DEFAULT_NAMESPACE_DIR)), process_name_ (0), - database_ (0), + database_ (ACE_OS::strdup (ACE_DEFAULT_LOCALNAME)), base_address_ (ACE_DEFAULT_BASE_ADDR) { ACE_TRACE ("ACE_Name_Options::ACE_Name_Options"); diff --git a/ace/OS.cpp b/ace/OS.cpp index f52c5639c40..2a8b83b75cd 100644 --- a/ace/OS.cpp +++ b/ace/OS.cpp @@ -696,6 +696,7 @@ ACE_OS::thr_create (ACE_THR_FUNC func, size = PTHREAD_STACK_MIN; #endif /* PTHREAD_STACK_MIN */ +#if !defined (ACE_LACKS_THREAD_STACK_SIZE) // JCEJ 12/17/96 if (::pthread_attr_setstacksize (&attr, size) != 0) { #if defined (ACE_HAS_SETKIND_NP) @@ -706,6 +707,7 @@ ACE_OS::thr_create (ACE_THR_FUNC func, return -1; } } +#endif /* !ACE_LACKS_THREAD_STACK_SIZE */ #if !defined (ACE_LACKS_THREAD_STACK_ADDR) if (stack != 0) @@ -919,17 +921,17 @@ ACE_OS::thr_create (ACE_THR_FUNC func, if (ACE_BIT_ENABLED (flags, THR_USE_AFX)) { CWinThread *cwin_thread = - ::AfxBeginThread (ACE_THR_C_FUNC (&ace_thread_adapter)), + ::AfxBeginThread ((AFX_THREADPROC) &ace_thread_adapter), thread_args, priority, 0, flags | THR_SUSPENDED); // Have to duplicate the handle because // CWinThread::~CWinThread() closes the original handle. - *thr_handle = ::DuplicateHandle (::GetCurrentProcess (), - cwin_thread->m_hThread, - ::GetCurrentProcess (), - thr_handle, - 0, - TRUE, - DUPLICATE_SAME_ACCESS); + (void) ::DuplicateHandle (::GetCurrentProcess (), + cwin_thread->m_hThread, + ::GetCurrentProcess (), + thr_handle, + 0, + TRUE, + DUPLICATE_SAME_ACCESS); *thr_id = cwin_thread->m_nThreadID; @@ -1115,7 +1117,11 @@ ACE_OS::thr_keyfree (ACE_thread_key_t key) int ACE_OS::thr_keycreate (ACE_thread_key_t *key, +#if defined (ACE_HAS_THR_C_DEST) + ACE_THR_C_DEST dest, +#else ACE_THR_DEST dest, +#endif /* ACE_HAS_THR_C_DEST */ void *inst) { // ACE_TRACE ("ACE_OS::thr_keycreate"); @@ -1392,62 +1398,59 @@ int sys_nerr = ERRMAX + 1; #include /**/ <usrLib.h> /* for ::sp() */ -// This global function can be used from the VxWorks shell to -// pass arguments to a C main () function. -// usage: -> spa main, "arg1", "arg2" -// All arguments must be quoted, even numbers. +// This global function can be used from the VxWorks shell to pass +// arguments to a C main () function. usage: -> spa main, "arg1", +// "arg2" All arguments must be quoted, even numbers. int spa (FUNCPTR entry, ...) { - static const unsigned int MAX_ARGS = 10; - static char *argv[MAX_ARGS]; - va_list pvar; - int argc; - - // Hardcode a program name because the real one isn't available - // through the VxWorks shell. - argv[0] = "spa ():t"; - - // Peel off arguments to spa () and put into argv. va_arg () - // isn't necessarily supposed to return 0 when done, though - // since the VxWorks shell uses a fixed number (10) of arguments, - // it might 0 the unused ones. - // This function could be used to increase that limit, but then - // it couldn't depend on the trailing 0. So, the number of arguments - // would have to be passed. - va_start (pvar, entry); - for (argc = 1; argc <= MAX_ARGS; ++argc) - { - argv[argc] = va_arg (pvar, char *); - if (argv[argc] == 0) - break; - } + static const unsigned int MAX_ARGS = 10; + static char *argv[MAX_ARGS]; + va_list pvar; + int argc; + + // Hardcode a program name because the real one isn't available + // through the VxWorks shell. + argv[0] = "spa ():t"; + + // Peel off arguments to spa () and put into argv. va_arg () isn't + // necessarily supposed to return 0 when done, though since the + // VxWorks shell uses a fixed number (10) of arguments, it might 0 + // the unused ones. This function could be used to increase that + // limit, but then it couldn't depend on the trailing 0. So, the + // number of arguments would have to be passed. + va_start (pvar, entry); + + for (argc = 1; argc <= MAX_ARGS; ++argc) + { + argv[argc] = va_arg (pvar, char *); - if (argc > MAX_ARGS && argv[argc-1] != 0) - { - // try to read another arg, and warn user if the limit was exceeded - if (va_arg (pvar, char *) != 0) - fprintf (stderr, "spa(): number of arguments limited to %d\n", - MAX_ARGS); - } - else - { - // fill unused argv slots with 0 to get rid of leftovers - // from previous invocations - for ( int i = argc; i <= MAX_ARGS; ++i) - { - argv[i] = 0; - } - } + if (argv[argc] == 0) + break; + } + + if (argc > MAX_ARGS && argv[argc-1] != 0) + { + // try to read another arg, and warn user if the limit was exceeded + if (va_arg (pvar, char *) != 0) + fprintf (stderr, "spa(): number of arguments limited to %d\n", + MAX_ARGS); + } + else + { + // fill unused argv slots with 0 to get rid of leftovers + // from previous invocations + for (int i = argc; i <= MAX_ARGS; ++i) + argv[i] = 0; + } - int ret = ::sp (entry, argc, (int) argv, 0, 0, 0, 0, 0, 0, 0); - va_end (pvar); + int ret = ::sp (entry, argc, (int) argv, 0, 0, 0, 0, 0, 0, 0); + va_end (pvar); - // ::sp () returns the taskID on success: return 0 instead - // if successful - return ret > 0 ? 0 : ret; + // ::sp () returns the taskID on success: return 0 instead if + // successful + return ret > 0 ? 0 : ret; } - #endif /* VXWORKS */ #if !defined (ACE_HAS_SIGINFO_T) @@ -644,7 +644,6 @@ typedef pthread_mutex_t ACE_thread_mutex_t; #define THR_SCOPE_PROCESS 0x00200000 #define THR_INHERIT_SCHED 0x00400000 #define THR_EXPLICIT_SCHED 0x00800000 -#define THR_USE_AFX 0x01000000 #if !defined (ACE_HAS_STHREADS) #if !defined (ACE_HAS_POSIX_SEM) @@ -663,28 +662,6 @@ struct ACE_sema_t }; #endif /* !ACE_HAS_POSIX_SEM */ -// This is used to implement readers/writer locks for POSIX pthreads. -struct ACE_rwlock_t -{ - ACE_mutex_t lock_; - // Serialize access to internal state. - - ACE_cond_t waiting_readers_; - // Reader threads waiting to acquire the lock. - - int num_waiting_readers_; - // Number of waiting readers. - - ACE_cond_t waiting_writers_; - // Writer threads waiting to acquire the lock. - - int num_waiting_writers_; - // Number of waiting writers. - - int ref_count_; - // Value is -1 if writer has the lock, else this keeps track of the - // number of readers holding the lock. -}; #else // If we are on Solaris we can just reuse the existing implementations // of these synchronization types. @@ -751,59 +728,6 @@ typedef char * ACE_thread_t; typedef int ACE_hthread_t; typedef int ACE_thread_key_t; -struct ACE_cond_t - // = TITLE - // This structure is used to implement condition variables on VxWorks - // - // = DESCRIPTION - // At the current time, this stuff only works for threads - // within the same process, which there's only one of on VxWorks. -{ - long waiters_; - // Number of waiting threads. - - ACE_thread_mutex_t waiters_lock_; - // Serialize access to the waiters count. - - ACE_sema_t sema_; - // Queue up threads waiting for the condition to become signaled. - - ACE_event_t waiters_done_; - // An auto reset event used by the broadcast/signal thread to wait - // for the waiting thread(s) to wake up and get a chance at the - // semaphore. - - size_t was_broadcast_; - // Keeps track of whether we were broadcasting or just signaling. -}; - -struct ACE_rwlock_t - // = TITLE - // This is used to implement readers/writer locks on VxWorks - // - // = DESCRIPTION - // At the current time, this stuff only works for threads - // within the same process, which there's only one of on VxWorks. -{ - ACE_mutex_t lock_; - // Serialize access to internal state. - - ACE_cond_t waiting_readers_; - // Reader threads waiting to acquire the lock. - - int num_waiting_readers_; - // Number of waiting readers. - - ACE_cond_t waiting_writers_; - // Writer threads waiting to acquire the lock. - - int num_waiting_writers_; - // Number of waiting writers. - - int ref_count_; - // Value is -1 if writer has the lock, else this keeps track of the - // number of readers holding the lock. -}; #elif defined (ACE_HAS_WTHREADS) typedef CRITICAL_SECTION ACE_thread_mutex_t; typedef struct @@ -817,28 +741,59 @@ typedef struct } ACE_mutex_t; typedef HANDLE ACE_sema_t; +// These need to be different values, neither of which can be 0... +#define USYNC_THREAD 1 +#define USYNC_PROCESS 2 + +#define THR_CANCEL_DISABLE 0 +#define THR_CANCEL_ENABLE 0 +#define THR_CANCEL_DEFERRED 0 +#define THR_CANCEL_ASYNCHRONOUS 0 +#define THR_DETACHED 0 /* ?? ignore in most places */ +#define THR_BOUND 0 /* ?? ignore in most places */ +#define THR_NEW_LWP 0 /* ?? ignore in most places */ +#define THR_SUSPENDED CREATE_SUSPENDED +#define THR_USE_AFX 0x01000000 +#endif /* ACE_HAS_DCETHREADS || ACE_HAS_PTHREADS */ + +#if defined (ACE_LACKS_COND_T) struct ACE_cond_t // = TITLE - // This structure is used to implement condition variables on NT. + // This structure is used to implement condition variables on + // VxWorks and Win32. // // = DESCRIPTION - // At the current time, this stuff only works for threads - // within the same process. + // At the current time, this stuff only works for threads + // within the same process. { - DWORD waiters_; + long waiters_; // Number of waiting threads. + ACE_thread_mutex_t waiters_lock_; + // Serialize access to the waiters count. + ACE_sema_t sema_; // Queue up threads waiting for the condition to become signaled. + + ACE_event_t waiters_done_; + // An auto reset event used by the broadcast/signal thread to wait + // for the waiting thread(s) to wake up and get a chance at the + // semaphore. + + size_t was_broadcast_; + // Keeps track of whether we were broadcasting or just signaling. }; +#endif /* ACE_LACKS_COND_T */ +#if defined (ACE_LACKS_RWLOCK_T) struct ACE_rwlock_t // = TITLE - // This is used to implement readers/writer locks on NT. + // This is used to implement readers/writer locks on NT, + // VxWorks, and POSIX pthreads. // // = DESCRIPTION - // At the current time, this stuff only works for threads - // within the same process. + // At the current time, this stuff only works for threads + // within the same process. { ACE_mutex_t lock_; // Serialize access to internal state. @@ -859,20 +814,8 @@ struct ACE_rwlock_t // Value is -1 if writer has the lock, else this keeps track of the // number of readers holding the lock. }; +#endif /* ACE_LACKS_RWLOCK_T */ -// These need to be different values, neither of which can be 0... -#define USYNC_THREAD 1 -#define USYNC_PROCESS 2 - -#define THR_CANCEL_DISABLE 0 -#define THR_CANCEL_ENABLE 0 -#define THR_CANCEL_DEFERRED 0 -#define THR_CANCEL_ASYNCHRONOUS 0 -#define THR_DETACHED 0 /* ?? ignore in most places */ -#define THR_BOUND 0 /* ?? ignore in most places */ -#define THR_NEW_LWP 0 /* ?? ignore in most places */ -#define THR_SUSPENDED CREATE_SUSPENDED -#endif /* ACE_HAS_DCETHREADS || ACE_HAS_PTHREADS */ #else /* !ACE_HAS_THREADS, i.e., the OS/platform doesn't support threading. */ // Give these things some reasonable value... #define THR_CANCEL_DISABLE 0 @@ -1806,14 +1749,10 @@ typedef FUNCPTR ACE_THR_FUNC; // where typedef int (*FUNCPTR) (...) typedef void *(*ACE_THR_FUNC)(void *); #endif /* VXWORKS */ -#if defined (ACE_HAS_THR_C_DEST) -// Needed for frigging MVS C++... extern "C" { -typedef void (*ACE_THR_DEST)(void *); +typedef void (*ACE_THR_C_DEST)(void *); } -#else typedef void (*ACE_THR_DEST)(void *); -#endif /* ACE_HAS_THR_C_DEST */ extern "C" { @@ -2422,7 +2361,11 @@ public: static int thr_getspecific (ACE_thread_key_t key, void **data); static int thr_keyfree (ACE_thread_key_t key); static int thr_key_detach (void *inst); +#if defined (ACE_HAS_THR_C_DEST) + static int thr_keycreate (ACE_thread_key_t *key, ACE_THR_C_DEST, void *inst = 0); +#else static int thr_keycreate (ACE_thread_key_t *key, ACE_THR_DEST, void *inst = 0); +#endif /* ACE_HAS_THR_C_DEST */ static int thr_key_used (ACE_thread_key_t key); static size_t thr_min_stack (void); static int thr_setconcurrency (int hint); @@ -743,9 +743,15 @@ ACE_OS::mutex_init (ACE_mutex_t *m, int result = -1; #if defined (ACE_HAS_SETKIND_NP) +#if defined (ACE_HAS_DCETHREADS) + if (::pthread_mutexattr_create (&attributes) == 0 + && ::pthread_mutexattr_setkind_np (&attributes, type) == 0 + && ::pthread_mutex_init (m, attributes) == 0) +#else if (::pthread_mutexattr_init (&attributes) == 0 && ::pthread_mutexattr_setkind_np (&attributes, type) == 0 && ::pthread_mutex_init (m, &attributes) == 0) +#endif /* ACE_HAS_DCETHREADS */ #else if (::pthread_mutexattr_init (&attributes) == 0 #if defined (ACE_HAS_PTHREAD_MUTEXATTR_SETKIND_NP) @@ -1074,8 +1080,13 @@ ACE_OS::cond_init (ACE_cond_t *cv, int type, LPCTSTR name, void *arg) int result = -1; #if defined (ACE_HAS_SETKIND_NP) +#if defined (ACE_HAS_DCETHREADS) + if (::pthread_condattr_create (&attributes) == 0 + && ::pthread_cond_init (cv, attributes) == 0 +#else if (::pthread_condattr_init (&attributes) == 0 && ::pthread_cond_init (cv, &attributes) == 0 +#endif /* ACE_HAS_DCETHREADS */ #if defined (ACE_HAS_PTHREAD_CONDATTR_SETKIND_NP) && ::pthread_condattr_setkind_np (&attributes, type) == 0 #endif /* ACE_HAS_PTHREAD_CONDATTR_SETKIND_NP */ @@ -1275,7 +1286,6 @@ ACE_OS::cond_timedwait (ACE_cond_t *cv, // ACE_TRACE ("ACE_OS::cond_timedwait"); #if defined (ACE_HAS_THREADS) #if defined (ACE_HAS_WTHREADS) - // Handle the easy case first. if (timeout == 0) return ACE_OS::cond_wait (cv, external_mutex); @@ -1391,41 +1401,71 @@ ACE_OS::cond_timedwait (ACE_cond_t *cv, // ACE_TRACE ("ACE_OS::cond_timedwait"); #if defined (ACE_HAS_THREADS) #if defined (ACE_HAS_WTHREADS) - cv->waiters_++; - - if (ACE_OS::thread_mutex_unlock (external_mutex) != 0) - return -1; - - DWORD result; - + // Handle the easy case first. if (timeout == 0) - // Wait forever. - result = ::WaitForSingleObject (cv->sema_, INFINITE); - else if (timeout->sec () == 0 && timeout->usec () == 0) - // Do a "poll". - result = ::WaitForSingleObject (cv->sema_, 0); + return ACE_OS::cond_wait (cv, external_mutex); + + // It's ok to increment this because the <external_mutex> must be + // locked by the caller. + cv->waiters_++; + + int result = 0; + int error = 0; + int msec_timeout; + + if (timeout->sec () == 0 && timeout->usec () == 0) + msec_timeout = 0; // Do a "poll." else { - // Wait for upto <relative_time> number of milliseconds. Note - // that we must convert between absolute time (which is passed - // as a parameter) and relative time (which is what + // Note that we must convert between absolute time (which is + // passed as a parameter) and relative time (which is what // WaitForSingleObjects() expects). ACE_Time_Value relative_time (*timeout - ACE_OS::gettimeofday ()); - result = ::WaitForSingleObject (cv->sema_, relative_time.msec ()); + msec_timeout = relative_time.msec (); } - ACE_OS::thread_mutex_lock (external_mutex); - - cv->waiters_--; + // We keep the lock held just long enough to increment the count of + // waiters by one. Note that we can't keep it held across the call + // to WaitForSingleObject since that will deadlock other calls to + // ACE_OS::cond_signal(). + if (ACE_OS::thread_mutex_unlock (external_mutex) != 0) + return -1; - if (result == WAIT_OBJECT_0) - return 0; - else + // Wait to be awakened by a ACE_OS::signal() or ACE_OS::broadcast(). + result = ::WaitForSingleObject (cv->sema_, msec_timeout); + + if (result != WAIT_OBJECT_0) + // This is a hack, we need to find an appropriate mapping... + error = result == WAIT_TIMEOUT ? ETIME : ::GetLastError (); + else { - errno = result == WAIT_TIMEOUT ? ETIME : ::GetLastError (); - // This is a hack, we need to find an appropriate mapping... - return -1; + // If we are broadcasting, then we need to be smarter about + // locking since there can now be multiple threadsd in the + // crtical section. If we are signaling, however, we don't have + // to worry since there will just be 1 thread here. + if (cv->was_broadcast_) + { + if (ACE_OS::thread_mutex_lock (cv->waiters_lock_) != -1) + { + // By making the waiter responsible for decrementing its count we + // don't have to worry about having an internal mutex. Thanks to + // Karlheinz for recognizing this optimization. + cv->waiters_--; + // Release the signaler/broadcaster if we're the last waiter. + if (cv->waiters_ == 0) + ::SetEvent (cv->waiters_done_); + ACE_OS::thread_mutex_unlock (cv->internal_mutex_); + } + } + else + cv->waiters_--; } + // We must always regain the external mutex, even when errors + // occur because that's the guarantee that we give to our + // callers. + ACE_OS::thread_mutex_lock (external_mutex); + errno = error; + return result; #endif /* ACE_HAS_WTHREADS */ #else ACE_NOTSUP_RETURN (-1); @@ -1439,29 +1479,58 @@ ACE_OS::cond_wait (ACE_cond_t *cv, // ACE_TRACE ("ACE_OS::cond_wait"); #if defined (ACE_HAS_THREADS) #if defined (ACE_HAS_WTHREADS) + // It's ok to increment this because the <external_mutex> must be + // locked by the caller. cv->waiters_++; + int result = 0; + int error = 0; + + // We keep the lock held just long enough to increment the count of + // waiters by one. Note that we can't keep it held across the call + // to ACE_OS::sema_wait() since that will deadlock other calls to + // ACE_OS::cond_signal(). if (ACE_OS::thread_mutex_unlock (external_mutex) != 0) return -1; - int result = 0; - int error = 0; + // Wait to be awakened by a ACE_OS::cond_signal() or + // ACE_OS::cond_broadcast(). + result = ::WaitForSingleObject (cv->sema_, INFINITE); - if (ACE_OS::sema_wait (&cv->sema_) != 0) + if (result != WAIT_OBJECT_0) + // This is a hack, we need to find an appropriate mapping... + error = result == WAIT_TIMEOUT ? ETIME : ::GetLastError (); + else { - result = -1; - error = errno; + // If we are broadcasting, then we need to be smarter about + // locking since there can now be multiple threadsd in the + // crtical section. If we are signaling, however, we don't have + // to worry since there will just be 1 thread here. + if (cv->was_broadcast_) + { + if (ACE_OS::thread_mutex_lock (cv->waiters_lock_) != -1) + { + // By making the waiter responsible for decrementing its count we + // don't have to worry about having an internal mutex. Thanks to + // Karlheinz for recognizing this optimization. + cv->waiters_--; + // Release the signaler/broadcaster if we're the last waiter. + if (cv->waiters_ == 0) + ::SetEvent (cv->waiters_done_); + ACE_OS::thread_mutex_unlock (cv->internal_mutex_); + } + } + else + cv->waiters_--; } - - // We must always regain the mutex, even when errors occur. + // We must always regain the external mutex, even when errors + // occur because that's the guarantee that we give to our + // callers. ACE_OS::thread_mutex_lock (external_mutex); - cv->waiters_--; - // Reset errno in case mutex_lock() also fails... errno = error; return result; - #endif /* ACE_HAS_STHREADS */ #else ACE_NOTSUP_RETURN (-1); @@ -3467,7 +3536,7 @@ ACE_OS::thr_sigsetmask (int how, ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigmask (how, nsm, osm), ace_result_), int, -1); #elif defined (ACE_HAS_PTHREADS) && !defined (ACE_HAS_FSU_PTHREADS) -#if defined (ACE_HAS_IRIX62_THREADS) +#if defined (ACE_HAS_IRIX62_THREADS) || defined (ACE_HAS_PTHREADS_XAVIER) ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigmask (how, nsm, osm), ace_result_),int, -1); #else @@ -3592,7 +3661,9 @@ ACE_OS::thr_self (ACE_hthread_t &self) { // ACE_TRACE ("ACE_OS::thr_self"); #if defined (ACE_HAS_THREADS) -#if defined (ACE_HAS_THREAD_SELF) +#if defined (ACE_HAS_DCETHREADS) + self = ::pthread_self (); +#elif defined (ACE_HAS_THREAD_SELF) self = ::thread_self (); #elif defined (ACE_HAS_PTHREADS) || defined (ACE_HAS_SETKIND_NP) self = ::pthread_self (); @@ -3662,8 +3733,9 @@ ACE_OS::thr_setprio (ACE_hthread_t thr_id, int prio) #elif (defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS)) && !defined (ACE_LACKS_SETSCHED) struct sched_param param; int result; + int policy = 0; - ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_setschedparam (thr_id, policy, ¶m), result), int, -1, result); + ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_setschedparam (thr_id, &policy, ¶m), result), int, -1, result); prio = param.sched_priority; return result; ACE_NOTSUP_RETURN (-1); diff --git a/ace/Proactor.cpp b/ace/Proactor.cpp index 0484a7e31b7..7229d2ac8c4 100644 --- a/ace/Proactor.cpp +++ b/ace/Proactor.cpp @@ -245,14 +245,14 @@ ACE_Proactor::schedule_timer (ACE_Event_Handler *handler, #define ACE_TIMEOUT_OCCURRED 258 int -ACE_Proactor::handle_events (ACE_Time_Value *how_long) +ACE_Proactor::handle_events (ACE_Time_Value *max_wait_time) { // Stash the current time -- the destructor of this object will // automatically compute how much time elapsed since this method was // called. - ACE_Countdown_Time countdown (how_long); + ACE_Countdown_Time countdown (max_wait_time); - how_long = timer_queue_->calculate_timeout (how_long); + max_wait_time = timer_queue_->calculate_timeout (max_wait_time); ACE_Overlapped_IO *overlapped = 0; u_long bytes_transferred = 0; @@ -260,7 +260,7 @@ ACE_Proactor::handle_events (ACE_Time_Value *how_long) int error = 0; #if defined (ACE_WIN32) ACE_HANDLE io_handle = ACE_INVALID_HANDLE; - int timeout = how_long == 0 ? INFINITE : how_long->msec (); + int timeout = max_wait_time == 0 ? INFINITE : max_wait_time->msec (); BOOL result = 0; diff --git a/ace/Proactor.h b/ace/Proactor.h index 7d85e12fd03..af2431cc1eb 100644 --- a/ace/Proactor.h +++ b/ace/Proactor.h @@ -64,7 +64,7 @@ public: // = Initialization and termination methods. ACE_Proactor (size_t number_of_threads = 0, ACE_Timer_Queue *tq = 0); - // Initialize a proactor. -number_of_threads- is passed to + // Initialize a proactor. <number_of_threads> is passed to // CreateIoCompletionPort. ~ACE_Proactor (void); @@ -83,15 +83,15 @@ public: // integrate I/O completion ports with the ReactorEx. // = Event loop methods. - virtual int handle_events (ACE_Time_Value *how_long = 0); - virtual int handle_events (ACE_Time_Value &how_long); - // Main event loop driver that blocks for -how_long- before + virtual int handle_events (ACE_Time_Value *max_wait_time = 0); + virtual int handle_events (ACE_Time_Value &max_wait_time); + // Main event loop driver that blocks for <max_wait_time> before // returning (will return earlier if I/O or signal events occur). - // Note that -how_long- can be 0, in which case this method blocks + // Note that <max_wait_time> can be 0, in which case this method blocks // until I/O events or signals occur. handle_events just blocks // on GetQueuedCompletionStatus at completion_port_. When I/O // completions arrive, it calls back the Event_Handler associated - // with completed I/O operation. Returns 0 if -how_long- elapses + // with completed I/O operation. Returns 0 if <max_wait_time> elapses // before an event occurs, 1 when if an event occured, and -1 on // failure. diff --git a/ace/README b/ace/README index 01b65c546cb..a5be0ad87dc 100644 --- a/ace/README +++ b/ace/README @@ -132,6 +132,7 @@ ACE_HAS_XLI Platform has the XLI version of TLI ACE_HAS_XT Platform has Xt and Motif ACE_HAS_YIELD_VOID_PTR Platform requires pthread_yield() to take a NULL. ACE_LACKS_CONST_TIMESPEC_PTR Platform forgot const in cond_timewait (e.g., HP/UX). +ACE_LACKS_COND_T Platform lacks condition variables (e.g., Win32 and VxWorks) ACE_LACKS_CONDATTR_PSHARED Platform has no implementation of pthread_condattr_setpshared(), even though it supports pthreads! ACE_LACKS_MADVISE Platform lacks madvise() (e.g., Linux) ACE_LACKS_MALLOC_H Platform lacks malloc.h @@ -146,6 +147,7 @@ ACE_LACKS_POSIX_PROTO Platform lacks POSIX prototypes for certain System V fun ACE_LACKS_PTHREAD_THR_SIGSETMASK Platform lacks pthread_thr_sigsetmask (e.g., MVS, HP/UX, and OSF/1 3.2) ACE_LACKS_RECVMSG Platform lacks recvmsg() (e.g., Linux) ACE_LACKS_RPC_H Platform lacks the ONC RPC header files. +ACE_LACKS_RWLOCK_T Platform lacks readers/writer locks. ACE_LACKS_SBRK Platform lacks a working sbrk() (e.g., Win32 and VxWorks) ACE_LACKS_SEMBUF_T Platform lacks struct sembuf (e.g., Win32 and VxWorks) ACE_LACKS_SETDETACH Platform lacks pthread_attr_setdetachstate() (e.g., HP/UX 10.x) @@ -161,6 +163,7 @@ ACE_LACKS_STRRECVFD Platform doesn't define struct strrecvfd. ACE_LACKS_SYSCALL Platform doesn't have syscall() prototype ACE_LACKS_SYSV_MSQ_PROTOS Platform doesn't have prototypes for Sys V msg()* queues. ACE_LACKS_T_ERRNO Header files lack t_errno for TLI +ACE_LACKS_THREAD_STACK_SIZE Platform lacks pthread_attr_setstacksize() (e.g., Linux pthreads) ACE_LACKS_UCONTEXT_H Platform lacks the ucontext.h file ACE_LACKS_UNIX_DOMAIN_SOCKETS ACE platform has no UNIX domain sockets ACE_LACKS_UTSNAME_T Platform lacks struct utsname (e.g., Win32 and VxWorks) diff --git a/ace/ReactorEx.cpp b/ace/ReactorEx.cpp index 21bcc46f161..9215d3d815e 100644 --- a/ace/ReactorEx.cpp +++ b/ace/ReactorEx.cpp @@ -120,18 +120,19 @@ ACE_ReactorEx::schedule_timer (ACE_Event_Handler *handler, } // Waits for and dispatches all events. Returns -1 on error, 0 if -// how_long expired, and 1 if events were dispatched. +// max_wait_time expired, and 1 if events were dispatched. int -ACE_ReactorEx::handle_events (ACE_Time_Value *how_long, +ACE_ReactorEx::handle_events (ACE_Time_Value *max_wait_time, int wait_all, - ACE_Event_Handler *wait_all_callback) + ACE_Event_Handler *wait_all_callback, + int alertable) { ACE_TRACE ("ACE_ReactorEx::handle_events"); // Stash the current time -- the destructor of this object will // automatically compute how much time elapsed since this method was // called. - ACE_Countdown_Time countdown (how_long); + ACE_Countdown_Time countdown (max_wait_time); #if defined (ACE_MT_SAFE) ACE_GUARD_RETURN (ACE_ReactorEx_Token, ace_mon, this->token_, -1); @@ -148,16 +149,26 @@ ACE_ReactorEx::handle_events (ACE_Time_Value *how_long, } // Check for pending timeout events. - ACE_Time_Value *wait_time = timer_queue_->calculate_timeout (how_long); + ACE_Time_Value *wait_time = timer_queue_->calculate_timeout (max_wait_time); // Translate into Win32 time value. int timeout = wait_time == 0 ? INFINITE : wait_time->msec (); + DWORD wait_status; // Wait for any of handles_ to be active, or until timeout expires. // If wait_all is true, then wait for all handles_ to be active. - DWORD wait_status = ::WaitForMultipleObjects (active_handles_, - handles_, - wait_all, - timeout); + + if (alertable) + // Allow asynchronous completion of ReadFileEx and WriteFileEx + // operations. + wait_status= ::WaitForMultipleObjectsEx (active_handles_, + handles_, + wait_all, + timeout); + else + wait_status= ::WaitForMultipleObjects (active_handles_, + handles_, + wait_all, + timeout); // Expire all pending timers. this->timer_queue_->expire (); diff --git a/ace/ReactorEx.h b/ace/ReactorEx.h index 6c4ec881b8a..ef72259970f 100644 --- a/ace/ReactorEx.h +++ b/ace/ReactorEx.h @@ -61,11 +61,10 @@ private: class ACE_Export ACE_ReactorEx_Notify : public ACE_Event_Handler // = TITLE - // Unblock the <ACE_ReactorEx> from its event loop, passing it an - // optional <ACE_Event_Handler> to dispatch. + // Unblock the <ACE_ReactorEx> from its event loop, passing it an + // optional <ACE_Event_Handler> to dispatch. // // = DESCRIPTION - // // This implementation is necessary for cases where the // <ACE_ReactorEx> is run in a multi-threaded program. In this // case, we need to be able to unblock WaitForMultipleObjects() @@ -130,61 +129,73 @@ public: virtual ~ACE_ReactorEx (void); // Close down the ReactorEx and release all of its resources. - // = Event loop drivers. Main event loop driver that blocks for - // -how_long- before returning (will return earlier if I/O or signal - // events occur). Note that -how_long- can be 0, in which case this - // method blocks until I/O events or signals occur. Returns 0 if - // timed out, 1 if an event occurred, and -1 if an error occured. - // -how_long- is decremented to reflect how much time the call to - // handle_events took. For instance, if a time value of 3 seconds - // is passed to handle_events and an event occurs after 2 seconds, - // -how_long- will equal 1 second. This can be used if an - // application wishes to handle events for some fixed amount of - // time. If wait_all is TRUE, then handle_events will only dispatch - // the handlers if *all* handles become active. If a timeout - // occurs, then no handlers will be dispatched. If - // <wait_all_callback> is NULL then we dispatch the <handle_signal> - // method on each and every HANDLE in the dispatch array. - // Otherwise, we just call back the <handle_signal> method of the - // <wait_all_callback> object, after first assigning the siginfo_t - // <si_handles_> argument to point to the array of signaled handles. - virtual int handle_events (ACE_Time_Value *how_long = 0, + // = Event loop drivers. + + virtual int handle_events (ACE_Time_Value *max_wait_time = 0, int wait_all = 0, - ACE_Event_Handler *wait_all_callback = 0); - virtual int handle_events (ACE_Time_Value &how_long, + ACE_Event_Handler *wait_all_callback = 0, + int alertable = 0); + // This event loop driver blocks for up to <max_wait_time> for I/O + // or signaled events occur. Note that <max_wait_time> can be 0, in + // which case this method blocks until I/O events or signaled events + // occur. Returns 0 if timed out, 1 if an event occurred, and -1 if + // an error occured. <max_wait_time> is decremented to reflect how + // much time this call took. For instance, if a time value of 3 + // seconds is passed to handle_events and an event occurs after 2 + // seconds, <max_wait_time> will equal 1 second. This can be used + // if an application wishes to handle events for some fixed amount + // of time. + // + // If <wait_all> is TRUE, then handle_events will only dispatch the + // handlers if *all* handles become active. If a timeout occurs, + // then no handlers will be dispatched. If <wait_all_callback> is 0 + // then we dispatch the <handle_signal> method on each and every + // registered HANDLE. Otherwise, we just call back the + // <handle_signal> method of the <wait_all_callback> object, after + // first assigning the siginfo_t <si_handles_> argument to point to + // the array of signaled handles. + // + // If <alertable> is true, then <WaitForMultipleObjectsEx> is used + // as the demultiplexing call, otherwise <WaitForMultipleObjects> is + // used. + + virtual int handle_events (ACE_Time_Value &max_wait_time, int wait_all = 0, - ACE_Event_Handler *wait_all_callback = 0); + ACE_Event_Handler *wait_all_callback = 0, + int alertable = 0); + // This method is just like the one above, except the <max_wait_time> + // value is a reference and must therefore never be NULL. // = Register and remove Handlers. virtual int register_handler (ACE_Event_Handler *eh, ACE_HANDLE handle = ACE_INVALID_HANDLE); - // Register an Event_Handler -eh-. If handle == ACE_INVALID_HANDLE - // the ReactorEx will call eh->get_handle() to extract the - // underlying I/O handle). + // Register an Event_Handler <eh>. If handle == ACE_INVALID_HANDLE + // the <ReactorEx> will call the <get_handle> method of <eh> to + // extract the underlying I/O handle. virtual int remove_handler (ACE_Event_Handler *eh, ACE_Reactor_Mask mask = 0); - // Removes -eh- from the ReactorEx. Note that the ReactorEx will - // call eh->get_handle() to extract the underlying I/O handle. If - // -mask- == ACE_Event_Handler::DONT_CALL then the -handle_close- - // method of the -eh- is not invoked. + // Removes <eh> from the ReactorEx. Note that the ReactorEx will + // call the <get_handle> method of <eh> to extract the underlying + // I/O handle. If <mask> == ACE_Event_Handler::DONT_CALL then the + // <handle_close> method of the <eh> is not invoked. int notify (ACE_Event_Handler * = 0, ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK); // Wakeup <ACE_ReactorEx> if currently blocked in - // WaitForMultipleObjects(). + // <WaitForMultipleObjects>. // = Timer management. virtual int schedule_timer (ACE_Event_Handler *eh, const void *arg, const ACE_Time_Value &delta, const ACE_Time_Value &interval = ACE_Time_Value::zero); - // Schedule an Event Handler -eh- that will expire after -delta- - // amount of time. If it expires then -arg- is passed in as the - // value to eh->handle_timeout. If -interval- is != to - // ACE_Time_Value::zero then it is used to reschedule -eh- + // Schedule an Event Handler <eh> that will expire after <delta> + // amount of time. If it expires then <arg> is passed in as the + // value to <handle_timeout> method call on <eh>. If <interval> is + // != to ACE_Time_Value::zero then it is used to reschedule <eh> // automatically. This method returns a timer handle that uniquely - // identifies the -eh- in an internal list. This timer handle can + // identifies the <eh> in an internal list. This timer handle can // be used to cancel an Event_Handler before it expires. The // cancellation ensures that timer_ids are unique up to values of // greater than 2 billion timers. As long as timers don't stay @@ -193,10 +204,10 @@ public: virtual int cancel_timer (ACE_Event_Handler *event_handler); // Cancel all Event_Handlers that match the address of - // -event_handler-. + // <event_handler>. virtual int cancel_timer (int timer_id, const void **arg = 0); - // Cancel the single Event_Handler that matches the -timer_id- value + // Cancel the single Event_Handler that matches the <timer_id> value // (which was returned from the schedule method). If arg is // non-NULL then it will be set to point to the ``magic cookie'' // argument passed in when the Event_Handler was registered. This @@ -210,7 +221,7 @@ public: protected: int dispatch (size_t index); - // Dispatches any active handles from handles_[-index-] to + // Dispatches any active handles from handles_[<index>] to // handles_[active_handles_] using <WaitForMultipleObjects> to poll // through our handle set looking for active handles. diff --git a/ace/ReactorEx.i b/ace/ReactorEx.i index fda66981674..a5cd53034a2 100644 --- a/ace/ReactorEx.i +++ b/ace/ReactorEx.i @@ -20,9 +20,12 @@ ACE_ReactorEx::cancel_timer (int timer_id, ACE_INLINE int ACE_ReactorEx::handle_events (ACE_Time_Value &how_long, - int wait_all) + int wait_all, + ACE_Event_Handler *wait_all_callback, + int alertable) { - return this->handle_events (&how_long, wait_all); + return this->handle_events (&how_long, wait_all, + wait_all_callback, alertable); } #endif /* ACE_WIN32 */ diff --git a/ace/SV_Semaphore_Complex.cpp b/ace/SV_Semaphore_Complex.cpp index 09aac60b0bf..1bcd3d64cec 100644 --- a/ace/SV_Semaphore_Complex.cpp +++ b/ace/SV_Semaphore_Complex.cpp @@ -103,12 +103,11 @@ ACE_SV_Semaphore_Complex::open (key_t k, // Get the value of the process counter. If it equals 0, then no // one has initialized the ACE_SV_Semaphore yet. - int semval; + int semval = ACE_SV_Semaphore_Simple::control (GETVAL, 0, 1); - if ((semval = ACE_SV_Semaphore_Simple::control (GETVAL, 0, 1)) < 0) + if (semval == -1) return this->init (); - - if (semval == 0) + else if (semval == 0) { // We should initialize by doing a SETALL, but that would // clear the adjust value that we set when we locked the diff --git a/ace/SV_Semaphore_Simple.cpp b/ace/SV_Semaphore_Simple.cpp index 29d97dfa8a3..f7a6809dbb2 100644 --- a/ace/SV_Semaphore_Simple.cpp +++ b/ace/SV_Semaphore_Simple.cpp @@ -121,26 +121,26 @@ ACE_SV_Semaphore_Simple::name_2_key (const char *name) { ACE_TRACE ("ACE_SV_Semaphore_Simple::name_2_key"); - if (name == 0 || !isalpha (*name)) + if (name == 0) { errno = EINVAL; return ACE_INVALID_SEM_KEY; } - - // The key is the character value of the first LUSED chars from name - // placed in proto. + else + { + // Basically "hash" the values in the <name>. This won't + // necessarily guarantee uniqueness of all keys. - u_long proto = 0; + u_long proto = 0; - for (int i = 0; i < LUSED; ++i) - { - if (*name == '\0') - break; - proto <<= 8; - proto |= *name++ & 0xff; - } + for (int i = 0; name[i] != '\0'; ++i) + { + proto <<= 8; + proto |= *name++ & 0xff; + } - return (key_t) proto; + return (key_t) proto; + } } // Open or create a ACE_SV_Semaphore. We return 1 if all is OK, else diff --git a/ace/SV_Semaphore_Simple.i b/ace/SV_Semaphore_Simple.i index 1e159f36604..a66806507f2 100644 --- a/ace/SV_Semaphore_Simple.i +++ b/ace/SV_Semaphore_Simple.i @@ -6,9 +6,6 @@ #include "ace/SV_Semaphore_Simple.h" #include "ace/Trace.h" -#undef LUSED -#define LUSED 4 /* # of chars used from name */ - inline int ACE_SV_Semaphore_Simple::control (int cmd, semun arg, diff --git a/ace/Signal.cpp b/ace/Signal.cpp index 50071e83619..bceff59af42 100644 --- a/ace/Signal.cpp +++ b/ace/Signal.cpp @@ -29,7 +29,10 @@ static ACE_SignalHandler ace_signal_handler_dispatcher = ACE_SignalHandler (ace_ static ACE_SignalHandler ace_signal_handlers_dispatcher = ACE_SignalHandler (ace_sig_handlers_dispatch); #else static ACE_SignalHandler ace_signal_handler_dispatcher = ACE_SignalHandler (ACE_Sig_Handler::dispatch); + +#if !defined (HPUX) static ACE_SignalHandler ace_signal_handlers_dispatcher = ACE_SignalHandler (ACE_Sig_Handlers::dispatch); +#endif /* HPUX */ #endif /* ACE_HAS_SIG_C_FUNC */ #if defined (ACE_MT_SAFE) @@ -331,9 +334,9 @@ ACE_Sig_Adapter::handle_signal (int signum, // ---------------------------------------- // The following classes are local to this file. -// HPUX sucks big time! +// There are bugs with HP/UX's C++ compiler that prevents this stuff +// from compiling... #if !defined (HPUX) -// This needs to be fixed... #define ACE_MAX_SIGNAL_HANDLERS size_t (20) // Keeps track of the id that uniquely identifies each registered diff --git a/ace/Signal.h b/ace/Signal.h index f627bd73222..f95703de081 100644 --- a/ace/Signal.h +++ b/ace/Signal.h @@ -271,7 +271,6 @@ private: // This is a normal C function. }; -// HPUX sucks big time! #if !defined (HPUX) class ACE_Export ACE_Sig_Handlers : public ACE_Sig_Handler // = TITLE diff --git a/ace/Synch.cpp b/ace/Synch.cpp index c8fb75545ab..b163eecc7a6 100644 --- a/ace/Synch.cpp +++ b/ace/Synch.cpp @@ -16,9 +16,36 @@ ACE_ALLOC_HOOK_DEFINE(ACE_Null_Mutex) ACE_ALLOC_HOOK_DEFINE(ACE_File_Lock) ACE_ALLOC_HOOK_DEFINE(ACE_RW_Process_Mutex) - ACE_ALLOC_HOOK_DEFINE(ACE_Process_Mutex) +ACE_TSS_Adapter::ACE_TSS_Adapter (void *object, ACE_THR_DEST f) + : ts_obj_ (object), + func_ (f) +{ + // ACE_TRACE ("ACE_TSS_Adapter::ACE_TSS_Adapter"); +} + +void +ACE_TSS_Adapter::cleanup (void) +{ + // ACE_TRACE ("ACE_TSS_Adapter::~ACE_TSS_Adapter"); + (*this->func_)(this->ts_obj_); // call cleanup routine for ts_obj_ +} + +extern "C" void +ACE_TSS_C_cleanup (void *object) +{ + // ACE_TRACE ("ACE_TSS_C_cleanup"); + if (object != 0) + { + ACE_TSS_Adapter *tss_adapter = (ACE_TSS_Adapter *) object; + // Perform cleanup on the real TS object. + tss_adapter->cleanup (); + // Delete the adapter object. + delete tss_adapter; + } +} + void ACE_Process_Mutex::dump (void) const { @@ -297,8 +324,6 @@ ACE_Mutex::~ACE_Mutex (void) ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Mutex::~ACE_Mutex")); } -#if defined (ACE_HAS_THREADS) - ACE_Event::ACE_Event (int manual_reset, int initial_state, int type, @@ -406,6 +431,8 @@ ACE_Auto_Event::dump (void) const ACE_Event::dump (); } +#if defined (ACE_HAS_THREADS) + ACE_ALLOC_HOOK_DEFINE(ACE_Recursive_Thread_Mutex) ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Mutex_Guard) diff --git a/ace/Synch.h b/ace/Synch.h index 0e2aba63078..1c0c5335b87 100644 --- a/ace/Synch.h +++ b/ace/Synch.h @@ -490,7 +490,35 @@ protected: ACE_Null_Mutex_Guard (const ACE_Null_Mutex_Guard &) {} }; -#if defined (ACE_HAS_THREADS) /* ACE platform supports some form of threading. */ +class ACE_TSS_Adapter + // = TITLE + // This class encapsulates a TSS object and its associated + // C++ destructor function. It is used by the ACE_TSS... + // methods (in Synch_T.cpp) in order to allow an extern + // "C" cleanup routine to be used. Needed by the "frigging" + // MVS C++ compiler. + // + // = DESCRIPTION + // Objects of this class are stored in thread specific + // storage. ts_obj_ points to the "real" object and + // func_ is a pointer to the C++ cleanup function for ts_obj_. + // +{ +public: + ACE_TSS_Adapter (void *object, ACE_THR_DEST f); + // Initialize the adapter. + + void cleanup (void); + // Perform the cleanup operation. + +//private: + + void *ts_obj_; + // The real TS object. + + ACE_THR_DEST func_; + // The real cleanup routine for ts_obj; +}; class ACE_Export ACE_Event // = TITLE @@ -610,6 +638,8 @@ public: // Declare the dynamic allocation hooks }; +#if defined (ACE_HAS_THREADS) /* ACE platform supports some form of threading. */ + class ACE_Export ACE_Thread_Mutex // = TITLE // ACE_Thread_Mutex wrapper (only valid for threads in the same diff --git a/ace/Synch_T.cpp b/ace/Synch_T.cpp index 4357c9702a3..60e0b02908f 100644 --- a/ace/Synch_T.cpp +++ b/ace/Synch_T.cpp @@ -246,6 +246,13 @@ ACE_TSS<TYPE>::dump (void) const } #if defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) +template <class TYPE> void +ACE_TSS<TYPE>::cleanup (void *ptr) +{ + // Cast this to the concrete TYPE * so the destructor gets called. + delete (TYPE *) ptr; +} + template <class TYPE> ACE_TSS<TYPE>::ACE_TSS (TYPE *ts_obj) : once_ (0), @@ -262,7 +269,11 @@ ACE_TSS<TYPE>::ACE_TSS (TYPE *ts_obj) ACE_ASSERT (this->once_ == 0); if (ACE_Thread::keycreate (&this->key_, - &ACE_TSS<TYPE>::cleanup, +#if defined (ACE_HAS_THR_C_DEST) + &ACE_TSS_C_cleanup, +#else + &ACE_TSS<TYPE>::cleanup, +#endif /* ACE_HAS_THR_C_DEST */ (void *) this) != 0) { int errnum = errno; @@ -274,8 +285,22 @@ ACE_TSS<TYPE>::ACE_TSS (TYPE *ts_obj) this->once_ = 1; +#if defined (ACE_HAS_THR_C_DEST) + // Encapsulate a ts_obj and it's destructor in an ACE_TSS_Adapter + ACE_TSS_Adapter *tss_adapter; + ACE_NEW (tss_adapter, + ACE_TSS_Adapter ((void *)ts_obj, ACE_TSS<TYPE>::cleanup)); + + // Put the adapter in thread specific storage + if (ACE_Thread::setspecific (this->key_, (void *) tss_adapter) != 0) + { + delete tss_adapter; + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Thread::setspecific() failed!")); + } +#else if (ACE_Thread::setspecific (this->key_, (void *) ts_obj) != 0) - ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Thread::setspecific() failed!")); + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Thread::setspecific() failed!")); +#endif /* ACE_HAS_THR_C_DEST */ } } @@ -293,8 +318,12 @@ ACE_TSS<TYPE>::ts_get (void) const if (this->once_ == 0) { if (ACE_Thread::keycreate ((ACE_thread_key_t *) &this->key_, - &ACE_TSS<TYPE>::cleanup, - (void *) this) != 0) +#if defined (ACE_HAS_THR_C_DEST) + &ACE_TSS_C_cleanup, +#else + &ACE_TSS<TYPE>::cleanup, +#endif /* ACE_HAS_THR_C_DEST */ + (void *) this) != 0) return 0; // Major problems, this should *never* happen! else // This *must* come last to avoid race conditions! Note @@ -305,6 +334,16 @@ ACE_TSS<TYPE>::ts_get (void) const TYPE *ts_obj = 0; +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + + // Get the adapter from thread-specific storage + if (ACE_Thread::getspecific (this->key_, (void **) &tss_adapter) == -1) + return 0; // This should not happen! + + // Check to see if this is the first time in for this thread. + if (tss_adapter == 0) +#else // Get the ts_obj from thread-specific storage. Note that no locks // are required here... if (ACE_Thread::getspecific (this->key_, (void **) &ts_obj) == -1) @@ -312,6 +351,7 @@ ACE_TSS<TYPE>::ts_get (void) const // Check to see if this is the first time in for this thread. if (ts_obj == 0) +#endif /* ACE_HAS_THR_C_DEST */ { // Allocate memory off the heap and store it in a pointer in // thread-specific storage (on the stack...). @@ -321,6 +361,19 @@ ACE_TSS<TYPE>::ts_get (void) const if (ts_obj == 0) return 0; +#if defined (ACE_HAS_THR_C_DEST) + // Encapsulate a ts_obj and it's destructor in an ACE_TSS_Adapter + ACE_NEW_RETURN (tss_adapter, + ACE_TSS_Adapter (ts_obj, ACE_TSS<TYPE>::cleanup), 0); + + // Put the adapter in thread specific storage + if (ACE_Thread::setspecific (this->key_, (void *) tss_adapter) != 0) + { + delete tss_adapter; + delete ts_obj; + return 0; // Major problems, this should *never* happen! + } +#else // Store the dynamically allocated pointer in thread-specific // storage. if (ACE_Thread::setspecific (this->key_, (void *) ts_obj) != 0) @@ -328,9 +381,14 @@ ACE_TSS<TYPE>::ts_get (void) const delete ts_obj; return 0; // Major problems, this should *never* happen! } +#endif /* ACE_HAS_THR_C_DEST */ } +#if defined (ACE_HAS_THR_C_DEST) + return (TYPE *) tss_adapter->ts_obj_; // return the underlying ts object +#else return ts_obj; +#endif /* ACE_HAS_THR_C_DEST */ } // Get the thread-specific object for the key associated with this @@ -348,11 +406,20 @@ ACE_TSS<TYPE>::ts_object (void) const else { TYPE *ts_obj = 0; +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + // Get the tss adapter from thread-specific storage + if (ACE_Thread::getspecific (this->key_, (void **) &tss_adapter) == -1) + return 0; // This should not happen! + else if (tss_adapter != 0) + // Extract the real TS object. + ts_obj = (TYPE *) tss_adapter->ts_obj_; +#else if (ACE_Thread::getspecific (this->key_, (void **) &ts_obj) == -1) return 0; // This should not happen! - else - return ts_obj; +#endif /* ACE_HAS_THR_C_DEST */ + return ts_obj; } } @@ -368,23 +435,38 @@ ACE_TSS<TYPE>::ts_object (TYPE *new_ts_obj) { TYPE *ts_obj = 0; +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + + if (ACE_Thread::getspecific (this->key_, (void **) &tss_adapter) == -1) + return 0; // This should not happen! + + if (tss_adapter != 0) + { + ts_obj = (TYPE *) tss_adapter->ts_obj_; + delete tss_adapter; // don't need this anymore + } + + ACE_NEW_RETURN (tss_adapter, + ACE_TSS_Adapter ((void *)new_ts_obj, ACE_TSS<TYPE>::cleanup), + 0); + + if (ACE_Thread::setspecific (this->key_, (void *) tss_adapter) == -1) + { + delete tss_adapter; + return ts_obj; // This should not happen! + } +#else if (ACE_Thread::getspecific (this->key_, (void **) &ts_obj) == -1) - return 0; // This should not happen! + return 0; // This should not happen! if (ACE_Thread::setspecific (this->key_, (void *) new_ts_obj) == -1) - return ts_obj; // This should not happen! + return ts_obj; // This should not happen! +#endif /* ACE_HAS_THR_C_DEST */ else return ts_obj; } } -/* static */ -template <class TYPE> void -ACE_TSS<TYPE>::cleanup (void *ptr) -{ - // This cast is necessary to invoke the destructor (if necessary). - delete (TYPE *) ptr; -} - ACE_ALLOC_HOOK_DEFINE(ACE_TSS_Guard) template <class LOCK> void @@ -405,7 +487,11 @@ ACE_TSS_Guard<LOCK>::init_key (void) this->key_ = ACE_OS::NULL_key; ACE_Thread::keycreate (&this->key_, +#if defined (ACE_HAS_THR_C_DEST) + &ACE_TSS_C_cleanup, +#else &ACE_TSS_Guard<LOCK>::cleanup, +#endif /* ACE_HAS_THR_C_DEST */ (void *) this); } @@ -422,7 +508,15 @@ ACE_TSS_Guard<LOCK>::release (void) // ACE_TRACE ("ACE_TSS_Guard<LOCK>::release"); ACE_Guard<LOCK> *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + ACE_Thread::getspecific (this->key_, (void **) &tss_adapter); + guard = (ACE_Guard<LOCK> *)tss_adapter->ts_obj_; +#else ACE_Thread::getspecific (this->key_, (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + return guard->release (); } @@ -432,7 +526,15 @@ ACE_TSS_Guard<LOCK>::remove (void) // ACE_TRACE ("ACE_TSS_Guard<LOCK>::remove"); ACE_Guard<LOCK> *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + ACE_Thread::getspecific (this->key_, (void **) &tss_adapter); + guard = (ACE_Guard<LOCK> *)tss_adapter->ts_obj_; +#else ACE_Thread::getspecific (this->key_, (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + return guard->remove (); } @@ -442,7 +544,15 @@ ACE_TSS_Guard<LOCK>::~ACE_TSS_Guard (void) // ACE_TRACE ("ACE_TSS_Guard<LOCK>::~ACE_TSS_Guard"); ACE_Guard<LOCK> *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + ACE_Thread::getspecific (this->key_, (void **) &tss_adapter); + guard = (ACE_Guard<LOCK> *)tss_adapter->ts_obj_; +#else ACE_Thread::getspecific (this->key_, (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + // Make sure that this pointer is NULL when we shut down... ACE_Thread::setspecific (this->key_, 0); ACE_Thread::keyfree (this->key_); @@ -467,7 +577,16 @@ ACE_TSS_Guard<LOCK>::ACE_TSS_Guard (LOCK &lock, int block) this->init_key (); ACE_Guard<LOCK> *guard; ACE_NEW (guard, ACE_Guard<LOCK> (lock, block)); + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter; + ACE_NEW (tss_adapter, + ACE_TSS_Adapter ((void *) guard, + ACE_TSS_Guard<LOCK>::cleanup)); + ACE_Thread::setspecific (this->key_, (void *) tss_adapter); +#else ACE_Thread::setspecific (this->key_, (void *) guard); +#endif /* ACE_HAS_THR_C_DEST */ } template <class LOCK> int @@ -476,7 +595,15 @@ ACE_TSS_Guard<LOCK>::acquire (void) // ACE_TRACE ("ACE_TSS_Guard<LOCK>::acquire"); ACE_Guard<LOCK> *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + ACE_Thread::getspecific (this->key_, (void **) &tss_adapter); + guard = (ACE_Guard<LOCK> *) tss_adapter->ts_obj_; +#else ACE_Thread::getspecific (this->key_, (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + return guard->acquire (); } @@ -486,7 +613,15 @@ ACE_TSS_Guard<LOCK>::tryacquire (void) // ACE_TRACE ("ACE_TSS_Guard<LOCK>::tryacquire"); ACE_Guard<LOCK> *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + ACE_Thread::getspecific (this->key_, (void **) &tss_adapter); + guard = (ACE_Guard<LOCK> *) tss_adapter->ts_obj_; +#else ACE_Thread::getspecific (this->key_, (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + return guard->tryacquire (); } @@ -498,7 +633,16 @@ ACE_TSS_Write_Guard<LOCK>::ACE_TSS_Write_Guard (LOCK &lock, int block) this->init_key (); ACE_Guard<LOCK> *guard; ACE_NEW (guard, ACE_Write_Guard<LOCK> (lock, block)); + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter; + ACE_NEW (tss_adapter, + ACE_TSS_Adapter ((void *) guard, + ACE_TSS_Guard<LOCK>::cleanup)); + ACE_Thread::setspecific (this->key_, (void *) tss_adapter); +#else ACE_Thread::setspecific (this->key_, (void *) guard); +#endif /* ACE_HAS_THR_C_DEST */ } template <class LOCK> int @@ -507,7 +651,15 @@ ACE_TSS_Write_Guard<LOCK>::acquire (void) // ACE_TRACE ("ACE_TSS_Write_Guard<LOCK>::acquire"); ACE_Write_Guard<LOCK> *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + ACE_Thread::getspecific (this->key_, (void **) &tss_adapter); + guard = (ACE_Guard<LOCK> *) tss_adapter->ts_obj_; +#else ACE_Thread::getspecific (this->key_, (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + return guard->acquire_write (); } @@ -517,7 +669,15 @@ ACE_TSS_Write_Guard<LOCK>::tryacquire (void) // ACE_TRACE ("ACE_TSS_Write_Guard<LOCK>::tryacquire"); ACE_Write_Guard<LOCK> *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + ACE_Thread::getspecific (this->key_, (void **) &tss_adapter); + guard = (ACE_Guard<LOCK> *) tss_adapter->ts_obj_; +#else ACE_Thread::getspecific (this->key_, (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + return guard->tryacquire_write (); } @@ -552,7 +712,16 @@ ACE_TSS_Read_Guard<LOCK>::ACE_TSS_Read_Guard (LOCK &lock, int block) this->init_key (); ACE_Guard<LOCK> *guard; ACE_NEW (guard, ACE_Read_Guard<LOCK> (lock, block)); + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter; + ACE_NEW (tss_adapter, + ACE_TSS_Adapter ((void *)guard, + ACE_TSS_Guard<LOCK>::cleanup)); + ACE_Thread::setspecific (this->key_, (void *) tss_adapter); +#else ACE_Thread::setspecific (this->key_, (void *) guard); +#endif /* ACE_HAS_THR_C_DEST */ } template <class LOCK> int @@ -561,7 +730,15 @@ ACE_TSS_Read_Guard<LOCK>::acquire (void) // ACE_TRACE ("ACE_TSS_Read_Guard<LOCK>::acquire"); ACE_Read_Guard<LOCK> *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + ACE_Thread::getspecific (this->key_, (void **) &tss_adapter); + guard = (ACE_Guard<LOCK> *)tss_adapter->ts_obj_; +#else ACE_Thread::getspecific (this->key_, (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + return guard->acquire_read (); } @@ -571,7 +748,15 @@ ACE_TSS_Read_Guard<LOCK>::tryacquire (void) // ACE_TRACE ("ACE_TSS_Read_Guard<LOCK>::tryacquire"); ACE_Read_Guard<LOCK> *guard = 0; + +#if defined (ACE_HAS_THR_C_DEST) + ACE_TSS_Adapter *tss_adapter = 0; + ACE_Thread::getspecific (this->key_, (void **) &tss_adapter); + guard = (ACE_Guard<LOCK> *) tss_adapter->ts_obj_; +#else ACE_Thread::getspecific (this->key_, (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + return guard->tryacquire_read (); } diff --git a/ace/Thread.h b/ace/Thread.h index 8d71fb8a29d..bb5411e8b95 100644 --- a/ace/Thread.h +++ b/ace/Thread.h @@ -132,7 +132,11 @@ public: // Change and/or examine calling thread's signal mask. static int keycreate (ACE_thread_key_t *keyp, +#if defined (ACE_HAS_THR_C_DEST) + ACE_THR_C_DEST destructor, +#else ACE_THR_DEST destructor, +#endif /* ACE_HAS_THR_C_DEST */ void * = 0); // Allocates a <keyp> that is used to identify data that is specific // to each thread in the process. The key is global to all threads diff --git a/ace/Thread.i b/ace/Thread.i index 1a5e2746f65..1684c0c7f14 100644 --- a/ace/Thread.i +++ b/ace/Thread.i @@ -9,7 +9,11 @@ ACE_INLINE int ACE_Thread::keycreate (ACE_thread_key_t *keyp, +#if defined (ACE_HAS_THR_C_DEST) + ACE_THR_C_DEST destructor, +#else ACE_THR_DEST destructor, +#endif /* ACE_HAS_THR_C_DEST */ void *inst) { ACE_TRACE ("ACE_Thread::keycreate"); diff --git a/ace/config-aix-4.1.x.h b/ace/config-aix-4.1.x.h index 6ee505fc0bf..04b6529e0f7 100644 --- a/ace/config-aix-4.1.x.h +++ b/ace/config-aix-4.1.x.h @@ -95,6 +95,7 @@ // EYE assume it does for now. #define ACE_LACKS_PTHREAD_THR_SIGSETMASK #define ACE_HAS_PTHREADS +#define ACE_LACKS_RWLOCK_T #define ACE_PTHREADS_MAP // include there diff --git a/ace/config-hpux-10.x.h b/ace/config-hpux-10.x.h index 83ff5c4eafb..b40b27c39ea 100644 --- a/ace/config-hpux-10.x.h +++ b/ace/config-hpux-10.x.h @@ -58,6 +58,7 @@ #define ACE_HAS_THREADS #define ACE_HAS_PTHREADS +#define ACE_LACKS_RWLOCK_T #define ACE_MT_SAFE #define ACE_HAS_SIGINFO_T #define ACE_LACKS_PTHREAD_THR_SIGSETMASK diff --git a/ace/config-irix6.2-sgic++.h b/ace/config-irix6.2-sgic++.h index c35f452cb17..47076738861 100644 --- a/ace/config-irix6.2-sgic++.h +++ b/ace/config-irix6.2-sgic++.h @@ -42,6 +42,7 @@ // IRIX 6.2 supports some variant of POSIX Pthreads, is it stock DCE? #define ACE_HAS_PTHREADS +#define ACE_LACKS_RWLOCK_T // Platform/compiler has the sigwait(2) prototype #define ACE_HAS_SIGWAIT diff --git a/ace/config-linux-lxpthreads.h b/ace/config-linux-lxpthreads.h new file mode 100644 index 00000000000..66dab145a99 --- /dev/null +++ b/ace/config-linux-lxpthreads.h @@ -0,0 +1,104 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for Linux +// platforms using GNU C++ and L. Xavier's pthreads package. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// Fixes a problem with new versions of Linux... +#ifndef msg_accrights +#undef msg_control +#define msg_accrights msg_control +#endif + +#ifndef msg_accrightslen +#undef msg_controllen +#define msg_accrightslen msg_controllen +#endif + +#define ACE_HAS_POSIX_TIME +#define ACE_LACKS_STRRECVFD + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Compiler/platform contains the <sys/syscall.h> file. +#define ACE_HAS_SYSCALL_H + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Platforms lacks UNIX domain sockets. +//#define ACE_LACKS_UNIX_DOMAIN_SOCKETS + +// Compiler/platform supports alloca(). +#define ACE_HAS_ALLOCA + +//#define ACE_LACKS_SENDMSG +//#define ACE_LACKS_RECVMSG +#define ACE_LACKS_MSYNC +#define ACE_LACKS_MADVISE + +// Compiler/platform has <alloca.h> +#define ACE_HAS_ALLOCA_H + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +// Compiler/platform defines a union semun for SysV shared memory. +#define ACE_HAS_SEMUN + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +#define ACE_HAS_SUNOS4_GETTIMEOFDAY +#define LINUX 1.2.10 + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// Linux defines struct msghdr in /usr/include/socket.h +#define ACE_HAS_MSG + +// TDN - adapted from file for SunOS4 platforms using the GNU g++ compiler +// Compiler's template mechanism must see source code (i.e., .C files). +#define ACE_TEMPLATES_REQUIRE_SOURCE + +#define ACE_TEMPLATES_REQUIRE_SPECIALIZATION + +// Compiler doesn't support static data member templates. +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES + +// Yes, we do have threads. +#define ACE_HAS_THREADS +// And they're even POSIX pthreads (MIT implementation) +#define ACE_HAS_PTHREADS +#define ACE_MT_SAFE +#define ACE_HAS_THREAD_SPECIFIC_STORAGE +#define ACE_HAS_PTHREADS_XAVIER // JCEJ 12/19/96 +#define ACE_HAS_SIGWAIT +#define ACE_LACKS_CONDATTR_PSHARED +#define ACE_LACKS_THREAD_STACK_ADDR // JCEJ 12/17/96 +#define ACE_LACKS_THREAD_STACK_SIZE // JCEJ 12/17/96 + +// To use pthreads on Linux you'll need to use the MIT version, for +// now... +#define _MIT_POSIX_THREADS 1 +#include /**/ <pthread.h> + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-linux-pthread.h b/ace/config-linux-pthread.h index 1b43cbbe68f..0cb01d1fbf0 100644 --- a/ace/config-linux-pthread.h +++ b/ace/config-linux-pthread.h @@ -86,8 +86,12 @@ // Yes, we do have threads. #define ACE_HAS_THREADS + +#define ACE_HAS_THREAD_SPECIFIC_STORAGE +#define ACE_MT_SAFE // And they're even POSIX pthreads (MIT implementation) #define ACE_HAS_PTHREADS +#define ACE_LACKS_RWLOCK_T #define ACE_HAS_SIGWAIT #define ACE_LACKS_CONDATTR_PSHARED diff --git a/ace/config-m88k.h b/ace/config-m88k.h index 212a0869c53..d5b2ac928dc 100644 --- a/ace/config-m88k.h +++ b/ace/config-m88k.h @@ -177,12 +177,8 @@ struct ip_mreq // Compile using multi-thread libraries. #define ACE_MT_SAFE -#if !defined (m88k) -// Platform supports Solaris threads. -#define ACE_HAS_STHREADS -#else #define ACE_HAS_PTHREADS -#endif /* m88k */ +#define ACE_LACKS_RWLOCK_T // Platform supports threads. #define ACE_HAS_THREADS diff --git a/ace/config-mvs.h b/ace/config-mvs.h index 7ead2fc5488..c6f13364a32 100644 --- a/ace/config-mvs.h +++ b/ace/config-mvs.h @@ -61,6 +61,8 @@ // Platform supports POSIX threads #define ACE_HAS_PTHREADS +#define ACE_LACKS_RWLOCK_T + // Platform has pthread_condattr_setkind_np() #define ACE_HAS_PTHREAD_CONDATTR_SETKIND_NP diff --git a/ace/config-osf1-4.0-g++.h b/ace/config-osf1-4.0-g++.h index f60a6e2577b..4564aa8234b 100644 --- a/ace/config-osf1-4.0-g++.h +++ b/ace/config-osf1-4.0-g++.h @@ -109,7 +109,11 @@ // DJT modified 6/5/96 // ACE supports POSIX Pthreads. //#define ACE_HAS_DCETHREADS + #define ACE_HAS_PTHREADS + +#define ACE_LACKS_RWLOCK_T + // DJT 6/6/96 added // IEEE Std 1003.1c-1995, POSIX System Application Program Interface #define ACE_HAS_PTHREADS_1003_DOT_1C diff --git a/ace/config-osf1-4.0.h b/ace/config-osf1-4.0.h index 5a8f4a565a0..711e3f5c547 100644 --- a/ace/config-osf1-4.0.h +++ b/ace/config-osf1-4.0.h @@ -88,6 +88,8 @@ // ACE supports POSIX Pthreads. //#define ACE_HAS_DCETHREADS #define ACE_HAS_PTHREADS + +#define ACE_LACKS_RWLOCK_T // DJT 6/6/96 added // IEEE Std 1003.1c-1995, POSIX System Application Program Interface #define ACE_HAS_PTHREADS_1003_DOT_1C diff --git a/ace/config-vxworks-ghs-1.8.h b/ace/config-vxworks-ghs-1.8.h index 02b3c8f0b72..bc20ffd918f 100644 --- a/ace/config-vxworks-ghs-1.8.h +++ b/ace/config-vxworks-ghs-1.8.h @@ -7,6 +7,8 @@ #if !defined (ACE_CONFIG_H) #define ACE_CONFIG_H +#define ACE_LACKS_COND_T +#define ACE_LACKS_RWLOCK_T #define ACE_HAS_BROKEN_SENDMSG #define ACE_HAS_BROKEN_WRITEV #define ACE_HAS_CHARPTR_SOCKOPT diff --git a/ace/config-vxworks5.2-g++.h b/ace/config-vxworks5.2-g++.h index 842c11d723d..82a6efd8440 100644 --- a/ace/config-vxworks5.2-g++.h +++ b/ace/config-vxworks5.2-g++.h @@ -7,6 +7,8 @@ #if !defined (ACE_CONFIG_H) #define ACE_CONFIG_H +#define ACE_LACKS_COND_T +#define ACE_LACKS_RWLOCK_T #define ACE_HAS_BROKEN_SENDMSG #define ACE_HAS_BROKEN_WRITEV #define ACE_HAS_CHARPTR_SOCKOPT diff --git a/ace/config-win32-msvc2.0.h b/ace/config-win32-msvc2.0.h index 357201c7caa..e68ead2d81f 100644 --- a/ace/config-win32-msvc2.0.h +++ b/ace/config-win32-msvc2.0.h @@ -220,4 +220,6 @@ inline void *operator new (unsigned int, void *p) { return p; } // Compiler/Platform supports the "using" keyword. // #define ACE_HAS_USING_KEYWORD +#define ACE_LACKS_COND_T +#define ACE_LACKS_RWLOCK_T #endif /* ACE_CONFIG_H */ diff --git a/ace/config-win32-msvc4.0.h b/ace/config-win32-msvc4.0.h index 62d41a93a30..97856aeacc3 100644 --- a/ace/config-win32-msvc4.0.h +++ b/ace/config-win32-msvc4.0.h @@ -226,4 +226,6 @@ // Compiler/Platform supports the "using" keyword. #define ACE_HAS_USING_KEYWORD +#define ACE_LACKS_COND_T +#define ACE_LACKS_RWLOCK_T #endif /* ACE_CONFIG_H */ diff --git a/apps/Gateway/Gateway/Event_Channel.h b/apps/Gateway/Gateway/Event_Channel.h index 47dd8572012..0cb928d7884 100644 --- a/apps/Gateway/Gateway/Event_Channel.h +++ b/apps/Gateway/Gateway/Event_Channel.h @@ -27,6 +27,7 @@ class ACE_Svc_Export ACE_Event_Channel : public ACE_Event_Handler public: // = Initialization and termination methods. ACE_Event_Channel (void); + ~ACE_Event_Channel (void); int open (int argc, char *argv[]); // Initialize the Channel. @@ -89,7 +90,7 @@ private: }; #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) -#include "ace/Event_Channel.cpp" +#include "Event_Channel.cpp" #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) diff --git a/apps/Gateway/Gateway/IO_Handler.cpp b/apps/Gateway/Gateway/IO_Handler.cpp index 94997955979..ba1b355b3ba 100644 --- a/apps/Gateway/Gateway/IO_Handler.cpp +++ b/apps/Gateway/Gateway/IO_Handler.cpp @@ -337,9 +337,9 @@ Consumer_Handler::nonblk_put (ACE_Message_Block *mb) // Event_List and ask the ACE_Reactor to inform us (via // handle_output()) when it is possible to try again. - ssize_t n; + ssize_t n = this->send (mb); - if ((n = this->send (mb)) == -1) + if (n == -1) { // Things have gone wrong, let's try to close down and set up a new reconnection. this->state (IO_Handler::FAILED); @@ -366,13 +366,13 @@ Consumer_Handler::nonblk_put (ACE_Message_Block *mb) return n; } -int +ssize_t Consumer_Handler::send (ACE_Message_Block *mb) { - ssize_t n; - size_t len = mb->length (); + ssize_t len = mb->length (); + ssize_t n = this->peer ().send (mb->rd_ptr (), len); - if ((n = this->peer ().send (mb->rd_ptr (), len)) <= 0) + if (n <= 0) return errno == EWOULDBLOCK ? 0 : n; else if (n < len) // Re-adjust pointer to skip over the part we did send. @@ -395,8 +395,7 @@ int Consumer_Handler::handle_output (ACE_HANDLE) { ACE_Message_Block *mb = 0; - int status = 0; - + ACE_DEBUG ((LM_DEBUG, "(%t) in handle_output on handle %d\n", this->get_handle ())); @@ -486,9 +485,8 @@ int Supplier_Handler::recv (ACE_Message_Block *&forward_addr) { Event *event; - size_t len; + ssize_t len; ssize_t n = 0; - ssize_t m = 0; size_t offset = 0; if (this->msg_frag_ == 0) @@ -538,9 +536,11 @@ Supplier_Handler::recv (ACE_Message_Block *&forward_addr) // At this point there is a complete, valid header in msg_frag_ len = sizeof event->buf_ + HEADER_SIZE - this->msg_frag_->length (); + ssize_t m = this->peer ().recv (event->buf_ + offset, len); + // Try to receive the remainder of the event - switch (m = this->peer ().recv (event->buf_ + offset, len)) + switch (m) { case -1: if (errno == EWOULDBLOCK) diff --git a/apps/Gateway/Gateway/IO_Handler.h b/apps/Gateway/Gateway/IO_Handler.h index c22f1a3df26..7bda073f09b 100644 --- a/apps/Gateway/Gateway/IO_Handler.h +++ b/apps/Gateway/Gateway/IO_Handler.h @@ -217,7 +217,7 @@ protected: int nonblk_put (ACE_Message_Block *mb); // Perform a non-blocking put(). - virtual int send (ACE_Message_Block *); + virtual ssize_t send (ACE_Message_Block *); // Send an event to a Consumer. }; diff --git a/apps/Gateway/Gateway/Makefile b/apps/Gateway/Gateway/Makefile index 3b54556c4f6..f81df3d73af 100644 --- a/apps/Gateway/Gateway/Makefile +++ b/apps/Gateway/Gateway/Makefile @@ -9,7 +9,7 @@ #---------------------------------------------------------------------------- BIN = gatewayd -#LIB = libGateway.a +LIB = libGateway.a SHLIB = libGateway.so FILES = Event_Channel \ diff --git a/apps/Gateway/Gateway/gatewayd.cpp b/apps/Gateway/Gateway/gatewayd.cpp index eaa05b7aa2f..48b6e9a173d 100644 --- a/apps/Gateway/Gateway/gatewayd.cpp +++ b/apps/Gateway/Gateway/gatewayd.cpp @@ -18,7 +18,7 @@ main (int argc, char *argv[]) else // Use static binding. { static char *l_argv[3] = { "-d" }; - ACE_Service_Object *so = ACE_SVC_INVOKE (ACE_Gateway); + ACE_Service_Object *so = ACE_SVC_INVOKE (Gateway); if (so->init (1, l_argv) == -1) ACE_ERROR ((LM_ERROR, "%p\n%a", "init", 1)); diff --git a/apps/Gateway/Gateway/svc.conf b/apps/Gateway/Gateway/svc.conf index 6c41415a9ce..db7a9d04ad5 100644 --- a/apps/Gateway/Gateway/svc.conf +++ b/apps/Gateway/Gateway/svc.conf @@ -1,3 +1,3 @@ #static Svc_Manager "-d -p 2913" -dynamic Gateway Service_Object * ./libGateway:_make_ACE_Gateway() active "-d -c connection_config -f consumer_config" +dynamic Gateway Service_Object * ./Gateway:_make_Gateway() active "-d -c connection_config -f consumer_config" diff --git a/apps/Makefile b/apps/Makefile index 9022247ebf5..3883598f646 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -10,7 +10,7 @@ INFO = README -DIRS = Gateway +DIRS = Gateway # The following directory isn't compiled by default since haven't # finished integrating it into ACE... diff --git a/examples/IPC_SAP/SOCK_SAP/C-inclient.cpp b/examples/IPC_SAP/SOCK_SAP/C-inclient.cpp index 84526a72421..049bd51d1e6 100644 --- a/examples/IPC_SAP/SOCK_SAP/C-inclient.cpp +++ b/examples/IPC_SAP/SOCK_SAP/C-inclient.cpp @@ -21,27 +21,27 @@ main (int argc, char *argv[]) int r_bytes; int n; - /* Create a local endpoint of communication */ + // Create a local endpoint of communication. if ((s_handle = ACE_OS::socket (PF_INET, SOCK_STREAM, 0)) == ACE_INVALID_HANDLE) ACE_OS::perror ("socket"), ACE_OS::exit (1); - /* Determine IP address of the server */ + // Determine IP address of the server. if ((hp = ACE_OS::gethostbyname (host)) == 0) ACE_OS::perror ("gethostbyname"), ACE_OS::exit (1); - /* Set up the address information to contact the server */ + // Set up the address information to contact the server. ACE_OS::memset ((void *) &saddr, 0, sizeof saddr); saddr.sin_family = AF_INET; saddr.sin_port = port_num; ACE_OS::memcpy (&saddr.sin_addr, hp->h_addr, hp->h_length); - /* Establish connection with remote server */ + // Establish connection with remote server. if (ACE_OS::connect (s_handle, (struct sockaddr *) &saddr, sizeof saddr) == -1) ACE_OS::perror ("connect"), ACE_OS::exit (1); - /* Send data to server (correctly handles - "incomplete writes" due to flow control) */ + // Send data to server (correctly handles "incomplete writes" due to + // flow control). while ((r_bytes = ACE_OS::read (ACE_STDIN, buf, sizeof buf)) > 0) for (w_bytes = 0; w_bytes < r_bytes; w_bytes += n) @@ -52,7 +52,7 @@ main (int argc, char *argv[]) if (ACE_OS::recv (s_handle, buf, 1) == 1) ACE_OS::write (ACE_STDOUT, buf, 1); - /* Explicitly close the connection */ + // Explicitly close the connection. if (ACE_OS::closesocket (s_handle) == -1) ACE_OS::perror ("close"), ACE_OS::exit (1); diff --git a/examples/IPC_SAP/SOCK_SAP/CPP-inclient.cpp b/examples/IPC_SAP/SOCK_SAP/CPP-inclient.cpp index 67809a9eee8..de2d0b1f6cb 100644 --- a/examples/IPC_SAP/SOCK_SAP/CPP-inclient.cpp +++ b/examples/IPC_SAP/SOCK_SAP/CPP-inclient.cpp @@ -1,7 +1,7 @@ -// This tests the non-blocking features of the ACE_SOCK_Connector class. // $Id$ - +// This tests the non-blocking features of the ACE_SOCK_Connector +// class. #include "ace/SOCK_Connector.h" #include "ace/INET_Addr.h" @@ -10,8 +10,8 @@ int main (int argc, char *argv[]) { - char *host = argc > 1 ? argv[1] : ACE_DEFAULT_SERVER_HOST; - u_short r_port = argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_SERVER_PORT; + char *host = argc > 1 ? argv[1] : ACE_DEFAULT_SERVER_HOST; + u_short r_port = argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_SERVER_PORT; ACE_Time_Value timeout (argc > 3 ? ACE_OS::atoi (argv[3]) : ACE_DEFAULT_TIMEOUT); char buf[BUFSIZ]; diff --git a/include/makeinclude/platform_linux_lxpthread.GNU b/include/makeinclude/platform_linux_lxpthread.GNU new file mode 100644 index 00000000000..67e517633ce --- /dev/null +++ b/include/makeinclude/platform_linux_lxpthread.GNU @@ -0,0 +1,25 @@ +# For pthreads support on Linux, you need +# -D_MIT_POSIX_THREADS +# -D_POSIX_THREADS +# -D_POSIX_THREAD_SAFE_FUNCTIONS +# in the CXX command line. Also, add -lpthreads to the LIBS. +# libpthreads.so comes with the sources of Linux libc-5.3.*, you need +# to compile it yourself (no binaries included) -- +# Jan Rychter <jwr@icm.edu.pl> + +CC = gcc -w +CXX = gcc -w -I. -fno-strict-prototypes -D__ACE_INLINE__ -D_MIT_POSIX_THREADS -D_POSIX_THREADS -D_POSIX_THREAD_SAFE_FUNCTIONS +DLD = $(CXX) +LD = $(CXX) +LIBS += -lpthread -lstdc++ +PIC = -fPIC +AR = ar +ARFLAGS = ruv +RANLIB = ranlib + +SOFLAGS = $(CPPFLAGS) -shared +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.so $< +PRELIB = (echo "int main() { return 0; }" > gcctemp.c && \ + $(COMPILE.cc) -o gcctemp.o gcctemp.c && \ + $(LINK.cc) -o gcctemp gcctemp.o $^ $(LDFLAGS) $(LIBS); \ + status=$$?; exit $$status) diff --git a/include/makeinclude/platform_linux_lxpthreads.GNU b/include/makeinclude/platform_linux_lxpthreads.GNU new file mode 100644 index 00000000000..67e517633ce --- /dev/null +++ b/include/makeinclude/platform_linux_lxpthreads.GNU @@ -0,0 +1,25 @@ +# For pthreads support on Linux, you need +# -D_MIT_POSIX_THREADS +# -D_POSIX_THREADS +# -D_POSIX_THREAD_SAFE_FUNCTIONS +# in the CXX command line. Also, add -lpthreads to the LIBS. +# libpthreads.so comes with the sources of Linux libc-5.3.*, you need +# to compile it yourself (no binaries included) -- +# Jan Rychter <jwr@icm.edu.pl> + +CC = gcc -w +CXX = gcc -w -I. -fno-strict-prototypes -D__ACE_INLINE__ -D_MIT_POSIX_THREADS -D_POSIX_THREADS -D_POSIX_THREAD_SAFE_FUNCTIONS +DLD = $(CXX) +LD = $(CXX) +LIBS += -lpthread -lstdc++ +PIC = -fPIC +AR = ar +ARFLAGS = ruv +RANLIB = ranlib + +SOFLAGS = $(CPPFLAGS) -shared +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.so $< +PRELIB = (echo "int main() { return 0; }" > gcctemp.c && \ + $(COMPILE.cc) -o gcctemp.o gcctemp.c && \ + $(LINK.cc) -o gcctemp gcctemp.o $^ $(LDFLAGS) $(LIBS); \ + status=$$?; exit $$status) diff --git a/tests/Makefile b/tests/Makefile index 35c36f3f78b..2ebad503491 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -10,7 +10,6 @@ BIN = Barrier_Test \ Buffer_Stream_Test \ - CPP_Test \ Future_Test \ Handle_Set_Test \ MM_Shared_Memory_Test \ @@ -28,6 +27,7 @@ BIN = Barrier_Test \ Reader_Writer_Test \ Recursive_Mutex_Test \ Service_Config_Test \ + SOCK_Test \ SPIPE_Test \ SString_Test \ SV_Shared_Memory_Test \ @@ -185,65 +185,6 @@ include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU $(WRAPPER_ROOT)/ace/Task.h \ $(WRAPPER_ROOT)/ace/Task_T.h \ test_config.h -.obj/CPP_Test.o .shobj/CPP_Test.so: CPP_Test.cpp \ - $(WRAPPER_ROOT)/ace/OS.h \ - $(WRAPPER_ROOT)/ace/Time_Value.h \ - $(WRAPPER_ROOT)/ace/config.h \ - $(WRAPPER_ROOT)/ace/stdcpp.h \ - $(WRAPPER_ROOT)/ace/Trace.h \ - $(WRAPPER_ROOT)/ace/Log_Msg.h \ - $(WRAPPER_ROOT)/ace/Log_Record.h \ - $(WRAPPER_ROOT)/ace/Log_Priority.h \ - $(WRAPPER_ROOT)/ace/ACE.h \ - $(WRAPPER_ROOT)/ace/ACE.i \ - $(WRAPPER_ROOT)/ace/Log_Record.i \ - $(WRAPPER_ROOT)/ace/Thread.h \ - $(WRAPPER_ROOT)/ace/Service_Config.h \ - $(WRAPPER_ROOT)/ace/Service_Object.h \ - $(WRAPPER_ROOT)/ace/Shared_Object.h \ - $(WRAPPER_ROOT)/ace/Event_Handler.h \ - $(WRAPPER_ROOT)/ace/Thread_Manager.h \ - $(WRAPPER_ROOT)/ace/Synch.h \ - $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ - $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ - $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ - $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ - $(WRAPPER_ROOT)/ace/Synch_T.h \ - $(WRAPPER_ROOT)/ace/Signal.h \ - $(WRAPPER_ROOT)/ace/Set.h \ - $(WRAPPER_ROOT)/ace/Reactor.h \ - $(WRAPPER_ROOT)/ace/Handle_Set.h \ - $(WRAPPER_ROOT)/ace/Timer_Queue.h \ - $(WRAPPER_ROOT)/ace/Token.h \ - $(WRAPPER_ROOT)/ace/Pipe.h \ - $(WRAPPER_ROOT)/ace/Pipe.i \ - $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ - $(WRAPPER_ROOT)/ace/SOCK_IO.h \ - $(WRAPPER_ROOT)/ace/SOCK.h \ - $(WRAPPER_ROOT)/ace/Addr.h \ - $(WRAPPER_ROOT)/ace/IPC_SAP.h \ - $(WRAPPER_ROOT)/ace/IPC_SAP.i \ - $(WRAPPER_ROOT)/ace/SOCK.i \ - $(WRAPPER_ROOT)/ace/SOCK_IO.i \ - $(WRAPPER_ROOT)/ace/INET_Addr.h \ - $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ - $(WRAPPER_ROOT)/ace/Reactor.i \ - $(WRAPPER_ROOT)/ace/Proactor.h \ - $(WRAPPER_ROOT)/ace/Message_Block.h \ - $(WRAPPER_ROOT)/ace/Malloc.h \ - $(WRAPPER_ROOT)/ace/Malloc_T.h \ - $(WRAPPER_ROOT)/ace/Memory_Pool.h \ - $(WRAPPER_ROOT)/ace/Mem_Map.h \ - $(WRAPPER_ROOT)/ace/ReactorEx.h \ - $(WRAPPER_ROOT)/ace/Message_Queue.h \ - $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ - $(WRAPPER_ROOT)/ace/Strategies.h \ - $(WRAPPER_ROOT)/ace/Strategies_T.h \ - $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ - $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ - $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ - $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ - test_config.h .obj/Future_Test.o .shobj/Future_Test.so: Future_Test.cpp \ $(WRAPPER_ROOT)/ace/Task.h \ $(WRAPPER_ROOT)/ace/Service_Object.h \ @@ -632,6 +573,64 @@ include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU $(WRAPPER_ROOT)/ace/ReactorEx.h \ $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ test_config.h +.obj/Priority_Task_Test.o .shobj/Priority_Task_Test.so: Priority_Task_Test.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/stdcpp.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies_T.h \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Task_T.h \ + test_config.h .obj/Pipe_Test.o .shobj/Pipe_Test.so: Pipe_Test.cpp \ $(WRAPPER_ROOT)/ace/Pipe.h \ $(WRAPPER_ROOT)/ace/ACE.h \ @@ -915,7 +914,67 @@ include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ $(WRAPPER_ROOT)/ace/Strategies.h \ $(WRAPPER_ROOT)/ace/Strategies_T.h \ - $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + test_config.h +.obj/SOCK_Test.o .shobj/SOCK_Test.so: SOCK_Test.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/stdcpp.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies_T.h \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + test_config.h .obj/SPIPE_Test.o .shobj/SPIPE_Test.so: SPIPE_Test.cpp \ $(WRAPPER_ROOT)/ace/OS.h \ $(WRAPPER_ROOT)/ace/Time_Value.h \ @@ -1331,7 +1390,7 @@ include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU $(WRAPPER_ROOT)/ace/Strategies.h \ $(WRAPPER_ROOT)/ace/Strategies_T.h \ $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ - test_config.h + TSS_Test_Errno.h test_config.h .obj/UPIPE_SAP_Test.o .shobj/UPIPE_SAP_Test.so: UPIPE_SAP_Test.cpp \ $(WRAPPER_ROOT)/ace/Stream.h \ $(WRAPPER_ROOT)/ace/ACE.h \ diff --git a/tests/Priority_Task_Test.cpp b/tests/Priority_Task_Test.cpp index bcc52856f43..1524af0c497 100644 --- a/tests/Priority_Task_Test.cpp +++ b/tests/Priority_Task_Test.cpp @@ -17,7 +17,6 @@ // // ============================================================================ - #include "ace/Service_Config.h" #include "ace/Task.h" #include "test_config.h" @@ -64,7 +63,12 @@ Priority_Task::svc (void) ACE_hthread_t thr_handle; ACE_Thread::self (thr_handle); int prio; - ACE_Thread::getprio (thr_handle, prio); + + if (ACE_Thread::getprio (thr_handle, prio) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "getprio failed"), -1); + + ACE_DEBUG ((LM_DEBUG, "(%t) prio = %d, priority_ = %d\n", + prio, this->priority_)); ACE_ASSERT (this->priority_ == prio); return 0; } diff --git a/tests/SOCK_Test.cpp b/tests/SOCK_Test.cpp new file mode 100644 index 00000000000..37665a99bfa --- /dev/null +++ b/tests/SOCK_Test.cpp @@ -0,0 +1,258 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// SOCK_Test.cpp +// +// = DESCRIPTION +// This is a simple test of the ACE_SOCK_Acceptor and +// ACE_SOCK_Connector classes. The test forks two processes or +// spawns two threads (depending upon the platform) and then +// executes client and server allowing them to connect and +// exchange data. +// +// = AUTHOR +// Prashant Jain and Doug Schmidt +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Thread.h" +#include "ace/Service_Config.h" +#include "ace/SOCK_Connector.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Handle_Set.h" +#include "test_config.h" + +static void * +client (void *arg) +{ +#if (defined (ACE_WIN32) || defined (VXWORKS)) && defined (ACE_HAS_THREADS) + // Insert thread into thr_mgr + ACE_Thread_Control thread_control (ACE_Service_Config::thr_mgr ()); + ACE_NEW_THREAD; +#endif /* (defined (ACE_WIN32) || defined (VXWORKS)) && defined (ACE_HAS_THREADS) */ + + ACE_INET_Addr *remote_addr = (ACE_INET_Addr *) arg; + ACE_INET_Addr server_addr (remote_addr->get_port_number (), "localhost"); + ACE_SOCK_Stream cli_stream; + ACE_SOCK_Connector con; + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting non-blocking connect\n")); + // Initiate timed, non-blocking connection with server. + + // Attempt a non-blocking connect to the server, reusing the local + // addr if necessary. + if (con.connect (cli_stream, server_addr, + (ACE_Time_Value *) &ACE_Time_Value::zero) == -1) + { + if (errno != EWOULDBLOCK) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "connection failed")); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting timed connect\n")); + + // Check if non-blocking connection is in progress, + // and wait up to ACE_DEFAULT_TIMEOUT seconds for it to complete. + ACE_Time_Value tv (ACE_DEFAULT_TIMEOUT); + + if (con.complete (cli_stream, &server_addr, &tv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "connection failed"), 0); + else + ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected to %s\n", + server_addr.get_host_name ())); + } + + if (cli_stream.disable (ACE_NONBLOCK) == -1) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "disable")); + + // Send data to server (correctly handles "incomplete writes"). + + for (char c = 'a'; c <= 'z'; c++) + if (cli_stream.send_n (&c, 1) == -1) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "send_n")); + + // Explicitly close the writer-side of the connection. + if (cli_stream.close_writer () == -1) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "close_writer")); + + char buf[1]; + + // Wait for handshake with server. + if (cli_stream.recv_n (buf, 1) != 1) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "recv_n")); + + // Close the connection completely. + if (cli_stream.close () == -1) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "close")); + + return 0; +} + +static void * +server (void *arg) +{ +#if (defined (ACE_WIN32) || defined (VXWORKS)) && defined (ACE_HAS_THREADS) + // Insert thread into thr_mgr + ACE_Thread_Control thread_control (ACE_Service_Config::thr_mgr ()); + ACE_NEW_THREAD; +#endif /* (defined (ACE_WIN32) || defined (VXWORKS)) && defined (ACE_HAS_THREADS) */ + + ACE_SOCK_Acceptor *peer_acceptor = (ACE_SOCK_Acceptor *) arg; + + if (peer_acceptor->enable (ACE_NONBLOCK) == -1) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "enable")); + + // Keep these objects out here to prevent excessive constructor + // calls... + ACE_SOCK_Stream new_stream; + ACE_INET_Addr cli_addr; + ACE_Handle_Set handle_set; + ACE_Time_Value tv (ACE_DEFAULT_TIMEOUT); + // Performs the iterative server activities. + + for (;;) + { + char buf[BUFSIZ]; + char t = 'a'; + + handle_set.reset (); + handle_set.set_bit (peer_acceptor->get_handle ()); + + int result = ACE_OS::select (int (peer_acceptor->get_handle ()) + 1, + handle_set, + 0, 0, &tv); + if (result == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "select"), 0); + else if (result == 0) + { + ACE_DEBUG ((LM_DEBUG, "(%P|%t) select timed out, shutting down\n")); + return 0; + } + + // Create a new ACE_SOCK_Stream endpoint (note automatic restart + // if errno == EINTR). + + while ((result = peer_acceptor->accept (new_stream, &cli_addr)) != -1) + { + ACE_DEBUG ((LM_DEBUG, "(%P|%t) client %s connected from %d\n", + cli_addr.get_host_name (), cli_addr.get_port_number ())); + + // Enable non-blocking I/O. + if (new_stream.enable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "enable"), 0); + + handle_set.reset (); + handle_set.set_bit (new_stream.get_handle ()); + + // Read data from client (terminate on error). + + for (ssize_t r_bytes; ;) + { + if (ACE_OS::select (int (new_stream.get_handle ()) + 1, + handle_set, + 0, 0, 0) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "select"), 0); + + while ((r_bytes = new_stream.recv_n (buf, 1)) > 0) + { + ACE_ASSERT (t == buf[0]); + t++; + } + + if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reached end of input, connection closed by client\n")); + + // Handshake back with client. + if (new_stream.send_n ("", 1) != 1) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "send_n")); + + // Close endpoint. + if (new_stream.close () == -1) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "close")); + return 0; + } + else if (r_bytes == -1) + { + if (errno == EWOULDBLOCK) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) no input available, going back to reading\n")); + else + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "recv_n"), 0); + } + } + } + + if (result == -1) + { + if (errno == EWOULDBLOCK) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) no connections available, going back to accepting\n")); + else + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "accept")); + } + } + return 0; +} + +static void +spawn (void) +{ + // Acceptor + ACE_SOCK_Acceptor peer_acceptor; + + // Create a server address. + ACE_INET_Addr server_addr; + + // Bind listener to any port and then find out what the port was. + if (peer_acceptor.open (ACE_Addr::sap_any) == -1 + || peer_acceptor.get_local_addr (server_addr) == -1) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "open")); + else + { + ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting server at port %d\n", + server_addr.get_port_number ())); + +#if !defined (ACE_WIN32) && !defined (VXWORKS) + switch (ACE_OS::fork ()) + { + case -1: + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n%a", "fork failed")); + exit (-1); + case 0: + ACE_LOG_MSG->sync ("child"); + client (&server_addr); + default: + server ((void *) &peer_acceptor); + ACE_OS::wait (); + } +#elif defined (ACE_HAS_THREADS) + if (ACE_Service_Config::thr_mgr ()->spawn + (ACE_THR_FUNC (server), (void *) &peer_acceptor, THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n%a", "thread create failed")); + + if (ACE_Service_Config::thr_mgr ()->spawn + (ACE_THR_FUNC (client), (void *) &server_addr, THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n%a", "thread create failed")); + + // Wait for the threads to exit. + ACE_Service_Config::thr_mgr ()->wait (); +#else + ACE_ERROR ((LM_ERROR, "(%P|%t) only one thread may be run in a process on this platform\n%a", 1)); +#endif /* ACE_HAS_THREADS */ + } +} + +int +main (int, char *[]) +{ + ACE_START_TEST ("SOCK_Test"); + + spawn (); + + ACE_END_TEST; + return 0; +} diff --git a/tests/TSS_Test.cpp b/tests/TSS_Test.cpp index 724f1c322b0..b13fc43c182 100644 --- a/tests/TSS_Test.cpp +++ b/tests/TSS_Test.cpp @@ -26,7 +26,6 @@ #include "test_config.h" #if defined (ACE_HAS_THREADS) -#if !defined (ACE_TEMPLATES_REQUIRE_PRAGMA) // AIX is evil static const int ITERATIONS = 100; @@ -157,7 +156,6 @@ handler (int signum) template class ACE_TSS<Errno>; #endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ -#endif /* !ACE_TEMPLATES_REQUIRE_PRAGMA */ #endif /* ACE_HAS_THREADS */ int @@ -165,7 +163,7 @@ main (int, char *[]) { ACE_START_TEST ("TSS_Test"); -#if defined (ACE_MT_SAFE) +#if defined (ACE_HAS_THREADS) ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); // Register a signal handler. @@ -178,13 +176,10 @@ main (int, char *[]) ACE_OS::perror ("ACE_Thread_Manager::spawn_n"); ACE_Service_Config::thr_mgr ()->wait (); -#elif defined (ACE_TEMPLATES_REQUIRE_PRAGMA) - ACE_ERROR ((LM_ERROR, - "This platform has an evil template instantiation mechanism...\n")); #else ACE_ERROR ((LM_ERROR, "threads are not supported on this platform\n")); -#endif /* defined (ACE_MT_SAFE) */ +#endif /* ACE_HAS_THREADS */ ACE_END_TEST; return 0; } diff --git a/tests/run_tests.bat b/tests/run_tests.bat index b8fe7f03160..34043bc9295 100644 --- a/tests/run_tests.bat +++ b/tests/run_tests.bat @@ -5,7 +5,6 @@ Barrier_Test Buffer_Stream_Test -CPP_Test Future_Test Handle_Set_Test Map_Manager_Test @@ -23,6 +22,7 @@ Reactors_Test Reader_Writer_Test Recursive_Mutex_Test Service_Config_Test +SOCK_Test SPIPE_Test SString_Test SV_Shared_Memory_Test diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 830260bbb6c..f57f6fbbc67 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -58,11 +58,11 @@ run Task_Test # uses Thread_Manager, Task run Thread_Manager_Test # uses Thread_Manager, Task run Thread_Pool_Test # uses Thread_Manager, Task run Future_Test # uses Thread_Manager, Task -run CPP_Test # uses Thread_Manager, SAP -run TSS_Test # uses Task, Mutex, Guard run Reactors_Test # uses Task, Mutex, Reactor run Reactor_Timer_Test # uses Event_Handler, Reactor run Reader_Writer_Test # uses Thread_Manager, Mutex +run SOCK_Test # uses Thread_Manager, SOCK_SAP +run TSS_Test # uses Task, Mutex, Guard # ifdef ACE_HAS_STREAM_PIPES run SPIPE_Test # uses SPIPE_Acceptor/Connector, Thread_Manager |