diff options
220 files changed, 7447 insertions, 6160 deletions
diff --git a/ChangeLog b/ChangeLog index fe34f20d67c..766c192a6aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,169 @@ +Mon Aug 4 03:26:30 UTC 2003 Don Hinton <dhinton@dresystems.com> + + * ace/Auto_Event.{h,cpp,inl}: + * ace/Barrier.{h,cpp,inl}: + * ace/Condition_Recursive_Thread_Mutex.{h,cpp,inl}: + * ace/Condition_T.{h,cpp,inl}: + * ace/Condition_Thread_Mutex.{h,cpp,inl}: + * ace/Event.{h,cpp,inl}: + * ace/Guard_T.{h,cpp,inl}: + * ace/Lock.{h,cpp,inl}: + * ace/Lock_Adapter_T.{h,cpp,inl}: + * ace/Manual_Event.{h,cpp,inl}: + * ace/Mutex.{h,cpp,inl}: + * ace/Null_Barrier.h: + * ace/Null_Condition.h: + * ace/Null_Mutex.h: + * ace/Null_Semaphore.h: + * ace/RW_Mutex.{h,cpp,inl}: + * ace/RW_Thread_Mutex.{h,cpp,inl}: + * ace/Recursive_Thread_Mutex.{h,cpp,inl}: + * ace/Reverse_Lock_T.{h,cpp,inl}: + * ace/Semaphore.{h,cpp,inl}: + * ace/Synch_Traits.h: + * ace/TSS_Adapter.{h,cpp,inl}: + * ace/TSS_T.{h,cpp,inl}: + * ace/Thread_Mutex.{h,cpp,inl}: + * ace/Thread_Semaphore.{h,cpp,inl}: + * ace/Synch.{h,cpp,i}: + * ace/Synch_T.{h,cpp,i}: + Moved all the code out of Synch* and into new files, roughly one + per class as part of the footprint and compile time reduciton + effort. + + * ace/TSS_T.h: + * ace/OS.h: + Moved the ACE_TSS_TYPE macros from OS.h to TSS_T.h: + + * ace/Token.{h,i}: + * ace/Synch.{h,i}: + Moved the ACE_Noop_Token class from Synch.* to Token.*. + + * ace/ARGV.cpp: + * ace/Activation_Queue.h: + * ace/Active_Map_Manager_T.h: + * ace/Asynch_Pseudo_Task.h: + * ace/Atomic_Op.h: + * ace/Atomic_Op_T.{h,i}: + * ace/Based_Pointer_Repository.{cpp,h}: + * ace/Bound_Ptr.i: + * ace/Cached_Connect_Strategy_T.{cpp,h}: + * ace/Capabilities.h: + * ace/Configuration.h: + * ace/Containers_T.cpp: + * ace/DLL_Manager.{cpp,h}: + * ace/Dump.{cpp,h}: + * ace/Dynamic.cpp: + * ace/Event_Handler.h: + * ace/Filecache.h: + * ace/Framework_Component.{h,cpp,inl}: + * ace/Free_List.{h,i}: + * ace/Future.h: + * ace/Handle_Set.cpp: + * ace/Hash_Cache_Map_Manager_T.{h,i}: + * ace/Hash_Map_With_Allocator_T.h: + * ace/High_Res_Timer.cpp: + * ace/Lib_Find.cpp: + * ace/Local_Name_Space.h: + * ace/Local_Name_Space_T.h: + * ace/Log_Msg.{cpp,h}: + * ace/Log_Record.{h,i}: + * ace/MEM_SAP.i: + * ace/Malloc.cpp: + * ace/Malloc_Allocator.cpp: + * ace/Malloc_T.h: + * ace/Map_Manager.{h,i}: + * ace/Memory_Pool.cpp: + * ace/Message_Block.cpp: + * ace/Message_Queue.h: + * ace/Message_Queue_T.h: + * ace/Metrics_Cache.h: + * ace/Name_Request_Reply.cpp: + * ace/Object_Manager.{cpp,h}: + * ace/POSIX_Asynch_IO.h: + * ace/POSIX_CB_Proactor.h: + * ace/Proactor.cpp: + * ace/Process_Manager.{cpp,h}: + * ace/Process_Mutex.{cpp,h}: + * ace/Process_Semaphore.h: + * ace/RB_Tree.{cpp,i}: + * ace/SOCK_Acceptor.cpp: + * ace/SOCK_Dgram.cpp: + * ace/SOCK_Dgram_Mcast.h: + * ace/SOCK_SEQPACK_Acceptor.cpp: + * ace/SPIPE_Acceptor.h: + * ace/Select_Reactor_Base.cpp: + * ace/Select_Reactor_T.{cpp,h}: + * ace/Service_Repository.{h,i}: + * ace/Service_Types.{h,i}: + * ace/Signal.{cpp,h}: + * ace/Singleton.{cpp,h}: + * ace/Strategies_T.{cpp,h}: + * ace/System_Time.h: + * ace/Task_T.{cpp,h}: + * ace/Test_and_Set.cpp: + * ace/Thread_Exit.cpp: + * ace/Thread_Manager.{cpp,h}: + * ace/Timeprobe.h: + * ace/Timer_Queue.h: + * ace/Timer_Queue_T.cpp: + * ace/Token.{cpp,h,i}: + * ace/Token_Invariants.h: + * ace/Token_Manager.h: + * ace/UPIPE_Acceptor.h: + * ace/UPIPE_Connector.h: + * ace/UPIPE_Stream.h: + * ace/UUID.h: + * ace/Unbounded_Queue.cpp: + * apps/drwho/BS_Client.cpp: + * examples/ASX/Event_Server/Event_Server/Consumer_Router.h: + * examples/ASX/Event_Server/Event_Server/Peer_Router.h: + * examples/ASX/UPIPE_Event_Server/Peer_Router.h: + * examples/C++NPv2/Logging_Event_Handler_Ex.h: + * examples/Logger/simple-server/Reactor_Singleton.h: + * examples/Misc/test_get_opt.cpp: + * examples/Misc/test_set.cpp: + * examples/Misc/test_trace.cpp: + * examples/Reactor/Misc/test_timer_queue.cpp: + * examples/Shared_Malloc/test_persistence.cpp: + * examples/Threads/TSS_Data.h: + * examples/Threads/barrier2.cpp: + * examples/Threads/task_one.cpp: + * examples/Timer_Queue/Thread_Timer_Queue_Test.h : + * performance-tests/SCTP/Options_Manager.cpp + * performance-tests/Server_Concurrency/Leader_Follower/RT_CORBA_Leader_Follower.h: + * performance-tests/Server_Concurrency/Queue_Based_Workers/RT_CORBA_Workers.cpp: + * performance-tests/Server_Concurrency/Queue_Based_Workers/RT_CORBA_Workers.h: + * performance-tests/Server_Concurrency/Queue_Based_Workers/workers.cpp: + * tests/Aio_Platform_Test.cpp: + * tests/Basic_Types_Test.cpp: + * tests/Cached_Allocator_Test.cpp: + * tests/MT_Reference_Counted_Event_Handler_Test.cpp: + * tests/Malloc_Test.cpp: + * tests/Message_Block_Test.cpp: + * tests/Message_Queue_Notifications_Test.cpp: + * tests/Reactor_Timer_Test.cpp: + * tests/Recursive_Condition_Bug_Test.cpp: + * tests/Task_Test.cpp: + * tests/Thread_Manager_Test.cpp: + * tests/Thread_Pool_Test.cpp: + * tests/Timeprobe_Test.cpp: + * tests/Timer_Queue_Reference_Counting_Test.cpp: + * tests/Timer_Queue_Test.cpp: + * tests/Token_Strategy_Test.cpp: + Refactored the includes due to Synch changes above. + + * etc/ace.doxygen: + Added "__ACE_INLINE__" and ACE_TEMPLATES_REQUIRE_SOURCE to + PREDEFINES so that the all the includes would show up in the + doxygen file reference pages. + + * ace/Log_Msg.{h,cpp}: + Removed the static log_msg_tss_key_ variable from ACE_Log_Msg + and added a free function in Log_Msg.cpp with a static local + variable to hold the same value. The obviates the need to + include OS.h in Log_Msg.h. + Sun Aug 3 20:55:24 2003 Balachandran Natarajan <bala@dre.vanderbilt.edu> * tests/RMCast/RMCast_Reassembly_Test.cpp: diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 9233c059534..2b20e5b8581 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,20 @@ +Mon Aug 4 03:26:30 UTC 2003 Don Hinton <dhinton@dresystems.com> + + * TAO/tao/Muxed_TMS.h: + * TAO/tao/ObjectKey_Table.h: + * TAO/tao/PolicyFactory_Registry.h: + * TAO/tao/Typecode.cpp: + #included Null_Mutex.h needed due to Synch changes in ACE. + + * TAO/tao/Typecode.h: + #included Thread_Mutex.h needed due to Synch changes in ACE. + + * TAO/tao/orbconf.h: + #included Synch_Traits.h needed due to Synch changes in ACE. + + * TAO/tao/Sequence.cpp: + #included OS.h needed due to Synch changes in ACE. + Sun Aug 3 21:56:38 2003 Balachandran Natarajan <bala@dre.vanderbilt.edu> * orbsvcs/tests/ImplRepo/airplane_client_i.cpp: diff --git a/TAO/tao/Muxed_TMS.h b/TAO/tao/Muxed_TMS.h index 82c7843376a..9c84a3deec8 100644 --- a/TAO/tao/Muxed_TMS.h +++ b/TAO/tao/Muxed_TMS.h @@ -23,6 +23,7 @@ #include "ace/Functor.h" #include "ace/Hash_Map_Manager.h" +#include "ace/Null_Mutex.h" class TAO_Pluggable_Reply_Params; diff --git a/TAO/tao/ObjectKey_Table.h b/TAO/tao/ObjectKey_Table.h index a71a25efd16..650918e12ed 100644 --- a/TAO/tao/ObjectKey_Table.h +++ b/TAO/tao/ObjectKey_Table.h @@ -21,6 +21,7 @@ #include "tao/TAO_Export.h" #include "ace/Functor.h" +#include "ace/Null_Mutex.h" // Forward declarations diff --git a/TAO/tao/PolicyFactory_Registry.h b/TAO/tao/PolicyFactory_Registry.h index cc6bee524b3..64182a7cd33 100644 --- a/TAO/tao/PolicyFactory_Registry.h +++ b/TAO/tao/PolicyFactory_Registry.h @@ -24,6 +24,7 @@ #include "PortableInterceptorC.h" #include "PolicyC.h" #include "ace/Map_Manager.h" +#include "ace/Null_Mutex.h" class TAO_ORB_Core; diff --git a/TAO/tao/Sequence.cpp b/TAO/tao/Sequence.cpp index 38dbcf498ff..351572383e9 100644 --- a/TAO/tao/Sequence.cpp +++ b/TAO/tao/Sequence.cpp @@ -3,6 +3,7 @@ #include "tao/Sequence.h" #include "ace/Message_Block.h" #include "ace/Log_Msg.h" +#include "ace/OS.h" #if !defined (__ACE_INLINE__) #include "tao/Sequence.i" diff --git a/TAO/tao/Typecode.cpp b/TAO/tao/Typecode.cpp index 464fb25b7d4..0e80f0bffcd 100644 --- a/TAO/tao/Typecode.cpp +++ b/TAO/tao/Typecode.cpp @@ -20,6 +20,7 @@ #include "tao/CORBA_String.h" #include "tao/debug.h" #include "ace/Malloc_Base.h" +#include "ace/Null_Mutex.h" #if !defined (__ACE_INLINE__) # include "tao/Typecode.i" diff --git a/TAO/tao/Typecode.h b/TAO/tao/Typecode.h index 6a35e3d1839..be948e0dfba 100644 --- a/TAO/tao/Typecode.h +++ b/TAO/tao/Typecode.h @@ -21,6 +21,7 @@ #include "ace/Hash_Map_Manager.h" #include "ace/Unbounded_Queue.h" +#include "ace/Thread_Mutex.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/TAO/tao/orbconf.h b/TAO/tao/orbconf.h index 0bd007966ea..969f6baebf8 100644 --- a/TAO/tao/orbconf.h +++ b/TAO/tao/orbconf.h @@ -22,6 +22,7 @@ // particular, it is needed for the definition of ACE_LITTLE_ENDIAN. #include "ace/Basic_Types.h" #include "ace/Global_Macros.h" +#include "ace/Synch_Traits.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/ace/ARGV.cpp b/ace/ARGV.cpp index 4304b8b3eae..0a833c6040d 100644 --- a/ace/ARGV.cpp +++ b/ace/ARGV.cpp @@ -4,12 +4,14 @@ // Transforms a string BUF into an ARGV-style vector of strings. #include "ace/ARGV.h" -#include "ace/Log_Msg.h" #if !defined (__ACE_INLINE__) #include "ace/ARGV.i" #endif /* __ACE_INLINE__ */ +#include "ace/Log_Msg.h" +#include "ace/OS.h" + ACE_RCSID(ace, ARGV, "$Id$") ACE_ALLOC_HOOK_DEFINE (ACE_ARGV) diff --git a/ace/Activation_Queue.h b/ace/Activation_Queue.h index 1fcb6b7a297..4557e248c67 100644 --- a/ace/Activation_Queue.h +++ b/ace/Activation_Queue.h @@ -15,13 +15,14 @@ #define ACE_ACTIVATION_QUEUE_H #include /**/ "ace/pre.h" -#include "ace/Synch_T.h" +#include "ace/ACE_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/Message_Queue.h" +#include "ace/Condition_Thread_Mutex.h" #include "ace/Method_Request.h" // Be compatible with the terminology in the POSA2 book! diff --git a/ace/Active_Map_Manager_T.h b/ace/Active_Map_Manager_T.h index ea02a28ad7c..6aca3966ab2 100644 --- a/ace/Active_Map_Manager_T.h +++ b/ace/Active_Map_Manager_T.h @@ -22,6 +22,8 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ +#include "ace/Null_Mutex.h" + /** * @class ACE_Active_Map_Manager * diff --git a/ace/Asynch_Pseudo_Task.h b/ace/Asynch_Pseudo_Task.h index 825d94a44c3..2a9da3b25e8 100644 --- a/ace/Asynch_Pseudo_Task.h +++ b/ace/Asynch_Pseudo_Task.h @@ -23,6 +23,7 @@ #include "ace/Reactor.h" #include "ace/Select_Reactor.h" #include "ace/Task.h" +#include "ace/Manual_Event.h" /** diff --git a/ace/Atomic_Op.h b/ace/Atomic_Op.h index 8651e5cf2af..0d3730b477f 100644 --- a/ace/Atomic_Op.h +++ b/ace/Atomic_Op.h @@ -20,8 +20,7 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/Synch.h" - +#include "ace/Thread_Mutex.h" // Include the templates here. #include "ace/Atomic_Op_T.h" diff --git a/ace/Atomic_Op_T.h b/ace/Atomic_Op_T.h index 63b20b6db4b..00f5d71f611 100644 --- a/ace/Atomic_Op_T.h +++ b/ace/Atomic_Op_T.h @@ -20,9 +20,6 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/Synch.h" - - /** * @class ACE_Atomic_Op_Ex * diff --git a/ace/Atomic_Op_T.i b/ace/Atomic_Op_T.i index 2ba365a1aa6..b741a2a521a 100644 --- a/ace/Atomic_Op_T.i +++ b/ace/Atomic_Op_T.i @@ -2,6 +2,8 @@ // // $Id$ +#include "ace/Guard_T.h" + // // ACE_Atomic_Op_Ex inline functions // diff --git a/ace/Auto_Event.cpp b/ace/Auto_Event.cpp new file mode 100644 index 00000000000..c0b6ba9da4b --- /dev/null +++ b/ace/Auto_Event.cpp @@ -0,0 +1,30 @@ +// $Id$ + +#if !defined (__ACE_INLINE__) +#include "ace/Auto_Event.inl" +#endif /* __ACE_INLINE__ */ + + +ACE_RCSID(ace, Auto_Event, "$Id$") + +#if defined (ACE_HAS_WCHAR) +ACE_Auto_Event::ACE_Auto_Event (int initial_state, + int type, + const wchar_t *name, + void *arg) + : ACE_Event (0, + initial_state, + type, + ACE_TEXT_WCHAR_TO_TCHAR (name), + arg) +{ +} +#endif /* ACE_HAS_WCHAR */ + +void +ACE_Auto_Event::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_Event::dump (); +#endif /* ACE_HAS_DUMP */ +} diff --git a/ace/Auto_Event.h b/ace/Auto_Event.h new file mode 100644 index 00000000000..e722ee89500 --- /dev/null +++ b/ace/Auto_Event.h @@ -0,0 +1,69 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Auto_Event.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_AUTO_EVENT_H +#define ACE_AUTO_EVENT_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Event.h" + +/** + * @class ACE_Auto_Event + * + * @brief Auto Events. + * + * Specialization of Event mechanism which wakes up one waiting + * thread on <signal>. All platforms support process-scope locking + * support. However, only Win32 platforms support global naming and + * system-scope locking support. + */ +class ACE_Export ACE_Auto_Event : public ACE_Event +{ +public: + /// constructor which will create auto event + ACE_Auto_Event (int initial_state = 0, + int type = USYNC_THREAD, + const char *name = 0, + void *arg = 0); + +#if defined (ACE_HAS_WCHAR) + /// constructor which will create auto event (wchar_t version) + ACE_Auto_Event (int initial_state, + int type, + const wchar_t *name, + void *arg = 0); +#endif /* ACE_HAS_WCHAR */ + + /// Default dtor. + ~ACE_Auto_Event (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks + ACE_ALLOC_HOOK_DECLARE; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Auto_Event.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_AUTO_EVENT_H */ diff --git a/ace/Auto_Event.inl b/ace/Auto_Event.inl new file mode 100644 index 00000000000..e8858bfa4a6 --- /dev/null +++ b/ace/Auto_Event.inl @@ -0,0 +1,7 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_Auto_Event::~ACE_Auto_Event (void) +{ +} diff --git a/ace/Barrier.cpp b/ace/Barrier.cpp new file mode 100644 index 00000000000..d9763395ee4 --- /dev/null +++ b/ace/Barrier.cpp @@ -0,0 +1,143 @@ +// $Id$ + +#include "ace/Barrier.h" + +#if defined (ACE_HAS_THREADS) + +#if !defined (__ACE_INLINE__) +#include "ace/Barrier.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Barrier, "$Id$") + +ACE_ALLOC_HOOK_DEFINE(ACE_Sub_Barrier) + +void +ACE_Sub_Barrier::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Sub_Barrier::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->barrier_finished_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("running_threads_ = %d"), this->running_threads_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Sub_Barrier::ACE_Sub_Barrier (u_int count, + ACE_Thread_Mutex &lock, + const ACE_TCHAR *name, + void *arg) + : barrier_finished_ (lock, name, arg), + running_threads_ (count) +{ +// ACE_TRACE ("ACE_Sub_Barrier::ACE_Sub_Barrier"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Barrier) + +void +ACE_Barrier::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Barrier::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->lock_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("current_generation_ = %d"), this->current_generation_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ncount_ = %d"), this->count_)); + this->sub_barrier_1_.dump (); + this->sub_barrier_2_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Barrier::ACE_Barrier (u_int count, + const ACE_TCHAR *name, + void *arg) + : lock_ (name, (ACE_mutexattr_t *) arg), + current_generation_ (0), + count_ (count), + sub_barrier_1_ (count, lock_, name, arg), + sub_barrier_2_ (count, lock_, name, arg) +{ +// ACE_TRACE ("ACE_Barrier::ACE_Barrier"); + this->sub_barrier_[0] = &this->sub_barrier_1_; + this->sub_barrier_[1] = &this->sub_barrier_2_; +} + +int +ACE_Barrier::wait (void) +{ +// ACE_TRACE ("ACE_Barrier::wait"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + ACE_Sub_Barrier *sbp = + this->sub_barrier_[this->current_generation_]; + + // Check for shutdown... + if (sbp == 0) + return -1; + + if (sbp->running_threads_ == 1) + { + // We're the last running thread, so swap generations and tell + // all the threads waiting on the barrier to continue on their + // way. + + sbp->running_threads_ = this->count_; + // Swap generations. + this->current_generation_ = 1 - this->current_generation_; + sbp->barrier_finished_.broadcast (); + } + else + { + --sbp->running_threads_; + + // Block until all the other threads wait(). + while (sbp->running_threads_ != this->count_) + sbp->barrier_finished_.wait (); + } + + return 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Barrier) + +ACE_Thread_Barrier::ACE_Thread_Barrier (u_int count, const ACE_TCHAR *name) + : ACE_Barrier (count, name) +{ +// ACE_TRACE ("ACE_Thread_Barrier::ACE_Thread_Barrier"); +} + +void +ACE_Thread_Barrier::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Thread_Barrier::dump"); + ACE_Barrier::dump (); +#endif /* ACE_HAS_DUMP */ +} + +#if 0 +ACE_ALLOC_HOOK_DEFINE(ACE_Process_Barrier) + +ACE_Process_Barrier::ACE_Process_Barrier (u_int count, const ACE_TCHAR *name) + : ACE_Barrier (count, USYNC_PROCESS, name) +{ +// ACE_TRACE ("ACE_Process_Barrier::ACE_Process_Barrier"); +} + +void +ACE_Process_Barrier::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Process_Barrier::dump"); + ACE_Barrier::dump (); +#endif /* ACE_HAS_DUMP */ +} +#endif /* 0 */ + +#endif /* ACE_HAS_THREADS */ diff --git a/ace/Barrier.h b/ace/Barrier.h new file mode 100644 index 00000000000..56d163caad9 --- /dev/null +++ b/ace/Barrier.h @@ -0,0 +1,189 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Barrier.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_BARRIER_H +#define ACE_BARRIER_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// ACE platform supports some form of threading. +#if !defined (ACE_HAS_THREADS) +/** + * @class ACE_Barrier + * + * @brief This is a no-op to make ACE "syntactically consistent." + */ +class ACE_Export ACE_Barrier +{ +public: + ACE_Barrier (unsigned int, const ACE_TCHAR * = 0, void * = 0) {} + ~ACE_Barrier (void) {} + int wait (void) { ACE_NOTSUP_RETURN (-1); } + void dump (void) const {} +}; + +#else /* ACE_HAS_THREADS */ + +#include "ace/Condition_Thread_Mutex.h" + +struct ACE_Export ACE_Sub_Barrier +{ + // = Initialization. + ACE_Sub_Barrier (unsigned int count, + ACE_Thread_Mutex &lock, + const ACE_TCHAR *name = 0, + void *arg = 0); + + ~ACE_Sub_Barrier (void); + + /// True if this generation of the barrier is done. + ACE_Condition_Thread_Mutex barrier_finished_; + + /// Number of threads that are still running. + int running_threads_; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + +/** + * @class ACE_Barrier + * + * @brief Implements "barrier synchronization". + * + * This class allows <count> number of threads to synchronize + * their completion of (one round of) a task, which is known as + * "barrier synchronization". After all the threads call <wait()> + * on the barrier they are all atomically released and can begin a new + * round. + * + * This implementation uses a "sub-barrier generation numbering" + * scheme to avoid overhead and to ensure that all threads wait to + * leave the barrier correct. This code is based on an article from + * SunOpsis Vol. 4, No. 1 by Richard Marejka + * (Richard.Marejka@canada.sun.com). + */ +class ACE_Export ACE_Barrier +{ +public: + /// Initialize the barrier to synchronize <count> threads. + ACE_Barrier (unsigned int count, + const ACE_TCHAR *name = 0, + void *arg = 0); + + /// Default dtor. + ~ACE_Barrier (void); + + /// Block the caller until all <count> threads have called <wait> and + /// then allow all the caller threads to continue in parallel. + int wait (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// Serialize access to the barrier state. + ACE_Thread_Mutex lock_; + + /// Either 0 or 1, depending on whether we are the first generation + /// of waiters or the next generation of waiters. + int current_generation_; + + /// Total number of threads that can be waiting at any one time. + int count_; + + /** + * We keep two <sub_barriers>, one for the first "generation" of + * waiters, and one for the next "generation" of waiters. This + * efficiently solves the problem of what to do if all the first + * generation waiters don't leave the barrier before one of the + * threads calls wait() again (i.e., starts up the next generation + * barrier). + */ + ACE_Sub_Barrier sub_barrier_1_; + ACE_Sub_Barrier sub_barrier_2_; + ACE_Sub_Barrier *sub_barrier_[2]; + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Barrier &); + ACE_Barrier (const ACE_Barrier &); +}; + +#if 0 +/** + * @class ACE_Process_Barrier + * + * @brief Implements "barrier synchronization" using ACE_Process_Mutexes! + * + * This class is just a simple wrapper for ACE_Barrier that + * selects the USYNC_PROCESS variant for the locks. + */ +class ACE_Export ACE_Process_Barrier : public ACE_Barrier +{ +public: + /// Create a Process_Barrier, passing in the optional <name>. + ACE_Process_Barrier (unsigned int count, const ACE_TCHAR *name = 0); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; +#endif /* 0 */ + +/** + * @class ACE_Thread_Barrier + * + * @brief Implements "barrier synchronization" using ACE_Thread_Mutexes! + * + * This class is just a simple wrapper for ACE_Barrier that + * selects the USYNC_THREAD variant for the locks. + */ +class ACE_Export ACE_Thread_Barrier : public ACE_Barrier +{ +public: + /// Create a Thread_Barrier, passing in the optional <name>. + ACE_Thread_Barrier (unsigned int count, const ACE_TCHAR *name = 0); + + /// Default dtor. + ~ACE_Thread_Barrier (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Barrier.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* !ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_BARRIER_H */ diff --git a/ace/Barrier.inl b/ace/Barrier.inl new file mode 100644 index 00000000000..bb7a483b3e3 --- /dev/null +++ b/ace/Barrier.inl @@ -0,0 +1,17 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_Sub_Barrier::~ACE_Sub_Barrier (void) +{ +} + +ACE_INLINE +ACE_Barrier::~ACE_Barrier (void) +{ +} + +ACE_INLINE +ACE_Thread_Barrier::~ACE_Thread_Barrier (void) +{ +} diff --git a/ace/Based_Pointer_Repository.cpp b/ace/Based_Pointer_Repository.cpp index d3b5193610a..6f428ad5b1a 100644 --- a/ace/Based_Pointer_Repository.cpp +++ b/ace/Based_Pointer_Repository.cpp @@ -2,6 +2,8 @@ #include "ace/Map_Manager.h" #include "ace/Based_Pointer_Repository.h" +#include "ace/Null_Mutex.h" +#include "ace/Synch_Traits.h" /** * @class ACE_Based_Pointer_Repository_Rep diff --git a/ace/Based_Pointer_Repository.h b/ace/Based_Pointer_Repository.h index b7075648ee0..1edfc1a6c7b 100644 --- a/ace/Based_Pointer_Repository.h +++ b/ace/Based_Pointer_Repository.h @@ -23,6 +23,7 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/os_include/os_stddef.h" +#include "ace/Synch_Traits.h" // Forward decl., using the "Cheshire Cat" technique. class ACE_Based_Pointer_Repository_Rep; diff --git a/ace/Bound_Ptr.i b/ace/Bound_Ptr.i index 92229126592..9c50cdac759 100644 --- a/ace/Bound_Ptr.i +++ b/ace/Bound_Ptr.i @@ -3,8 +3,6 @@ // Bound_Ptr.i -#include "Synch_T.h" - template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> * ACE_Bound_Ptr_Counter<ACE_LOCK>::internal_create (int init_obj_ref_count) { diff --git a/ace/Cached_Connect_Strategy_T.cpp b/ace/Cached_Connect_Strategy_T.cpp index 8b186910ad3..9bf25fefce7 100644 --- a/ace/Cached_Connect_Strategy_T.cpp +++ b/ace/Cached_Connect_Strategy_T.cpp @@ -11,7 +11,6 @@ #include "ace/ACE.h" #include "ace/Service_Repository.h" -#include "ace/Synch.h" #include "ace/Service_Types.h" #include "ace/Thread_Manager.h" #include "ace/WFMO_Reactor.h" diff --git a/ace/Cached_Connect_Strategy_T.h b/ace/Cached_Connect_Strategy_T.h index 83e77f7ba5b..8c051a240d2 100644 --- a/ace/Cached_Connect_Strategy_T.h +++ b/ace/Cached_Connect_Strategy_T.h @@ -26,7 +26,6 @@ #include "ace/Caching_Strategies_T.h" #include "ace/Functor_T.h" #include "ace/Pair_T.h" -#include "ace/Synch.h" // For linkers which cant grok long names... #define ACE_Cached_Connect_Strategy_Ex ACCSE diff --git a/ace/Capabilities.h b/ace/Capabilities.h index 8fdecc343bd..4e130ec1a4f 100644 --- a/ace/Capabilities.h +++ b/ace/Capabilities.h @@ -21,7 +21,7 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/Synch.h" +#include "ace/Null_Mutex.h" #include "ace/Hash_Map_Manager_T.h" #include "ace/Containers.h" #include "ace/SString.h" diff --git a/ace/Condition_Recursive_Thread_Mutex.cpp b/ace/Condition_Recursive_Thread_Mutex.cpp new file mode 100644 index 00000000000..8c6b6313733 --- /dev/null +++ b/ace/Condition_Recursive_Thread_Mutex.cpp @@ -0,0 +1,120 @@ +/* -*- C++ -*- */ +/** + * @file Condition_Recursive_Thread_Mutex.cpp + * + * $Id$ + * + * Originally in Synch.cpp + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ + +#if !defined (__ACE_INLINE__) +#include "ace/Condition_Recursive_Thread_Mutex.inl" +#endif /* __ACE_INLINE__ */ + +//ACE_TEMPLATE_METHOD_SPECIALIZATION +int +ACE_Condition<ACE_Recursive_Thread_Mutex>::remove (void) +{ + return ACE_OS::cond_destroy (&this->cond_); +} + +void +ACE_Condition<ACE_Recursive_Thread_Mutex>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Condition<MUTEX>::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + // No dump method for ACE_cond_t even in emulated mode. + // cond_.dump (); + this->mutex_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +//ACE_TEMPLATE_METHOD_SPECIALIZATION +ACE_Condition<ACE_Recursive_Thread_Mutex>::~ACE_Condition (void) +{ + this->remove (); +} + +//ACE_TEMPLATE_METHOD_SPECIALIZATION +ACE_Condition<ACE_Recursive_Thread_Mutex>::ACE_Condition (ACE_Recursive_Thread_Mutex &m) + : mutex_ (m) +{ + ACE_OS::cond_init (&this->cond_); +} + +//ACE_TEMPLATE_METHOD_SPECIALIZATION +int +ACE_Condition<ACE_Recursive_Thread_Mutex>::wait (const ACE_Time_Value *abstime) +{ + return this->wait (this->mutex_, abstime); +} + +//ACE_TEMPLATE_METHOD_SPECIALIZATION +int +ACE_Condition<ACE_Recursive_Thread_Mutex>::wait (ACE_Recursive_Thread_Mutex &mutex, + const ACE_Time_Value *abstime) +{ + ACE_recursive_mutex_state mutex_state_holder; + ACE_recursive_thread_mutex_t &recursive_mutex = mutex.mutex (); + + if (ACE_OS::recursive_mutex_cond_unlock (&recursive_mutex, + mutex_state_holder) == -1) + return -1; + + // We wait on the condition, specifying the nesting mutex. For platforms + // with ACE_HAS_RECURSIVE_MUTEXES, this is the recursive mutex itself, + // and is the same as recursive_mutex, above. The caller should have been + // holding the lock on entry to this method, and it is still held. + // For other platforms, this is the nesting mutex that guards the + // ACE_recursive_mutex_t internals, and recursive_mutex_cond_unlock() + // returned with the lock held, but waiters primed and waiting to be + // released. At cond_wait below, the mutex will be released. + // On return, it will be reacquired. + const int result = abstime == 0 + ? ACE_OS::cond_wait (&this->cond_, + &mutex.get_nesting_mutex ()) + : ACE_OS::cond_timedwait (&this->cond_, + &mutex.get_nesting_mutex (), + (ACE_Time_Value *) abstime); + // We are holding the mutex, whether the wait succeeded or failed. + // Stash errno (in case it failed) and then we need to reset the + // recursive mutex state to what it was on entry to this method. + // Resetting it may require a wait for another thread to release + // the ACE_recursive_thread_mutex_t if this is a platform without + // ACE_HAS_RECURSIVE_MUTEXES, and recursive_mutex_cond_relock() takes + // care of that. + { + ACE_Errno_Guard error (errno); + ACE_OS::recursive_mutex_cond_relock (&recursive_mutex, + mutex_state_holder); + } + + return result; +} + +//ACE_TEMPLATE_METHOD_SPECIALIZATION +int +ACE_Condition<ACE_Recursive_Thread_Mutex>::signal (void) +{ + return ACE_OS::cond_signal (&this->cond_); +} + +//ACE_TEMPLATE_METHOD_SPECIALIZATION +int +ACE_Condition<ACE_Recursive_Thread_Mutex>::broadcast (void) +{ + return ACE_OS::cond_broadcast (&this->cond_); +} + +//ACE_TEMPLATE_METHOD_SPECIALIZATION +ACE_Recursive_Thread_Mutex & +ACE_Condition<ACE_Recursive_Thread_Mutex>::mutex (void) +{ + return this->mutex_; +} diff --git a/ace/Condition_Recursive_Thread_Mutex.h b/ace/Condition_Recursive_Thread_Mutex.h new file mode 100644 index 00000000000..fdab4b1dc9b --- /dev/null +++ b/ace/Condition_Recursive_Thread_Mutex.h @@ -0,0 +1,116 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Condition_Recursive_Thread_Mutex.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_CONDITION_RECURSIVE_TRHEAD_MUTEX_H +#define ACE_CONDITION_RECURSIVE_THREAD_MUTEX_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_HAS_THREADS) +# include "ace/Null_Condition.h" +#else /* ACE_HAS_THREADS */ +#include "ace/Recursive_Thread_Mutex.h" + +template <class ACE_LOCK> +class ACE_Condition; + +ACE_TEMPLATE_SPECIALIZATION +/** + * @class ACE_Condition<ACE_Recursive_Thread_Mutex> + * + * @brief ACE_Condition template specialization written using + * @a ACE_Recursive_Thread_Mutex. This allows threads to block until + * shared data changes state using recursive mutexes. + */ +class ACE_Export ACE_Condition<ACE_Recursive_Thread_Mutex> +{ +public: + /// Initialize the condition variable with a recursive mutex. + ACE_Condition (ACE_Recursive_Thread_Mutex &m); + + /// Implicitly destroy the condition variable. + ~ACE_Condition (void); + + /** + * Explicitly destroy the condition variable. Note that only one + * thread should call this method since it doesn't protect against + * race conditions. + */ + int remove (void); + + /** + * Block on condition, or until absolute time-of-day has passed. If + * abstime == 0 use "blocking" <wait> semantics. Else, if <abstime> + * != 0 and the call times out before the condition is signaled + * <wait> returns -1 and sets errno to ETIME. + */ + int wait (const ACE_Time_Value *abstime = 0); + + /** + * Block on condition or until absolute time-of-day has passed. If + * abstime == 0 use "blocking" wait() semantics on the recursive @a mutex + * passed as a parameter (this is useful if you need to store the + * <Condition> in shared memory). Else, if <abstime> != 0 and the + * call times out before the condition is signaled <wait> returns -1 + * and sets errno to ETIME. + */ + int wait (ACE_Recursive_Thread_Mutex &mutex, + const ACE_Time_Value *abstime = 0); + + /// Signal one waiting thread. + int signal (void); + + /// Signal *all* waiting threads. + int broadcast (void); + + /// Returns a reference to the underlying mutex; + ACE_Recursive_Thread_Mutex &mutex (void); + + /// Dump the state of an object. + void dump (void) const; + +private: + /// A normal (i.e., non-recursive) condition variable. + ACE_cond_t cond_; + + /// Reference to the recursive mutex. + ACE_Recursive_Thread_Mutex &mutex_; + + // = Prevent assignment and initialization. + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Condition<ACE_Recursive_Thread_Mutex> &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Condition (const ACE_Condition<ACE_Recursive_Thread_Mutex> &)) +}; + +class ACE_Export ACE_Condition_Recursive_Thread_Mutex + : public ACE_Condition<ACE_Recursive_Thread_Mutex> +{ +public: + /// Initialize the condition variable with a recursive mutex. + ACE_Condition_Recursive_Thread_Mutex (ACE_Recursive_Thread_Mutex &m): + ACE_Condition<ACE_Recursive_Thread_Mutex> (m) {} +}; + +#if defined (__ACE_INLINE__) +#include "ace/Condition_Recursive_Thread_Mutex.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* !ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONDITION_RECURSIVE_THREAD_MUTEX_H */ diff --git a/ace/Condition_Recursive_Thread_Mutex.inl b/ace/Condition_Recursive_Thread_Mutex.inl new file mode 100644 index 00000000000..f4f84bd4f2e --- /dev/null +++ b/ace/Condition_Recursive_Thread_Mutex.inl @@ -0,0 +1,3 @@ +/* -*- C++ -*- */ +// $Id$ + diff --git a/ace/Condition_T.cpp b/ace/Condition_T.cpp new file mode 100644 index 00000000000..6cbabdb0536 --- /dev/null +++ b/ace/Condition_T.cpp @@ -0,0 +1,194 @@ +// $Id$ + +#ifndef ACE_CONDITION_T_C +#define ACE_CONDITION_T_C + +#include "ace/Condition_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_RCSID(ace, Condition_T, "$Id$") + +#if defined (ACE_HAS_THREADS) + +#if !defined (__ACE_INLINE__) +#include "ace/Condition_T.inl" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Condition) + +template <class MUTEX> void +ACE_Condition<MUTEX>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Condition<MUTEX>::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); +#if defined (CHORUS) + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("condname_ = %s\n"), this->condname_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("process_cond_ = %x\n"), + this->process_cond_)); +#endif /* CHORUS */ + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template <class MUTEX> +ACE_Thread_Condition<MUTEX>::ACE_Thread_Condition (MUTEX &m, + const ACE_TCHAR *name, + void *arg) + : ACE_Condition<MUTEX> (m, USYNC_THREAD, name, arg) +{ +// ACE_TRACE ("ACE_Thread_Condition<MUTEX>::ACE_Thread_Condition"); +} + +template <class MUTEX> void +ACE_Thread_Condition<MUTEX>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Thread_Condition<MUTEX>::dump"); + + ACE_Condition<MUTEX>::dump (); +#endif /* ACE_HAS_DUMP */ +} + +template <class MUTEX> +ACE_Condition<MUTEX>::ACE_Condition (MUTEX &m, + int type, + const ACE_TCHAR *name, + void *arg) + : +#if defined (CHORUS) + process_cond_(0), + condname_ (0), +#endif /* CHORUS */ + mutex_ (m) +{ + +#if defined(CHORUS) + if (type == USYNC_PROCESS) + { + // Let's see if the shared memory entity already exists. + ACE_HANDLE fd = ACE_OS::shm_open (name, + O_RDWR | O_CREAT | O_EXCL, + ACE_DEFAULT_FILE_PERMS); + if (fd == ACE_INVALID_HANDLE) + { + if (errno == EEXIST) + fd = ACE_OS::shm_open (name, + O_RDWR | O_CREAT, + ACE_DEFAULT_FILE_PERMS); + else + return; + } + else + { + // We own this shared memory object! Let's set its size. + if (ACE_OS::ftruncate (fd, + sizeof (ACE_mutex_t)) == -1) + { + ACE_OS::close (fd); + return; + } + this->condname_ = ACE_OS::strdup (name); + if (this->condname_ == 0) + { + ACE_OS::close (fd); + return; + } + } + + this->process_cond_ = + (ACE_cond_t *) ACE_OS::mmap (0, + sizeof (ACE_cond_t), + PROT_RDWR, + MAP_SHARED, + fd, + 0); + ACE_OS::close (fd); + if (this->process_cond_ == MAP_FAILED) + return; + + if (this->condname_ + && ACE_OS::cond_init (this->process_cond_, + type, + name, + arg) != 0) + return; + } + // It is ok to fall through into the <cond_init> below if the + // USYNC_PROCESS flag is not enabled. +#endif /* CHORUS */ + + // ACE_TRACE ("ACE_Condition<MUTEX>::ACE_Condition"); + + if (ACE_OS::cond_init (&this->cond_, + (short) type, + name, + arg) != 0) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("ACE_Condition::ACE_Condition"))); +} + +template <class MUTEX> +ACE_Condition<MUTEX>::~ACE_Condition (void) +{ + // ACE_TRACE ("ACE_Condition<MUTEX>::~ACE_Condition"); + + if (this->remove () == -1) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("ACE_Condition::~ACE_Condition"))); +} + +template <class MUTEX> int +ACE_Condition<MUTEX>::wait (void) +{ + // ACE_TRACE ("ACE_Condition<MUTEX>::wait"); +#if defined (CHORUS) + if (this->process_cond_ != 0) + return ACE_OS::cond_wait (this->process_cond_, + &this->mutex_.lock_); +#endif /* CHORUS */ + return ACE_OS::cond_wait (&this->cond_, + &this->mutex_.lock_); +} + +template <class MUTEX> int +ACE_Condition<MUTEX>::wait (MUTEX &mutex, + const ACE_Time_Value *abstime) +{ +// ACE_TRACE ("ACE_Condition<MUTEX>::wait"); + if (abstime == 0) + return this->wait (); + else + { +#if defined (CHORUS) + if (this->process_cond_ != 0) + return ACE_OS::cond_timedwait (this->process_cond_, + &mutex_.lock_, + (ACE_Time_Value *) abstime); +#endif /* CHORUS */ + return ACE_OS::cond_timedwait (&this->cond_, + &mutex.lock_, + (ACE_Time_Value *) abstime); + } +} + +// Peform an "alertable" timed wait. If the argument ABSTIME == 0 +// then we do a regular cond_wait(), else we do a timed wait for up to +// ABSTIME using the Solaris cond_timedwait() function. + +template <class MUTEX> int +ACE_Condition<MUTEX>::wait (const ACE_Time_Value *abstime) +{ +// ACE_TRACE ("ACE_Condition<MUTEX>::wait"); + return this->wait (this->mutex_, abstime); +} +#endif /* ACE_HAS_THREADS */ + +#endif /* ACE_CONDITION_T_C */ diff --git a/ace/Condition_T.h b/ace/Condition_T.h new file mode 100644 index 00000000000..a872575d4bd --- /dev/null +++ b/ace/Condition_T.h @@ -0,0 +1,171 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Condition_T.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_CONDITION_T_H +#define ACE_CONDITION_T_H +#include /**/ "ace/pre.h" + +#include "ace/Lock.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (ACE_HAS_THREADS) /* ACE platform supports some form of threading. */ + +/** + * @class ACE_Condition + * + * @brief ACE_Condition variable wrapper, which allows threads to block + * until shared data changes state. + * + * A condition variable enables threads to atomically block and + * test the condition under the protection of a mutual exclu- + * sion lock (mutex) until the condition is satisfied. That is, + * the mutex must have been held by the thread before calling + * wait or signal on the condition. If the condition is false, + * a thread blocks on a condition variable and atomically + * releases the mutex that is waiting for the condition to + * change. If another thread changes the condition, it may wake + * up waiting threads by signaling the associated condition + * variable. The waiting threads, upon awakening, reacquire the + * mutex and re-evaluate the condition. + * Note, you can only parameterize <ACE_Condition> with + * @a ACE_Thread_Mutex, @a ACE_Recursive_Thread_Mutex, or @a ACE_Null_Mutex. + */ +template <class MUTEX> +class ACE_Condition +{ +public: + // = Initialiation and termination methods. + /// Initialize the condition variable. + ACE_Condition (MUTEX &m, int type = USYNC_THREAD, + const ACE_TCHAR *name = 0, void *arg = 0); + + /// Implicitly destroy the condition variable. + ~ACE_Condition (void); + + // = Lock accessors. + /** + * Block on condition, or until absolute time-of-day has passed. If + * abstime == 0 use "blocking" <wait> semantics. Else, if <abstime> + * != 0 and the call times out before the condition is signaled + * <wait> returns -1 and sets errno to ETIME. + */ + int wait (const ACE_Time_Value *abstime); + + /// Block on condition. + int wait (void); + + /** + * Block on condition or until absolute time-of-day has passed. If + * abstime == 0 use "blocking" wait() semantics on the <mutex> + * passed as a parameter (this is useful if you need to store the + * <Condition> in shared memory). Else, if <abstime> != 0 and the + * call times out before the condition is signaled <wait> returns -1 + * and sets errno to ETIME. + */ + int wait (MUTEX &mutex, const ACE_Time_Value *abstime = 0); + + /// Signal one waiting thread. + int signal (void); + + /// Signal *all* waiting threads. + int broadcast (void); + + // = Utility methods. + /// Explicitly destroy the condition variable. + int remove (void); + + /// Returns a reference to the underlying mutex_; + MUTEX &mutex (void); + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: +#if defined (CHORUS) + /// This condition resides in shared memory. + ACE_cond_t *process_cond_; + + /** + * Remember the name of the condition if we created it so we can + * unlink it when we go away (only the actor that initialized the + * memory can destroy it). + */ + const ACE_TCHAR *condname_; +#endif /* CHORUS */ + + /// Condition variable. + ACE_cond_t cond_; + + /// Reference to mutex lock. + MUTEX &mutex_; + +private: + // = Prevent assignment and initialization. + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Condition<MUTEX> &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Condition (const ACE_Condition<MUTEX> &)) +}; + +/** + * @class ACE_Thread_Condition + * + * @brief ACE_Condition variable wrapper that works within processes. + * + * A condition variable enables threads to atomically block and + * test the condition under the protection of a mutual exclu- + * sion lock (mutex) until the condition is satisfied. That is, + * the mutex must have been held by the thread before calling + * wait or signal on the condition. If the condition is false, + * a thread blocks on a condition variable and atomically + * releases the mutex that is waiting for the condition to + * change. If another thread changes the condition, it may wake + * up waiting threads by signaling the associated condition + * variable. The waiting threads, upon awakening, reacquire the + * mutex and re-evaluate the condition. + */ +template <class MUTEX> +class ACE_Thread_Condition : public ACE_Condition<MUTEX> +{ +public: + // = Initialization method. + ACE_Thread_Condition (MUTEX &m, const ACE_TCHAR *name = 0, void *arg = 0); + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Condition_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Condition_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Condition_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONDITION_T_H */ diff --git a/ace/Condition_T.inl b/ace/Condition_T.inl new file mode 100644 index 00000000000..4e67ffdb1fc --- /dev/null +++ b/ace/Condition_T.inl @@ -0,0 +1,82 @@ +/* -*- C++ -*- */ +// $Id$ + +template<class MUTEX> ACE_INLINE int +ACE_Condition<MUTEX>::remove (void) +{ + // ACE_TRACE ("ACE_Condition<MUTEX>::remove"); + + // cond_destroy() is called in a loop if the condition variable is + // BUSY. This avoids a condition where a condition is signaled and + // because of some timing problem, the thread that is to be signaled + // has called the cond_wait routine after the signal call. Since + // the condition signal is not queued in any way, deadlock occurs. + + int result = 0; + +#if defined (CHORUS) + // Are we the owner? + if (this->process_cond_ && this->condname_) + { + // Only destroy the condition if we're the ones who initialized + // it. + while ((result = ACE_OS::cond_destroy (this->process_cond_)) == -1 + && errno == EBUSY) + { + ACE_OS::cond_broadcast (this->process_cond_); + ACE_OS::thr_yield (); + } + ACE_OS::munmap (this->process_cond_, + sizeof (ACE_cond_t)); + ACE_OS::shm_unlink (this->condname_); + ACE_OS::free (ACE_static_cast (void *, + ACE_const_cast (ACE_TCHAR *, + this->condname_))); + } + else if (this->process_cond_) + { + ACE_OS::munmap (this->process_cond_, + sizeof (ACE_cond_t)); + result = 0; + } + else +#endif /* CHORUS */ + + while ((result = ACE_OS::cond_destroy (&this->cond_)) == -1 + && errno == EBUSY) + { + ACE_OS::cond_broadcast (&this->cond_); + ACE_OS::thr_yield (); + } + + return result; +} + +template<class MUTEX> ACE_INLINE MUTEX & +ACE_Condition<MUTEX>::mutex (void) +{ + // ACE_TRACE ("ACE_Condition<MUTEX>::mutex"); + return this->mutex_; +} + +template <class MUTEX> ACE_INLINE int +ACE_Condition<MUTEX>::signal (void) +{ +// ACE_TRACE ("ACE_Condition<MUTEX>::signal"); +#if defined (CHORUS) + if (this->process_cond_ != 0) + return ACE_OS::cond_signal (this->process_cond_); +#endif /* CHORUS */ + return ACE_OS::cond_signal (&this->cond_); +} + +template <class MUTEX> ACE_INLINE int +ACE_Condition<MUTEX>::broadcast (void) +{ +// ACE_TRACE ("ACE_Condition<MUTEX>::broadcast"); +#if defined (CHORUS) + if (this->process_cond_ != 0) + return ACE_OS::cond_broadcast (this->process_cond_); +#endif /* CHORUS */ + return ACE_OS::cond_broadcast (&this->cond_); +} diff --git a/ace/Condition_Thread_Mutex.cpp b/ace/Condition_Thread_Mutex.cpp new file mode 100644 index 00000000000..1de140fa190 --- /dev/null +++ b/ace/Condition_Thread_Mutex.cpp @@ -0,0 +1,129 @@ +/* -*- C++ -*- */ +/** + * @file Condition_Thread_Mutex.cpp + * + * $Id$ + * + * Originally in Synch.cpp + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ + +#if !defined (__ACE_INLINE__) +#include "ace/Condition_Thread_Mutex.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Condition_Thread_Mutex, "$Id$") + +ACE_ALLOC_HOOK_DEFINE(ACE_Condition_Thread_Mutex) + +void +ACE_Condition_Thread_Mutex::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Condition_Thread_Mutex::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); +#if defined (ACE_WIN32) + ACE_DEBUG ((LM_DEBUG, + ACE_LIB_TEXT ("waiters = %d\n"), + this->cond_.waiters ())); +#endif /* ACE_WIN32 */ + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex (const ACE_Thread_Mutex &m, + const ACE_TCHAR *name, + void *arg) + : mutex_ ((ACE_Thread_Mutex &) m), + removed_ (0) +{ +#if defined (ACE_HAS_FSU_PTHREADS) +// Initialize FSU pthreads package. +// If called more than once, pthread_init does nothing +// and so does no harm. + pthread_init (); +#endif /* ACE_HAS_FSU_PTHREADS */ + +// ACE_TRACE ("ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex"); + if (ACE_OS::cond_init (&this->cond_, + (short) USYNC_THREAD, + name, + arg) != 0) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex"))); +} + +ACE_Condition_Thread_Mutex:: +ACE_Condition_Thread_Mutex (const ACE_Thread_Mutex &m, + ACE_Condition_Attributes &attributes, + const ACE_TCHAR *name, + void *arg) + : mutex_ ((ACE_Thread_Mutex &) m), + removed_ (0) +{ +#if defined (ACE_HAS_FSU_PTHREADS) +// Initialize FSU pthreads package. +// If called more than once, pthread_init does nothing +// and so does no harm. + pthread_init (); +#endif /* ACE_HAS_FSU_PTHREADS */ + +// ACE_TRACE ("ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex"); + if (ACE_OS::cond_init (&this->cond_, attributes.attributes_, + name, arg) != 0) + ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex"))); +} + +ACE_Condition_Thread_Mutex::~ACE_Condition_Thread_Mutex (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::~ACE_Condition_Thread_Mutex"); + this->remove (); +} + +// Peform an "alertable" timed wait. If the argument <abstime> == 0 +// then we do a regular <cond_wait>, else we do a timed wait for up to +// <abstime> using the <cond_timedwait> function. + +int +ACE_Condition_Thread_Mutex::wait (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::wait"); + return ACE_OS::cond_wait (&this->cond_, &this->mutex_.lock_); +} + +int +ACE_Condition_Thread_Mutex::wait (ACE_Thread_Mutex &mutex, + const ACE_Time_Value *abstime) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::wait"); + return ACE_OS::cond_timedwait (&this->cond_, + &mutex.lock_, + (ACE_Time_Value *) abstime); +} + +int +ACE_Condition_Thread_Mutex::wait (const ACE_Time_Value *abstime) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::wait"); + return this->wait (this->mutex_, abstime); +} + +int +ACE_Condition_Thread_Mutex::signal (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::signal"); + return ACE_OS::cond_signal (&this->cond_); +} + +int +ACE_Condition_Thread_Mutex::broadcast (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::broadcast"); + return ACE_OS::cond_broadcast (&this->cond_); +} + diff --git a/ace/Condition_Thread_Mutex.h b/ace/Condition_Thread_Mutex.h new file mode 100644 index 00000000000..8cf8aa6171b --- /dev/null +++ b/ace/Condition_Thread_Mutex.h @@ -0,0 +1,186 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Condition_Thread_Mutex.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_CONDITION_THREAD_MUTEX_H +#define ACE_CONDITION_THREAD_MUTEX_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_HAS_THREADS) +# include "ace/Null_Condition.h" +#else /* ACE_HAS_THREADS */ +// ACE platform supports some form of threading. + +#include "ace/Thread_Mutex.h" + +class ACE_Time_Value; + +class ACE_Export ACE_Condition_Attributes +{ +public: + /// Constructor + ACE_Condition_Attributes (int type = ACE_DEFAULT_SYNCH_TYPE); + + /// Destructor + ~ACE_Condition_Attributes (void); + +private: + friend class ACE_Condition_Thread_Mutex; + + /// The attributes + ACE_condattr_t attributes_; + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Condition_Attributes &); + ACE_Condition_Attributes (const ACE_Condition_Attributes &); +}; + +/** + * @class ACE_Condition_Thread_Mutex + * + * @brief ACE_Condition variable wrapper written using ACE_Mutexes This + * allows threads to block until shared data changes state. + * A condition variable enables threads to atomically block and + * test the condition under the protection of a mutual exclu- + * sion lock (mutex) until the condition is satisfied. That is, + * the mutex must have been held by the thread before calling + * wait or signal on the condition. If the condition is false, + * a thread blocks on a condition variable and atomically + * releases the mutex that is waiting for the condition to + * change. If another thread changes the condition, it may wake + * up waiting threads by signaling the associated condition + * variable. The waiting threads, upon awakening, reacquire the + * mutex and re-evaluate the condition. + * + * This should be an instantiation of ACE_Condition but problems + * with compilers precludes this... + */ +class ACE_Export ACE_Condition_Thread_Mutex +{ +public: + /// Initialize the condition variable. + ACE_Condition_Thread_Mutex (const ACE_Thread_Mutex &m, + const ACE_TCHAR *name = 0, + void *arg = 0); + + /// Initialize the condition variable. + ACE_Condition_Thread_Mutex (const ACE_Thread_Mutex &m, + ACE_Condition_Attributes &attributes, + const ACE_TCHAR *name = 0, + void *arg = 0); + + /// Implicitly destroy the condition variable. + ~ACE_Condition_Thread_Mutex (void); + + /** + * Explicitly destroy the condition variable. Note that only one + * thread should call this method since it doesn't protect against + * race conditions. + */ + int remove (void); + + /** + * Block on condition, or until absolute time-of-day has passed. If + * abstime == 0 use "blocking" <wait> semantics. Else, if <abstime> + * != 0 and the call times out before the condition is signaled + * <wait> returns -1 and sets errno to ETIME. + */ + int wait (const ACE_Time_Value *abstime); + + /// Block on condition. + int wait (void); + + /** + * Block on condition or until absolute time-of-day has passed. If + * abstime == 0 use "blocking" wait() semantics on the <mutex> + * passed as a parameter (this is useful if you need to store the + * <Condition> in shared memory). Else, if <abstime> != 0 and the + * call times out before the condition is signaled <wait> returns -1 + * and sets errno to ETIME. + */ + int wait (ACE_Thread_Mutex &mutex, const ACE_Time_Value *abstime = 0); + + /// Signal one waiting thread. + int signal (void); + + /// Signal *all* waiting threads. + int broadcast (void); + + /// Returns a reference to the underlying mutex; + ACE_Thread_Mutex &mutex (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// Condition variable. + ACE_cond_t cond_; + + /// Reference to mutex lock. + ACE_Thread_Mutex &mutex_; + + /// Keeps track of whether <remove> has been called yet to avoid + /// multiple <remove> calls, e.g., explicitly and implicitly in the + /// destructor. This flag isn't protected by a lock, so make sure + /// that you don't have multiple threads simultaneously calling + /// <remove> on the same object, which is a bad idea anyway... + int removed_; + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Condition_Thread_Mutex &); + ACE_Condition_Thread_Mutex (const ACE_Condition_Thread_Mutex &); +}; + +#if 0 +// The following two classes are commented out since there doesn't +// appear to be a portable and robust means of implementing this +// functionality across platforms. If you know of a portable and +// robust way to implement this functionality please let us know. + +/** + * @class ACE_Process_Condition + * + * @brief ACE_Condition variable wrapper that works across processes. + */ +class ACE_Export ACE_Process_Condition +{ +public: + ACE_Process_Condition (MUTEX &m, const ACE_TCHAR *name = 0, void *arg = 0); + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; +#endif /* 0 */ + +#if defined (__ACE_INLINE__) +#include "ace/Condition_Thread_Mutex.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* !ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_CONDITION_THREAD_MUTEX_H */ diff --git a/ace/Condition_Thread_Mutex.inl b/ace/Condition_Thread_Mutex.inl new file mode 100644 index 00000000000..ff15f94ad04 --- /dev/null +++ b/ace/Condition_Thread_Mutex.inl @@ -0,0 +1,69 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_Condition_Attributes::ACE_Condition_Attributes (int type) +{ + (void) ACE_OS::condattr_init (this->attributes_, type); +} + +ACE_INLINE +ACE_Condition_Attributes::~ACE_Condition_Attributes (void) +{ + ACE_OS::condattr_destroy (this->attributes_); +} + +ACE_INLINE int +ACE_Condition_Thread_Mutex::remove (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::remove"); + + // <cond_destroy> is called in a loop if the condition variable is + // BUSY. This avoids a condition where a condition is signaled and + // because of some timing problem, the thread that is to be signaled + // has called the cond_wait routine after the signal call. Since + // the condition signal is not queued in any way, deadlock occurs. + + int result = 0; + + if (this->removed_ == 0) + { + this->removed_ = 1; + + while ((result = ACE_OS::cond_destroy (&this->cond_)) == -1 + && errno == EBUSY) + { + ACE_OS::cond_broadcast (&this->cond_); + ACE_OS::thr_yield (); + } + } + return result; +} + +ACE_INLINE ACE_Thread_Mutex & +ACE_Condition_Thread_Mutex::mutex (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::mutex"); + return this->mutex_; +} + +#if 0 +template <class MUTEX> void +ACE_Process_Condition<MUTEX>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Process_Condition<MUTEX>::dump"); + + ACE_Condition<MUTEX>::dump (); +#endif /* ACE_HAS_DUMP */ +} + +template <class MUTEX> +ACE_Process_Condition<MUTEX>::ACE_Process_Condition (MUTEX &m, + const ACE_TCHAR *name, + void *arg) + : ACE_Condition<MUTEX> (m, USYNC_PROCESS, name, arg) +{ +// ACE_TRACE ("ACE_Process_Condition<MUTEX>::ACE_Process_Condition"); +} +#endif /* 0 */ diff --git a/ace/Configuration.h b/ace/Configuration.h index 7815814055d..65c503b8e10 100644 --- a/ace/Configuration.h +++ b/ace/Configuration.h @@ -34,6 +34,7 @@ #include "ace/SString.h" #include "ace/Hash_Map_With_Allocator_T.h" #include "ace/Malloc.h" +#include "ace/Synch_Traits.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/ace/Containers_T.cpp b/ace/Containers_T.cpp index a0178e1d7ea..a5b7ed95493 100644 --- a/ace/Containers_T.cpp +++ b/ace/Containers_T.cpp @@ -5,6 +5,7 @@ #include "ace/Log_Msg.h" #include "ace/Malloc_Base.h" +#include "ace/OS_Memory.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/ace/DLL_Manager.cpp b/ace/DLL_Manager.cpp index 3a180ad2f2a..c2e491f73ac 100644 --- a/ace/DLL_Manager.cpp +++ b/ace/DLL_Manager.cpp @@ -11,6 +11,7 @@ #include "ace/Lib_Find.h" #include "ace/Object_Manager.h" #include "ace/SString.h" +#include "ace/Recursive_Thread_Mutex.h" ACE_RCSID(ace, DLL, "$Id$") diff --git a/ace/DLL_Manager.h b/ace/DLL_Manager.h index 9fda0afacde..1c2adb06e86 100644 --- a/ace/DLL_Manager.h +++ b/ace/DLL_Manager.h @@ -15,7 +15,7 @@ #define ACE_DLL_MANAGER_H #include /**/ "ace/pre.h" -#include "ace/Synch_T.h" +#include "ace/ACE_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -24,6 +24,10 @@ #include "ace/Auto_Ptr.h" #include "ace/SStringfwd.h" +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) +# include "ace/Thread_Mutex.h" +#endif /* ACE_MT_SAFE */ + #define ACE_DEFAULT_DLL_MANAGER_SIZE 1024 /** diff --git a/ace/Dump.cpp b/ace/Dump.cpp index 52786c00d99..e0f98640593 100644 --- a/ace/Dump.cpp +++ b/ace/Dump.cpp @@ -1,7 +1,8 @@ // $Id$ -#include "ace/Synch_T.h" #include "ace/Dump.h" +#include "ace/Guard_T.h" +#include "ace/Thread_Mutex.h" #include "ace/Object_Manager.h" #include "ace/Log_Msg.h" diff --git a/ace/Dump.h b/ace/Dump.h index 816f556bc9d..aff3faab9a9 100644 --- a/ace/Dump.h +++ b/ace/Dump.h @@ -52,7 +52,7 @@ #define ACE_DUMP_H #include /**/ "ace/pre.h" -#include "ace/Synch.h" +#include "ace/ACE_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/ace/Dynamic.cpp b/ace/Dynamic.cpp index 4042cd56402..14fa9ec538e 100644 --- a/ace/Dynamic.cpp +++ b/ace/Dynamic.cpp @@ -3,7 +3,9 @@ #include "ace/Dynamic.h" #include "ace/Singleton.h" -#include "ace/Synch_T.h" +#include "ace/TSS_T.h" +#include "ace/Synch_Traits.h" +#include "ace/Null_Mutex.h" #if !defined (__ACE_INLINE__) #include "ace/Dynamic.i" diff --git a/ace/Event.cpp b/ace/Event.cpp new file mode 100644 index 00000000000..e57dd554c14 --- /dev/null +++ b/ace/Event.cpp @@ -0,0 +1,83 @@ +// $Id$ + +#if !defined (__ACE_INLINE__) +#include "ace/Event.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Event, "$Id$") + +ACE_Event::ACE_Event (int manual_reset, + int initial_state, + int type, + const ACE_TCHAR *name, + void *arg) + : removed_ (0) +{ + if (ACE_OS::event_init (&this->handle_, + manual_reset, + initial_state, + type, + name, + arg) != 0) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("ACE_Event::ACE_Event"))); +} + +ACE_Event::~ACE_Event (void) +{ + this->remove (); +} + +int +ACE_Event::remove (void) +{ + int result = 0; + if (this->removed_ == 0) + { + this->removed_ = 1; + result = ACE_OS::event_destroy (&this->handle_); + } + return result; +} + +int +ACE_Event::wait (void) +{ + return ACE_OS::event_wait (&this->handle_); +} + +int +ACE_Event::wait (const ACE_Time_Value *abstime, int use_absolute_time) +{ + return ACE_OS::event_timedwait (&this->handle_, + (ACE_Time_Value *) abstime, + use_absolute_time); +} + +int +ACE_Event::signal (void) +{ + return ACE_OS::event_signal (&this->handle_); +} + +int +ACE_Event::pulse (void) +{ + return ACE_OS::event_pulse (&this->handle_); +} + +int +ACE_Event::reset (void) +{ + return ACE_OS::event_reset (&this->handle_); +} + +void +ACE_Event::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} diff --git a/ace/Event.h b/ace/Event.h new file mode 100644 index 00000000000..7d9326a4be9 --- /dev/null +++ b/ace/Event.h @@ -0,0 +1,138 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Event.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_EVENT_H +#define ACE_EVENT_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/OS.h" + +/** + * @class ACE_Event + * + * @brief A wrapper around the Win32 event locking mechanism. + * + * Portable implementation of an Event mechanism, which is native to + * Win32, but must be emulated on UNIX. All platforms support + * process-scope locking support. However, only Win32 platforms + * support global naming and system-scope locking support. + */ +class ACE_Export ACE_Event +{ +public: + /// Constructor that creates event. + ACE_Event (int manual_reset = 0, + int initial_state = 0, + int type = USYNC_THREAD, + const ACE_TCHAR *name = 0, + void *arg = 0); + + /// Implicitly destroy the event variable. + ~ACE_Event (void); + + /** + * Explicitly destroy the event variable. Note that only one thread + * should call this method since it doesn't protect against race + * conditions. + */ + int remove (void); + + /// Underlying handle to event. + ACE_event_t handle (void) const; + + /** + * Set the underlying handle to event. Note that this method assumes + * ownership of the <handle> and will close it down in <remove>. If + * you want the <handle> to stay open when <remove> is called make + * sure to call <dup> on the <handle> before closing it. You are + * responsible for the closing the existing <handle> before + * overwriting it. + */ + void handle (ACE_event_t new_handle); + + /** + * if MANUAL reset + * sleep till the event becomes signaled + * event remains signaled after wait() completes. + * else AUTO reset + * sleep till the event becomes signaled + * event resets wait() completes. + */ + int wait (void); + + /// Same as wait() above, but this one can be timed + /// <abstime> is absolute time-of-day if if <use_absolute_time> + /// is non-0, else it is relative time. + int wait (const ACE_Time_Value *abstime, + int use_absolute_time = 1); + + /** + * if MANUAL reset + * wake up all waiting threads + * set to signaled state + * else AUTO reset + * if no thread is waiting, set to signaled state + * if thread(s) are waiting, wake up one waiting thread and + * reset event + */ + int signal (void); + + /** + * if MANUAL reset + * wakeup all waiting threads and + * reset event + * else AUTO reset + * wakeup one waiting thread (if present) and + * reset event + */ + int pulse (void); + + /// Set to nonsignaled state. + int reset (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// The underlying handle. + ACE_event_t handle_; + + /// Keeps track of whether <remove> has been called yet to avoid + /// multiple <remove> calls, e.g., explicitly and implicitly in the + /// destructor. This flag isn't protected by a lock, so make sure + /// that you don't have multiple threads simultaneously calling + /// <remove> on the same object, which is a bad idea anyway... + int removed_; + +private: + // = Prevent copying. + ACE_Event (const ACE_Event& event); + const ACE_Event &operator= (const ACE_Event &rhs); +}; + +#if defined (__ACE_INLINE__) +#include "ace/Event.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_EVENT_H */ diff --git a/ace/Event.inl b/ace/Event.inl new file mode 100644 index 00000000000..fdb9b491650 --- /dev/null +++ b/ace/Event.inl @@ -0,0 +1,15 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE ACE_event_t +ACE_Event::handle (void) const +{ + return this->handle_; +} + +ACE_INLINE void +ACE_Event::handle (ACE_event_t new_handle) +{ + this->handle_ = new_handle; +} + diff --git a/ace/Event_Handler.h b/ace/Event_Handler.h index a2397179601..669d923d5e2 100644 --- a/ace/Event_Handler.h +++ b/ace/Event_Handler.h @@ -20,11 +20,9 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -// need to fix THR_DETACHED, then we can get rid of OS.h -#include "ace/OS.h" #include "ace/os_include/os_signal.h" -#include "ace/os_include/os_pthread.h" #include "ace/Atomic_Op.h" +#include "ace/Synch_Traits.h" // Forward declaration. class ACE_Message_Block; diff --git a/ace/Filecache.h b/ace/Filecache.h index 0b11f279eb0..9a6702356fc 100644 --- a/ace/Filecache.h +++ b/ace/Filecache.h @@ -22,9 +22,11 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/Synch_T.h" #include "ace/Hash_Map_Manager_T.h" #include "ace/SString.h" +#include "ace/Null_Mutex.h" +#include "ace/Synch_Traits.h" +#include "ace/RW_Thread_Mutex.h" enum ACE_Filecache_Flag { diff --git a/ace/Framework_Component.cpp b/ace/Framework_Component.cpp index c668f9c26bd..e5786d341f9 100644 --- a/ace/Framework_Component.cpp +++ b/ace/Framework_Component.cpp @@ -10,6 +10,7 @@ #include "ace/Object_Manager.h" #include "ace/Log_Msg.h" #include "ace/DLL_Manager.h" +#include "ace/Recursive_Thread_Mutex.h" ACE_RCSID(ace, Framework_Component, "$Id$") diff --git a/ace/Framework_Component.h b/ace/Framework_Component.h index cc17e75ac7f..318867773ba 100644 --- a/ace/Framework_Component.h +++ b/ace/Framework_Component.h @@ -36,12 +36,15 @@ #define ACE_FRAMEWORK_COMPONENT_H #include /**/ "ace/pre.h" -#include "ace/Synch.h" +#include "ace/ACE_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ +#include "ace/os_include/os_signal.h" +#include "ace/Thread_Mutex.h" + #define ACE_DEFAULT_FRAMEWORK_REPOSITORY_SIZE 1024 /** diff --git a/ace/Framework_Component.inl b/ace/Framework_Component.inl index 30a30168ac7..2d3662642bd 100644 --- a/ace/Framework_Component.inl +++ b/ace/Framework_Component.inl @@ -4,6 +4,7 @@ // Framework_Component.inl #include "ace/ACE.h" +#include "ace/Guard_T.h" ACE_INLINE ACE_Framework_Component::ACE_Framework_Component (void *_this, diff --git a/ace/Free_List.h b/ace/Free_List.h index 668659d5a31..46a6a6eb247 100644 --- a/ace/Free_List.h +++ b/ace/Free_List.h @@ -20,7 +20,8 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/Synch_T.h" +#include "ace/Global_Macros.h" +#include "ace/Default_Constants.h" /** * @class ACE_Free_List diff --git a/ace/Free_List.i b/ace/Free_List.i index 7875592c8a9..c5668dfd0bc 100644 --- a/ace/Free_List.i +++ b/ace/Free_List.i @@ -1,6 +1,7 @@ /* -*- C++ -*- */ // $Id$ +#include "ace/Guard_T.h" // Inserts an element onto the free list (if we are allowed to manage // elements withing and it pasts the high water mark, delete the diff --git a/ace/Future.h b/ace/Future.h index fd848116663..572a667ad9d 100644 --- a/ace/Future.h +++ b/ace/Future.h @@ -18,7 +18,6 @@ #include /**/ "ace/pre.h" #include "ace/Unbounded_Set.h" -#include "ace/Synch.h" #include "ace/Strategies_T.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) diff --git a/ace/Guard_T.cpp b/ace/Guard_T.cpp new file mode 100644 index 00000000000..2aa67ed5d81 --- /dev/null +++ b/ace/Guard_T.cpp @@ -0,0 +1,54 @@ +// $Id$ + +#ifndef ACE_GUARD_T_C +#define ACE_GUARD_T_C + +#include "ace/Guard_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_RCSID(ace, Guard_T, "$Id$") + +#if !defined (__ACE_INLINE__) +#include "ace/Guard_T.inl" +#endif /* __ACE_INLINE__ */ + +// **************************************************************** +// ACE_ALLOC_HOOK_DEFINE(ACE_Guard) + +template <class ACE_LOCK> void +ACE_Guard<ACE_LOCK>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Guard<ACE_LOCK>::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("mutex_ = %x\n"), this->lock_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("owner_ = %d\n"), this->owner_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +// ACE_ALLOC_HOOK_DEFINE(ACE_Write_Guard) + +template <class ACE_LOCK> void +ACE_Write_Guard<ACE_LOCK>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Write_Guard<ACE_LOCK>::dump"); + ACE_Guard<ACE_LOCK>::dump (); +#endif /* ACE_HAS_DUMP */ +} + +// ACE_ALLOC_HOOK_DEFINE(ACE_Read_Guard) + +template <class ACE_LOCK> void +ACE_Read_Guard<ACE_LOCK>::dump (void) const +{ +// ACE_TRACE ("ACE_Read_Guard<ACE_LOCK>::dump"); + ACE_Guard<ACE_LOCK>::dump (); +} + +#endif /* ACE_GUARD_T_C */ diff --git a/ace/Guard_T.h b/ace/Guard_T.h new file mode 100644 index 00000000000..1638e7c6071 --- /dev/null +++ b/ace/Guard_T.h @@ -0,0 +1,360 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Guard_T.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_GUARD_T_H +#define ACE_GUARD_T_H +#include /**/ "ace/pre.h" + +#include "ace/Lock.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Global_Macros.h" +#include "ace/OS.h" // for ACE_thread_key_t + +/** + * @class ACE_Guard + * + * @brief This data structure is meant to be used within a method or + * function... It performs automatic aquisition and release of + * a parameterized synchronization object <ACE_LOCK>. + * + * The <ACE_LOCK> class given as an actual parameter must provide at + * the very least the <acquire>, <tryacquire>, <release>, and + * <remove> methods. + */ +template <class ACE_LOCK> +class ACE_Guard +{ +public: + + // = Initialization and termination methods. + ACE_Guard (ACE_LOCK &l); + + /// Implicitly and automatically acquire (or try to acquire) the + /// lock. If <block> is non-0 then <acquire> the <ACE_LOCK>, else + /// <tryacquire> it. + ACE_Guard (ACE_LOCK &l, int block); + + /// Initialise the guard without implicitly acquiring the lock. The + /// <become_owner> parameter indicates whether the guard should release + /// the lock implicitly on destruction. The <block> parameter is + /// ignored and is used here to disambiguate with the preceding + /// constructor. + ACE_Guard (ACE_LOCK &l, int block, int become_owner); + + /// Implicitly release the lock. + ~ACE_Guard (void); + + // = Lock accessors. + + /// Explicitly acquire the lock. + int acquire (void); + + /// Conditionally acquire the lock (i.e., won't block). + int tryacquire (void); + + /// Explicitly release the lock, but only if it is held! + int release (void); + + /// Relinquish ownership of the lock so that it is not released + /// implicitly in the destructor. + void disown (void); + + // = Utility methods. + /// 1 if locked, 0 if couldn't acquire the lock + /// (errno will contain the reason for this). + int locked (void) const; + + /// Explicitly remove the lock. + int remove (void); + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + + /// Helper, meant for subclass only. + ACE_Guard (ACE_LOCK *lock): lock_ (lock) {} + + /// Pointer to the ACE_LOCK we're guarding. + ACE_LOCK *lock_; + + /// Keeps track of whether we acquired the lock or failed. + int owner_; + +private: + // = Prevent assignment and initialization. + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Guard<ACE_LOCK> &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Guard (const ACE_Guard<ACE_LOCK> &)) +}; + +/** + * @class ACE_Write_Guard + * + * @brief This class is similar to class <ACE_Guard>, though it + * acquires/releases a write lock automatically (naturally, the + * <ACE_LOCK> it is instantiated with must support the appropriate + * API). + */ +template <class ACE_LOCK> +class ACE_Write_Guard : public ACE_Guard<ACE_LOCK> +{ +public: + // = Initialization method. + + /// Implicitly and automatically acquire a write lock. + ACE_Write_Guard (ACE_LOCK &m); + + /// Implicitly and automatically acquire (or try to acquire) a write + /// lock. + ACE_Write_Guard (ACE_LOCK &m, int block); + + // = Lock accessors. + + /// Explicitly acquire the write lock. + int acquire_write (void); + + /// Explicitly acquire the write lock. + int acquire (void); + + /// Conditionally acquire the write lock (i.e., won't block). + int tryacquire_write (void); + + /// Conditionally acquire the write lock (i.e., won't block). + int tryacquire (void); + + // = Utility methods. + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +/** + * @class ACE_Read_Guard + * + * @brief This class is similar to class <ACE_Guard>, though it + * acquires/releases a read lock automatically (naturally, the + * <ACE_LOCK> it is instantiated with must support the appropriate + * API). + */ +template <class ACE_LOCK> +class ACE_Read_Guard : public ACE_Guard<ACE_LOCK> +{ +public: + // = Initialization methods. + + /// Implicitly and automatically acquire a read lock. + ACE_Read_Guard (ACE_LOCK& m); + + /// Implicitly and automatically acquire (or try to acquire) a read + /// lock. + ACE_Read_Guard (ACE_LOCK &m, int block); + + // = Lock accessors. + + /// Explicitly acquire the read lock. + int acquire_read (void); + + /// Explicitly acquire the read lock. + int acquire (void); + + /// Conditionally acquire the read lock (i.e., won't block). + int tryacquire_read (void); + + /// Conditionally acquire the read lock (i.e., won't block). + int tryacquire (void); + + // = Utility methods. + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#if !(defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) + +#define ACE_TSS_Guard ACE_Guard +#define ACE_TSS_Write_GUARD ACE_Write_Guard +#define ACE_TSS_Read_GUARD ACE_Read_Guard + +#else + /* ACE platform supports some form of threading and + thread-specific storage. */ + +/** + * @class ACE_TSS_Guard + * + * @brief This data structure is meant to be used within a method or + * function... It performs automatic aquisition and release of + * a synchronization object. Moreover, it ensures that the lock + * is released even if a thread exits via <thr_exit>! + */ +template <class ACE_LOCK> +class ACE_TSS_Guard +{ +public: + // = Initialization and termination methods. + + /// Implicitly and automatically acquire the thread-specific lock. + ACE_TSS_Guard (ACE_LOCK &lock, int block = 1); + + /// Implicitly release the thread-specific lock. + ~ACE_TSS_Guard (void); + + // = Lock accessors. + + /// Explicitly acquire the thread-specific lock. + int acquire (void); + + /// Conditionally acquire the thread-specific lock (i.e., won't + /// block). + int tryacquire (void); + + /// Explicitly release the thread-specific lock. + int release (void); + + // = Utility methods. + /// Explicitly release the thread-specific lock. + int remove (void); + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + /// Helper, meant for subclass only. + ACE_TSS_Guard (void); + + /// Initialize the key. + void init_key (void); + + /// Called when thread exits to clean up the lock. + static void cleanup (void *ptr); + + /// Thread-specific key... + ACE_thread_key_t key_; + +private: + // = Prevent assignment and initialization. + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_TSS_Guard<ACE_LOCK> &)) + ACE_UNIMPLEMENTED_FUNC (ACE_TSS_Guard (const ACE_TSS_Guard<ACE_LOCK> &)) +}; + +/** + * @class ACE_TSS_Write_Guard + * + * @brief This class is similar to class ACE_TSS_Guard, though it + * acquires/releases a write-lock automatically (naturally, the + * ACE_LOCK it is instantiated with must support the appropriate + * API). + */ +template <class ACE_LOCK> +class ACE_TSS_Write_Guard : public ACE_TSS_Guard<ACE_LOCK> +{ +public: + // = Initialization method. + + /// Implicitly and automatically acquire the thread-specific write lock. + ACE_TSS_Write_Guard (ACE_LOCK &lock, int block = 1); + + // = Lock accessors. + + /// Explicitly acquire the thread-specific write lock. + int acquire_write (void); + + /// Explicitly acquire the thread-specific write lock. + int acquire (void); + + /// Conditionally acquire the thread-specific write lock (i.e., won't block). + int tryacquire_write (void); + + /// Conditionally acquire the thread-specific write lock (i.e., won't block). + int tryacquire (void); + + // = Utility methods. + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +/** + * @class ACE_TSS_Read_Guard + * + * @brief This class is similar to class <ACE_TSS_Guard>, though it + * acquires/releases a read lock automatically (naturally, the + * <ACE_LOCK> it is instantiated with must support the + * appropriate API). + */ +template <class ACE_LOCK> +class ACE_TSS_Read_Guard : public ACE_TSS_Guard<ACE_LOCK> +{ +public: + // = Initialization method. + /// Implicitly and automatically acquire the thread-specific read lock. + ACE_TSS_Read_Guard (ACE_LOCK &lock, int block = 1); + + // = Lock accessors. + /// Explicitly acquire the thread-specific read lock. + int acquire_read (void); + + /// Explicitly acquire the thread-specific read lock. + int acquire (void); + + /// Conditionally acquire the thread-specific read lock (i.e., won't + /// block). + int tryacquire_read (void); + + /// Conditionally acquire the thread-specific read lock (i.e., won't + /// block). + int tryacquire (void); + + // = Utility methods. + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; +#endif /* !(defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) */ + +#if defined (__ACE_INLINE__) +#include "ace/Guard_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Guard_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Guard_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_GUARD_T_H */ diff --git a/ace/Guard_T.inl b/ace/Guard_T.inl new file mode 100644 index 00000000000..d80d7e26e65 --- /dev/null +++ b/ace/Guard_T.inl @@ -0,0 +1,164 @@ +/* -*- C++ -*- */ +// $Id$ + +template <class ACE_LOCK> ACE_INLINE int +ACE_Guard<ACE_LOCK>::acquire (void) +{ + return this->owner_ = this->lock_->acquire (); +} + +template <class ACE_LOCK> ACE_INLINE int +ACE_Guard<ACE_LOCK>::tryacquire (void) +{ + return this->owner_ = this->lock_->tryacquire (); +} + +template <class ACE_LOCK> ACE_INLINE int +ACE_Guard<ACE_LOCK>::release (void) +{ + if (this->owner_ == -1) + return -1; + else + { + this->owner_ = -1; + return this->lock_->release (); + } +} + +template <class ACE_LOCK> ACE_INLINE +ACE_Guard<ACE_LOCK>::ACE_Guard (ACE_LOCK &l) + : lock_ (&l), + owner_ (0) +{ + this->acquire (); +} + +template <class ACE_LOCK> ACE_INLINE +ACE_Guard<ACE_LOCK>::ACE_Guard (ACE_LOCK &l, int block) + : lock_ (&l), + owner_ (0) +{ + if (block) + this->acquire (); + else + this->tryacquire (); +} + +template <class ACE_LOCK> ACE_INLINE +ACE_Guard<ACE_LOCK>::ACE_Guard (ACE_LOCK &l, int block, int become_owner) + : lock_ (&l), + owner_ (become_owner == 0 ? -1 : 0) +{ + ACE_UNUSED_ARG (block); +} + +// Implicitly and automatically acquire (or try to acquire) the +// lock. + +template <class ACE_LOCK> ACE_INLINE +ACE_Guard<ACE_LOCK>::~ACE_Guard (void) +{ + this->release (); +} + +template <class ACE_LOCK> ACE_INLINE int +ACE_Guard<ACE_LOCK>::locked (void) const +{ + return this->owner_ != -1; +} + +template <class ACE_LOCK> ACE_INLINE int +ACE_Guard<ACE_LOCK>::remove (void) +{ + return this->lock_->remove (); +} + +template <class ACE_LOCK> ACE_INLINE void +ACE_Guard<ACE_LOCK>::disown (void) +{ + this->owner_ = -1; +} + +template <class ACE_LOCK> ACE_INLINE +ACE_Write_Guard<ACE_LOCK>::ACE_Write_Guard (ACE_LOCK &m) + : ACE_Guard<ACE_LOCK> (&m) +{ + this->acquire_write (); +} + +template <class ACE_LOCK> ACE_INLINE int +ACE_Write_Guard<ACE_LOCK>::acquire_write (void) +{ + return this->owner_ = this->lock_->acquire_write (); +} + +template <class ACE_LOCK> ACE_INLINE int +ACE_Write_Guard<ACE_LOCK>::acquire (void) +{ + return this->owner_ = this->lock_->acquire_write (); +} + +template <class ACE_LOCK> ACE_INLINE int +ACE_Write_Guard<ACE_LOCK>::tryacquire_write (void) +{ + return this->owner_ = this->lock_->tryacquire_write (); +} + +template <class ACE_LOCK> ACE_INLINE int +ACE_Write_Guard<ACE_LOCK>::tryacquire (void) +{ + return this->owner_ = this->lock_->tryacquire_write (); +} + +template <class ACE_LOCK> ACE_INLINE +ACE_Write_Guard<ACE_LOCK>::ACE_Write_Guard (ACE_LOCK &m, + int block) + : ACE_Guard<ACE_LOCK> (&m) +{ + if (block) + this->acquire_write (); + else + this->tryacquire_write (); +} + +template <class ACE_LOCK> ACE_INLINE int +ACE_Read_Guard<ACE_LOCK>::acquire_read (void) +{ + return this->owner_ = this->lock_->acquire_read (); +} + +template <class ACE_LOCK> ACE_INLINE int +ACE_Read_Guard<ACE_LOCK>::acquire (void) +{ + return this->owner_ = this->lock_->acquire_read (); +} + +template <class ACE_LOCK> ACE_INLINE int +ACE_Read_Guard<ACE_LOCK>::tryacquire_read (void) +{ + return this->owner_ = this->lock_->tryacquire_read (); +} + +template <class ACE_LOCK> ACE_INLINE int +ACE_Read_Guard<ACE_LOCK>::tryacquire (void) +{ + return this->owner_ = this->lock_->tryacquire_read (); +} + +template <class ACE_LOCK> ACE_INLINE +ACE_Read_Guard<ACE_LOCK>::ACE_Read_Guard (ACE_LOCK &m) + : ACE_Guard<ACE_LOCK> (&m) +{ + this->acquire_read (); +} + +template <class ACE_LOCK> ACE_INLINE +ACE_Read_Guard<ACE_LOCK>::ACE_Read_Guard (ACE_LOCK &m, + int block) + : ACE_Guard<ACE_LOCK> (&m) +{ + if (block) + this->acquire_read (); + else + this->tryacquire_read (); +} diff --git a/ace/Handle_Set.cpp b/ace/Handle_Set.cpp index 651cb52b998..1456a351faf 100644 --- a/ace/Handle_Set.cpp +++ b/ace/Handle_Set.cpp @@ -7,6 +7,8 @@ #include "ace/Handle_Set.i" #endif /* __ACE_INLINE__ */ +#include "ace/OS.h" + ACE_RCSID(ace, Handle_Set, "$Id$") ACE_ALLOC_HOOK_DEFINE(ACE_Handle_Set) diff --git a/ace/Hash_Cache_Map_Manager_T.h b/ace/Hash_Cache_Map_Manager_T.h index 8d3685cedbc..c9447b8d988 100644 --- a/ace/Hash_Cache_Map_Manager_T.h +++ b/ace/Hash_Cache_Map_Manager_T.h @@ -17,12 +17,13 @@ #include "ace/Hash_Map_Manager_T.h" #include "ace/Cache_Map_Manager_T.h" -#include "ace/Synch.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) #define ACE_LACKS_PRAGMA_ONCE #endif /* ACE_LACKS_PRAGMA_ONCE */ +#include "ace/Null_Mutex.h" + // Forward declaration. class ACE_Allocator; diff --git a/ace/Hash_Map_Manager_T.i b/ace/Hash_Map_Manager_T.i index 186fdeae613..778bbbd0d13 100644 --- a/ace/Hash_Map_Manager_T.i +++ b/ace/Hash_Map_Manager_T.i @@ -1,7 +1,7 @@ /* -*- C++ -*- */ // $Id$ -#include "ace/Synch.h" +#include "ace/Guard_T.h" template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE ACE_Hash_Map_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::ACE_Hash_Map_Manager_Ex (size_t size, diff --git a/ace/Hash_Map_With_Allocator_T.h b/ace/Hash_Map_With_Allocator_T.h index 69f016214b9..7d97a26bcfe 100644 --- a/ace/Hash_Map_With_Allocator_T.h +++ b/ace/Hash_Map_With_Allocator_T.h @@ -15,7 +15,7 @@ #include /**/ "ace/pre.h" #include "ace/Hash_Map_Manager_T.h" -#include "ace/Synch.h" +#include "ace/Null_Mutex.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/ace/High_Res_Timer.cpp b/ace/High_Res_Timer.cpp index 4723974bdc9..87e2bf136b3 100644 --- a/ace/High_Res_Timer.cpp +++ b/ace/High_Res_Timer.cpp @@ -26,7 +26,8 @@ ACE_ALLOC_HOOK_DEFINE(ACE_High_Res_Timer) defined (ACE_HAS_PENTIUM) || defined (ACE_HAS_ALPHA_TIMER)) && \ !defined (ACE_HAS_HI_RES_TIMER) -# include "ace/Synch.h" +# include "ace/Guard_T.h" +# include "ace/Recursive_Thread_Mutex.h" # include "ace/Object_Manager.h" // Initialize the global_scale_factor_ to 1. The first diff --git a/ace/Lib_Find.cpp b/ace/Lib_Find.cpp index 84f58d48ea5..d5ad37134e7 100644 --- a/ace/Lib_Find.cpp +++ b/ace/Lib_Find.cpp @@ -2,6 +2,7 @@ #include "ace/Lib_Find.h" #include "ace/Log_Msg.h" +#include "ace/OS.h" ACE_RCSID(ace, Lib_Find, "$Id$") diff --git a/ace/Local_Name_Space.h b/ace/Local_Name_Space.h index ae556522975..88a528a894d 100644 --- a/ace/Local_Name_Space.h +++ b/ace/Local_Name_Space.h @@ -24,7 +24,6 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/Malloc_T.h" -#include "ace/Synch.h" /** * @class ACE_NS_String diff --git a/ace/Local_Name_Space_T.h b/ace/Local_Name_Space_T.h index ee672791e86..6304f602153 100644 --- a/ace/Local_Name_Space_T.h +++ b/ace/Local_Name_Space_T.h @@ -25,6 +25,7 @@ #include "ace/Naming_Context.h" #include "ace/SString.h" #include "ace/Local_Name_Space.h" +#include "ace/Null_Mutex.h" /// A short-hand name for our set of name/value/type tuples passed back /// to callers. diff --git a/ace/Lock.cpp b/ace/Lock.cpp new file mode 100644 index 00000000000..bd1d1940524 --- /dev/null +++ b/ace/Lock.cpp @@ -0,0 +1,82 @@ +// $Id$ + +#if !defined (__ACE_INLINE__) +#include "ace/Lock.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Lock, "$Id$") + +ACE_Lock::~ACE_Lock (void) +{ +} + +ACE_Adaptive_Lock::ACE_Adaptive_Lock (void) + : lock_ (0) +{ +} + +ACE_Adaptive_Lock::~ACE_Adaptive_Lock (void) +{ +} + +int +ACE_Adaptive_Lock::remove (void) +{ + return this->lock_->remove (); +} + +int +ACE_Adaptive_Lock::acquire (void) +{ + return this->lock_->acquire (); +} + +int +ACE_Adaptive_Lock::tryacquire (void) +{ + return this->lock_->tryacquire (); +} + +int +ACE_Adaptive_Lock::release (void) +{ + return this->lock_->release (); +} + +int +ACE_Adaptive_Lock::acquire_read (void) +{ + return this->lock_->acquire_read (); +} + +int +ACE_Adaptive_Lock::acquire_write (void) +{ + return this->lock_->acquire_write (); +} + +int +ACE_Adaptive_Lock::tryacquire_read (void) +{ + return this->lock_->tryacquire_read (); +} + +int +ACE_Adaptive_Lock::tryacquire_write (void) +{ + return this->lock_->tryacquire_write (); +} + +int +ACE_Adaptive_Lock::tryacquire_write_upgrade (void) +{ + return this->lock_->tryacquire_write_upgrade (); +} + +void +ACE_Adaptive_Lock::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + // return this->lock_->dump (); +#endif /* ACE_HAS_DUMP */ +} diff --git a/ace/Lock.h b/ace/Lock.h new file mode 100644 index 00000000000..68bacb35dd8 --- /dev/null +++ b/ace/Lock.h @@ -0,0 +1,157 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Lock.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_LOCK_H +#define ACE_LOCK_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class ACE_Lock + * + * @brief This is the abstract base class that contains the uniform + * locking API that is supported by all the ACE synchronization + * mechanisms. + * + * This class is typically used in conjunction with the + * <ACE_Lock_Adapter> in order to provide a polymorphic + * interface to the ACE synchronization mechanisms (e.g., + * <ACE_Mutex>, <ACE_Semaphore>, <ACE_RW_Mutex>, etc). Note that + * the reason that all of ACE doesn't use polymorphic locks is + * that (1) they add ~20% extra overhead for virtual function + * calls and (2) objects with virtual functions can't be placed + * into shared memory. + */ +class ACE_Export ACE_Lock +{ +public: + /// CE needs a default ctor here. + ACE_Lock (void); + + /// Noop virtual destructor + virtual ~ACE_Lock (void); + + /** + * Explicitly destroy the lock. Note that only one thread should + * call this method since it doesn't protect against race + * conditions. + */ + virtual int remove (void) = 0; + + /// Block the thread until the lock is acquired. Returns -1 on + /// failure. + virtual int acquire (void) = 0; + + /** + * Conditionally acquire the lock (i.e., won't block). Returns -1 + * on failure. If we "failed" because someone else already had the + * lock, <errno> is set to <EBUSY>. + */ + virtual int tryacquire (void) = 0; + + /// Release the lock. Returns -1 on failure. + virtual int release (void) = 0; + + /** + * Block until the thread acquires a read lock. If the locking + * mechanism doesn't support read locks then this just calls + * <acquire>. Returns -1 on failure. + */ + virtual int acquire_read (void) = 0; + + /** + * Block until the thread acquires a write lock. If the locking + * mechanism doesn't support read locks then this just calls + * <acquire>. Returns -1 on failure. + */ + virtual int acquire_write (void) = 0; + + /** + * Conditionally acquire a read lock. If the locking mechanism + * doesn't support read locks then this just calls <acquire>. + * Returns -1 on failure. If we "failed" because someone else + * already had the lock, <errno> is set to <EBUSY>. + */ + virtual int tryacquire_read (void) = 0; + + /** + * Conditionally acquire a write lock. If the locking mechanism + * doesn't support read locks then this just calls <acquire>. + * Returns -1 on failure. If we "failed" because someone else + * already had the lock, <errno> is set to <EBUSY>. + */ + virtual int tryacquire_write (void) = 0; + + /** + * Conditionally try to upgrade a lock held for read to a write lock. + * If the locking mechanism doesn't support read locks then this just + * calls <acquire>. Returns 0 on success, -1 on failure. + */ + virtual int tryacquire_write_upgrade (void) = 0; +}; + +/** + * @class ACE_Adaptive_Lock + * + * @brief An adaptive general locking class that defers the decision of + * lock type to run time. + * + * This class, as ACE_Lock, provide a set of general locking APIs. + * However, it defers our decision of what kind of lock to use + * to the run time and delegates all locking operations to the actual + * lock. Users must define a constructor in their subclass to + * initialize <lock_>. + */ +class ACE_Export ACE_Adaptive_Lock : public ACE_Lock +{ +public: + /// You must also override the destructor function to match with how + /// you construct the underneath <lock_>. + virtual ~ACE_Adaptive_Lock (void); + + // = Lock/unlock operations. + + virtual int remove (void); + virtual int acquire (void); + virtual int tryacquire (void); + virtual int release (void); + virtual int acquire_read (void); + virtual int acquire_write (void); + virtual int tryacquire_read (void); + virtual int tryacquire_write (void); + virtual int tryacquire_write_upgrade (void); + void dump (void) const; + +protected: + /** + * Create and initialize create the actual lcok used in the class. + * The default constructor simply set the <lock_> to 0 (null). You + * must overwrite this method for this class to work. + */ + ACE_Adaptive_Lock (void); + + ACE_Lock *lock_; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Lock.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_LOCK_H */ diff --git a/ace/Lock.inl b/ace/Lock.inl new file mode 100644 index 00000000000..bd6d1585cc9 --- /dev/null +++ b/ace/Lock.inl @@ -0,0 +1,8 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_Lock::ACE_Lock (void) +{ +} + diff --git a/ace/Lock_Adapter_T.cpp b/ace/Lock_Adapter_T.cpp new file mode 100644 index 00000000000..792c1bf9e1e --- /dev/null +++ b/ace/Lock_Adapter_T.cpp @@ -0,0 +1,29 @@ +// $Id$ + +#ifndef ACE_LOCK_ADAPTER_T_C +#define ACE_LOCK_ADAPTER_T_C + +#include "ace/Lock_Adapter_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_RCSID(ace, Lock_Adapter_T, "$Id$") + +#if !defined (__ACE_INLINE__) +#include "ace/Lock_Adapter_T.inl" +#endif /* __ACE_INLINE__ */ + +// This constructor isn't inlined, because SunPRO C++ 4.2 + patch +// 104631-07 has trouble compiling TAO with it inline. +template <class ACE_LOCKING_MECHANISM> +ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::ACE_Lock_Adapter (void) + : lock_ (0), + delete_lock_ (1) +{ + ACE_NEW (this->lock_, + ACE_LOCKING_MECHANISM); +} + +#endif /* ACE_LOCK_ADAPTER_T_C */ diff --git a/ace/Lock_Adapter_T.h b/ace/Lock_Adapter_T.h new file mode 100644 index 00000000000..76445506e0a --- /dev/null +++ b/ace/Lock_Adapter_T.h @@ -0,0 +1,119 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Lock_Adapter_T.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_LOCK_ADAPTER_T_H +#define ACE_LOCK_ADAPTER_T_H +#include /**/ "ace/pre.h" + +#include "ace/Lock.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class ACE_Lock_Adapter + * + * @brief This is an adapter that allows applications to transparently + * combine the <ACE_Lock> abstract base class (which contains + * pure virtual methods) with any of the other concrete ACE + * synchronization classes (e.g., <ACE_Mutex>, <ACE_Semaphore>, + * <ACE_RW_Mutex>, etc.). + * + * This class uses a form of the Adapter pattern. + */ +template <class ACE_LOCKING_MECHANISM> +class ACE_Lock_Adapter : public ACE_Lock +{ +public: + typedef ACE_LOCKING_MECHANISM ACE_LOCK; + + // = Initialization/Finalization methods. + + /// Constructor. All locking requests will be forwarded to <lock>. + ACE_Lock_Adapter (ACE_LOCKING_MECHANISM &lock); + + /// Constructor. Since no lock is provided by the user, one will be + /// created internally. + ACE_Lock_Adapter (void); + + /// Destructor. If <lock_> was not passed in by the user, it will be + /// deleted. + virtual ~ACE_Lock_Adapter (void); + + // = Lock accessors. + /// Block the thread until the lock is acquired. + virtual int acquire (void); + + /// Conditionally acquire the lock (i.e., won't block). + virtual int tryacquire (void); + + /// Release the lock. + virtual int release (void); + + /** + * Block until the thread acquires a read lock. If the locking + * mechanism doesn't support read locks then this just calls + * <acquire>. + */ + virtual int acquire_read (void); + + /** + * Block until the thread acquires a write lock. If the locking + * mechanism doesn't support read locks then this just calls + * <acquire>. + */ + virtual int acquire_write (void); + + /// Conditionally acquire a read lock. If the locking mechanism + /// doesn't support read locks then this just calls <acquire>. + virtual int tryacquire_read (void); + + /// Conditionally acquire a write lock. If the locking mechanism + /// doesn't support read locks then this just calls <acquire>. + virtual int tryacquire_write (void); + + /** + * Conditionally try to upgrade a lock held for read to a write lock. + * If the locking mechanism doesn't support read locks then this just + * calls <acquire>. Returns 0 on success, -1 on failure. + */ + virtual int tryacquire_write_upgrade (void); + + /// Explicitly destroy the lock. + virtual int remove (void); + +private: + /// The concrete locking mechanism that all the methods delegate to. + ACE_LOCKING_MECHANISM *lock_; + + /// This flag keep track of whether we are responsible for deleting + /// the lock + int delete_lock_; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Lock_Adapter_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Lock_Adapter_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Lock_Adapter_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_LOCK_ADAPTER_T_H */ diff --git a/ace/Lock_Adapter_T.inl b/ace/Lock_Adapter_T.inl new file mode 100644 index 00000000000..90ba3002e6f --- /dev/null +++ b/ace/Lock_Adapter_T.inl @@ -0,0 +1,94 @@ +/* -*- C++ -*- */ +// $Id$ + +template <class ACE_LOCKING_MECHANISM> ACE_INLINE +ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::ACE_Lock_Adapter (ACE_LOCKING_MECHANISM &lock) + : lock_ (&lock), + delete_lock_ (0) +{ +} + +template <class ACE_LOCKING_MECHANISM> ACE_INLINE +ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::~ACE_Lock_Adapter (void) +{ + if (this->delete_lock_) + delete this->lock_; +} + +// Explicitly destroy the lock. +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::remove (void) +{ + return this->lock_->remove (); +} + +// Block the thread until the lock is acquired. +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::acquire (void) +{ + return this->lock_->acquire (); +} + +// Conditionally acquire the lock (i.e., won't block). + +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::tryacquire (void) +{ + return this->lock_->tryacquire (); +} + +// Release the lock. + +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::release (void) +{ + return this->lock_->release (); +} + +// Block until the thread acquires a read lock. If the locking +// mechanism doesn't support read locks then this just calls +// <acquire>. + +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::acquire_read (void) +{ + return this->lock_->acquire_read (); +} + +// Block until the thread acquires a write lock. If the locking +// mechanism doesn't support read locks then this just calls +// <acquire>. + +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::acquire_write (void) +{ + return this->lock_->acquire_write (); +} + +// Conditionally acquire a read lock. If the locking mechanism +// doesn't support read locks then this just calls <acquire>. + +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::tryacquire_read (void) +{ + return this->lock_->tryacquire_read (); +} + +// Conditionally acquire a write lock. If the locking mechanism +// doesn't support write locks then this just calls <acquire>. + +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::tryacquire_write (void) +{ + return this->lock_->tryacquire_write (); +} + +// Conditionally try to upgrade a lock held for read to a write lock. +// If the locking mechanism doesn't support read locks then this just +// calls <acquire>. Returns 0 on success, -1 on failure. + +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::tryacquire_write_upgrade (void) +{ + return this->lock_->tryacquire_write_upgrade (); +} diff --git a/ace/Log_Msg.cpp b/ace/Log_Msg.cpp index 6315c226a82..f129aeedecb 100644 --- a/ace/Log_Msg.cpp +++ b/ace/Log_Msg.cpp @@ -27,6 +27,7 @@ #include "ace/Log_Msg_NT_Event_Log.h" #include "ace/Log_Msg_UNIX_Syslog.h" #include "ace/Log_Record.h" +#include "ace/Recursive_Thread_Mutex.h" ACE_RCSID(ace, Log_Msg, "$Id$") @@ -36,7 +37,14 @@ ACE_ALLOC_HOOK_DEFINE(ACE_Log_Msg) int ACE_Log_Msg::key_created_ = 0; # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \ defined (ACE_HAS_TSS_EMULATION) - ACE_thread_key_t ACE_Log_Msg::log_msg_tss_key_; + +ACE_thread_key_t *log_msg_tss_key (void) +{ + static ACE_thread_key_t key; + + return &key; +} + # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */ #endif /* ACE_MT_SAFE */ @@ -243,7 +251,7 @@ ACE_Log_Msg::exists (void) // Get the tss_log_msg from thread-specific storage. return key_created_ - && ACE_Thread::getspecific (log_msg_tss_key_, + && ACE_Thread::getspecific (*(log_msg_tss_key ()), ACE_reinterpret_cast (void **, &tss_log_msg)) != -1 && tss_log_msg; @@ -285,7 +293,7 @@ ACE_Log_Msg::instance (void) { ACE_NO_HEAP_CHECK; - if (ACE_Thread::keycreate (&log_msg_tss_key_, + if (ACE_Thread::keycreate (log_msg_tss_key (), &ACE_TSS_cleanup) != 0) { if (1 == ACE_OS_Object_Manager::starting_up()) @@ -314,7 +322,7 @@ ACE_Log_Msg::instance (void) ACE_Log_Msg *tss_log_msg = 0; // Get the tss_log_msg from thread-specific storage. - if (ACE_Thread::getspecific (log_msg_tss_key_, + if (ACE_Thread::getspecific (*(log_msg_tss_key ()), ACE_reinterpret_cast (void **, &tss_log_msg)) == -1) return 0; // This should not happen! @@ -338,7 +346,7 @@ ACE_Log_Msg::instance (void) // storage. It gets deleted via the ACE_TSS_cleanup function // when the thread terminates. - if (ACE_Thread::setspecific (log_msg_tss_key_, + if (ACE_Thread::setspecific (*(log_msg_tss_key()), ACE_reinterpret_cast (void *, tss_log_msg)) != 0) return 0; // Major problems, this should *never* happen! diff --git a/ace/Log_Msg.h b/ace/Log_Msg.h index 09dd79c262e..9b26e0e9c8f 100644 --- a/ace/Log_Msg.h +++ b/ace/Log_Msg.h @@ -19,10 +19,11 @@ // ... but ACE_NDEBUG and ACE_NLOGGING can come from the config.h file, so // pull that one early. #include "ace/config-all.h" +#include "ace/ACE_export.h" #include "ace/Global_Macros.h" #include "ace/Default_Constants.h" #include "ace/Log_Priority.h" -#include "ace/OS.h" +#include "ace/os_include/os_limits.h" // The following ASSERT macro is courtesy of Alexandre Karev // <akg@na47sun05.cern.ch>. @@ -672,10 +673,6 @@ private: #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) static int key_created_; -# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \ - defined (ACE_HAS_TSS_EMULATION) - static ACE_thread_key_t log_msg_tss_key_; -# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */ #endif /* ACE_MT_SAFE */ /// For cleanup, at program termination. diff --git a/ace/Log_Record.h b/ace/Log_Record.h index 07baa649da5..6d92f1ef9eb 100644 --- a/ace/Log_Record.h +++ b/ace/Log_Record.h @@ -12,7 +12,6 @@ // These need to go outside of the #ifdef to avoid problems with // circular dependencies... -#include "ace/OS.h" #include "ace/Log_Priority.h" @@ -20,10 +19,18 @@ #define ACE_LOG_RECORD_H #include /**/ "ace/pre.h" +#include "ace/ACE_export.h" + #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ +#include "ace/Default_Constants.h" +#include "ace/Basic_Types.h" +#include "ace/iosfwd.h" + +class ACE_Time_Value; + /// Defines the structure of an ACE logging record. class ACE_Export ACE_Log_Record { diff --git a/ace/Log_Record.i b/ace/Log_Record.i index a5ecf5c62bf..6720391a9a8 100644 --- a/ace/Log_Record.i +++ b/ace/Log_Record.i @@ -2,6 +2,10 @@ // $Id$ // Log_Record.i +#include "ace/Global_Macros.h" +#include "ace/os_include/arpa/os_inet.h" +#include "ace/Time_Value.h" +#include "ace/OS.h" ASYS_INLINE ACE_Log_Record::~ACE_Log_Record (void) diff --git a/ace/MEM_SAP.i b/ace/MEM_SAP.i index b6a800df06b..da73dd09a7c 100644 --- a/ace/MEM_SAP.i +++ b/ace/MEM_SAP.i @@ -3,6 +3,7 @@ // MEM_SAP.i +#include "ace/RW_Thread_Mutex.h" ASYS_INLINE ACE_MEM_SAP_Node::ACE_MEM_SAP_Node (size_t cap) diff --git a/ace/Malloc.cpp b/ace/Malloc.cpp index 4326c0b52d9..1a3224dbe76 100644 --- a/ace/Malloc.cpp +++ b/ace/Malloc.cpp @@ -10,8 +10,6 @@ #include "ace/Malloc.i" #endif /* __ACE_INLINE__ */ -#include "ace/Synch_T.h" - ACE_RCSID(ace, Malloc, "$Id$") // Process-wide ACE_Allocator. diff --git a/ace/Malloc_Allocator.cpp b/ace/Malloc_Allocator.cpp index 79dfd969d19..f8db674cd1a 100644 --- a/ace/Malloc_Allocator.cpp +++ b/ace/Malloc_Allocator.cpp @@ -18,7 +18,8 @@ #include "ace/Malloc_Allocator.i" #endif /* __ACE_INLINE__ */ -#include "ace/Synch_T.h" +#include "ace/Guard_T.h" +#include "ace/Recursive_Thread_Mutex.h" ACE_RCSID (ace, Malloc_Allocator, "$Id$") diff --git a/ace/Malloc_T.h b/ace/Malloc_T.h index ccde56b901c..a1688439c8a 100644 --- a/ace/Malloc_T.h +++ b/ace/Malloc_T.h @@ -21,7 +21,6 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/Synch.h" #include "ace/Malloc.h" /* Need ACE_Control_Block */ #include "ace/Malloc_Allocator.h" #include "ace/Free_List.h" diff --git a/ace/Manual_Event.cpp b/ace/Manual_Event.cpp new file mode 100644 index 00000000000..ee9be7714c7 --- /dev/null +++ b/ace/Manual_Event.cpp @@ -0,0 +1,54 @@ +// $Id$ + +#if !defined (__ACE_INLINE__) +#include "ace/Manual_Event.inl" +#endif /* __ACE_INLINE__ */ + + +ACE_RCSID(ace, Manual_Event, "$Id$") + +ACE_Manual_Event::ACE_Manual_Event (int initial_state, + int type, + const char *name, + void *arg) + : ACE_Event (1, + initial_state, + type, + ACE_TEXT_CHAR_TO_TCHAR (name), + arg) +{ +} + +#if defined (ACE_HAS_WCHAR) +ACE_Manual_Event::ACE_Manual_Event (int initial_state, + int type, + const wchar_t *name, + void *arg) + : ACE_Event (1, + initial_state, + type, + ACE_TEXT_WCHAR_TO_TCHAR (name), + arg) +{ +} +#endif /* ACE_HAS_WCHAR */ + +void +ACE_Manual_Event::dump (void) const +{ +#if defined (ACE_HAS_DUMP) + ACE_Event::dump (); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Auto_Event::ACE_Auto_Event (int initial_state, + int type, + const char *name, + void *arg) + : ACE_Event (0, + initial_state, + type, + ACE_TEXT_CHAR_TO_TCHAR (name), + arg) +{ +} diff --git a/ace/Manual_Event.h b/ace/Manual_Event.h new file mode 100644 index 00000000000..784f5cfa6f5 --- /dev/null +++ b/ace/Manual_Event.h @@ -0,0 +1,70 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Manual_Event.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_MANUAL_EVENT_H +#define ACE_MANUAL_EVENT_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Event.h" + +/** + * @class ACE_Manual_Event + * + * @brief Manual Events. + * + * Specialization of Event mechanism which wakes up all waiting + * thread on <signal>. All platforms support process-scope locking + * support. However, only Win32 platforms support global naming and + * system-scope locking support. + */ +class ACE_Export ACE_Manual_Event : public ACE_Event +{ +public: + /// constructor which will create manual event + ACE_Manual_Event (int initial_state = 0, + int type = USYNC_THREAD, + const char *name = 0, + void *arg = 0); + +#if defined (ACE_HAS_WCHAR) + /// constructor which will create manual event (wchar_t version) + ACE_Manual_Event (int initial_state, + int type, + const wchar_t *name, + void *arg = 0); +#endif /* ACE_HAS_WCHAR */ + + /// Default dtor. + ~ACE_Manual_Event (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks + ACE_ALLOC_HOOK_DECLARE; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Manual_Event.inl" +#endif /* __ACE_INLINE__ */ + + +#include /**/ "ace/post.h" +#endif /* ACE_MANUAL_EVENT_H */ diff --git a/ace/Manual_Event.inl b/ace/Manual_Event.inl new file mode 100644 index 00000000000..1e4d560a855 --- /dev/null +++ b/ace/Manual_Event.inl @@ -0,0 +1,7 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_Manual_Event::~ACE_Manual_Event (void) +{ +} diff --git a/ace/Map_Manager.h b/ace/Map_Manager.h index e54f78d1024..48db1161f33 100644 --- a/ace/Map_Manager.h +++ b/ace/Map_Manager.h @@ -21,8 +21,8 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/Synch.h" #include "ace/Log_Msg.h" +#include "ace/Basic_Types.h" // Forward declaration. class ACE_Allocator; diff --git a/ace/Map_Manager.i b/ace/Map_Manager.i index ba2a672b2e8..f31a419eb46 100644 --- a/ace/Map_Manager.i +++ b/ace/Map_Manager.i @@ -1,6 +1,8 @@ /* -*- C++ -*- */ // $Id$ +#include "ace/Guard_T.h" + # if ! defined (ACE_HAS_BROKEN_NOOP_DTORS) template <class EXT_ID, class INT_ID> ACE_INLINE ACE_Map_Entry<EXT_ID, INT_ID>::~ACE_Map_Entry (void) diff --git a/ace/Memory_Pool.cpp b/ace/Memory_Pool.cpp index c33b0bc9080..9a44b4277fa 100644 --- a/ace/Memory_Pool.cpp +++ b/ace/Memory_Pool.cpp @@ -9,6 +9,7 @@ #endif /* __ACE_INLINE__ */ #include "ace/Auto_Ptr.h" +#include "ace/RW_Thread_Mutex.h" #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1) #include "ace/Based_Pointer_T.h" diff --git a/ace/Message_Block.cpp b/ace/Message_Block.cpp index dd76ee89d63..d36f00e8935 100644 --- a/ace/Message_Block.cpp +++ b/ace/Message_Block.cpp @@ -1,7 +1,7 @@ #include "ace/Message_Block.h" #include "ace/Log_Msg.h" #include "ace/Malloc_Base.h" -#include "ace/Synch_T.h" +#include "ace/Guard_T.h" //#define ACE_ENABLE_TIMEPROBES #include "ace/Timeprobe.h" diff --git a/ace/Message_Queue.h b/ace/Message_Queue.h index 07c795f20b1..9af59ac9655 100644 --- a/ace/Message_Queue.h +++ b/ace/Message_Queue.h @@ -21,7 +21,6 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/IO_Cntl_Msg.h" -#include "ace/Synch.h" // Forward decls. class ACE_Notification_Strategy; diff --git a/ace/Message_Queue_T.h b/ace/Message_Queue_T.h index 16060114125..41bdbd4b782 100644 --- a/ace/Message_Queue_T.h +++ b/ace/Message_Queue_T.h @@ -15,7 +15,8 @@ #include /**/ "ace/pre.h" #include "ace/Message_Queue.h" -#include "ace/Synch.h" +#include "ace/Synch_Traits.h" +#include "ace/Guard_T.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/ace/Metrics_Cache.h b/ace/Metrics_Cache.h index c82f8697a14..26c6881f6b8 100644 --- a/ace/Metrics_Cache.h +++ b/ace/Metrics_Cache.h @@ -112,7 +112,6 @@ METRICS_PTR->report_##NAME##_stop(); \ #endif /* __ACE_INLINE__ */ #include "ace/Metrics_Cache_T.h" -#include "ace/Synch.h" #include "ace/Singleton.h" #if defined (_MSC_VER) diff --git a/ace/Mutex.cpp b/ace/Mutex.cpp new file mode 100644 index 00000000000..99e99944e9a --- /dev/null +++ b/ace/Mutex.cpp @@ -0,0 +1,103 @@ +// $Id$ + +#if !defined (__ACE_INLINE__) +#include "ace/Mutex.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Mutex, "$Id$") + +ACE_ALLOC_HOOK_DEFINE(ACE_Mutex) + +void +ACE_Mutex::dump (void) const +{ +// ACE_TRACE ("ACE_Mutex::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); +#if defined (CHORUS) + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("lockname_ = %s\n"), this->lockname_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("process_lock_ = %x\n"), this->process_lock_)); +#endif /* CHORUS */ + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Mutex::ACE_Mutex (int type, const ACE_TCHAR *name, + ACE_mutexattr_t *arg, mode_t mode) + : +#if defined (CHORUS) || defined (ACE_HAS_PTHREADS) || defined(ACE_HAS_STHREADS) + process_lock_ (0), + lockname_ (0), +#endif /* CHORUS */ + removed_ (0) +{ + // ACE_TRACE ("ACE_Mutex::ACE_Mutex"); + + // These platforms need process-wide mutex to be in shared memory. +#if defined (CHORUS) || defined(ACE_HAS_PTHREADS) || defined (ACE_HAS_STHREADS) + if (type == USYNC_PROCESS) + { + // Let's see if the shared memory entity already exists. + ACE_HANDLE fd = ACE_OS::shm_open (name, O_RDWR | O_CREAT | O_EXCL, mode); + if (fd == ACE_INVALID_HANDLE) + { + if (errno == EEXIST) + fd = ACE_OS::shm_open (name, O_RDWR | O_CREAT, mode); + else + return; + } + else + { + // We own this shared memory object! Let's set its size. + if (ACE_OS::ftruncate (fd, + sizeof (ACE_mutex_t)) == -1) + { + ACE_OS::close (fd); + return; + } + this->lockname_ = ACE_OS::strdup (name); + if (this->lockname_ == 0) + { + ACE_OS::close (fd); + return; + } + } + + this->process_lock_ = + (ACE_mutex_t *) ACE_OS::mmap (0, + sizeof (ACE_mutex_t), + PROT_RDWR, + MAP_SHARED, + fd, + 0); + ACE_OS::close (fd); + if (this->process_lock_ == MAP_FAILED) + return; + + if (this->lockname_ + && ACE_OS::mutex_init (this->process_lock_, + type, + name, + arg) != 0) + return; + } + // It is ok to fall through into the <mutex_init> below if the + // USYNC_PROCESS flag is not enabled. +#else + ACE_UNUSED_ARG (mode); +#endif /* CHORUS */ + + if (ACE_OS::mutex_init (&this->lock_, + type, + name, + arg) != 0) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("ACE_Mutex::ACE_Mutex"))); +} + +ACE_Mutex::~ACE_Mutex (void) +{ +// ACE_TRACE ("ACE_Mutex::~ACE_Mutex"); + this->remove (); +} diff --git a/ace/Mutex.h b/ace/Mutex.h new file mode 100644 index 00000000000..610b1880bbe --- /dev/null +++ b/ace/Mutex.h @@ -0,0 +1,168 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Mutex.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_MUTEX_H +#define ACE_MUTEX_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/OS.h" + +class ACE_Time_Value; + +/** + * @class ACE_Mutex + * + * @brief <ACE_Mutex> wrapper (valid in same process or across + * processes (depending on TYPE flag)). + */ +class ACE_Export ACE_Mutex +{ +public: + /// Initialize the mutex. + ACE_Mutex (int type = USYNC_THREAD, + const ACE_TCHAR *name = 0, + ACE_mutexattr_t *arg = 0, + mode_t mode = ACE_DEFAULT_FILE_PERMS); + + /// Implicitly destroy the mutex. + ~ACE_Mutex (void); + + /** + * Explicitly destroy the mutex. Note that only one thread should + * call this method since it doesn't protect against race + * conditions. + */ + int remove (void); + + /// Acquire lock ownership (wait on queue if necessary). + int acquire (void); + + /** + * Block the thread until the mutex is acquired or <tv> times out, + * in which case -1 is returned and <errno> == <ETIME>. Note that + * <tv> is assumed to be in "absolute" rather than "relative" time. + * The value of <tv> is updated upon return to show the actual + * (absolute) acquisition time. + */ + int acquire (ACE_Time_Value &tv); + + /** + * If <tv> == 0 then call <acquire()> directly. Otherwise, block + * the thread until the mutex is acquired or <tv> times out, in + * which case -1 is returned and <errno> == <ETIME>. Note that + * <*tv> is assumed to be in "absolute" rather than "relative" time. + * The value of <*tv> is updated upon return to show the actual + * (absolute) acquisition time. */ + int acquire (ACE_Time_Value *tv); + + /** + * Conditionally acquire lock (i.e., don't wait on queue). Returns + * -1 on failure. If we "failed" because someone else already had + * the lock, <errno> is set to <EBUSY>. + */ + int tryacquire (void); + + /// Release lock and unblock a thread at head of queue. + int release (void); + + /** + * Acquire mutex ownership. This calls <acquire> and is only + * here to make the <ACE_Mutex> interface consistent with the + * other synchronization APIs. + */ + int acquire_read (void); + + /** + * Acquire mutex ownership. This calls <acquire> and is only + * here to make the <ACE_Mutex> interface consistent with the + * other synchronization APIs. + */ + int acquire_write (void); + + /** + * Conditionally acquire mutex (i.e., won't block). This calls + * <tryacquire> and is only here to make the <ACE_Mutex> interface + * consistent with the other synchronization APIs. Returns -1 on + * failure. If we "failed" because someone else already had the + * lock, <errno> is set to <EBUSY>. + */ + int tryacquire_read (void); + + /** + * Conditionally acquire mutex (i.e., won't block). This calls + * <tryacquire> and is only here to make the <ACE_Mutex> interface + * consistent with the other synchronization APIs. Returns -1 on + * failure. If we "failed" because someone else already had the + * lock, <errno> is set to <EBUSY>. + */ + int tryacquire_write (void); + + /** + * This is only here for consistency with the other synchronization + * APIs and usability with Lock adapters. Assumes the caller already has + * acquired the mutex and returns 0 in all cases. + */ + int tryacquire_write_upgrade (void); + + /// Return the underlying mutex. + const ACE_mutex_t &lock (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + // = This should be protected but some C++ compilers complain... +public: +#if defined (CHORUS) || defined(ACE_HAS_PTHREADS) || defined(ACE_HAS_STHREADS) + /// This lock resides in shared memory. + ACE_mutex_t *process_lock_; + + /** + * Remember the name of the mutex if we created it so we can unlink + * it when we go away (only the actor that initialized the memory + * can destroy it). + */ + const ACE_TCHAR *lockname_; +#endif /* CHORUS || ACE_HAS_PTHREADS */ + + /// Mutex type supported by the OS. + ACE_mutex_t lock_; + + /// Keeps track of whether <remove> has been called yet to avoid + /// multiple <remove> calls, e.g., explicitly and implicitly in the + /// destructor. This flag isn't protected by a lock, so make sure + /// that you don't have multiple threads simultaneously calling + /// <remove> on the same object, which is a bad idea anyway... + int removed_; + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Mutex &); + ACE_Mutex (const ACE_Mutex &); +}; + +#if defined (__ACE_INLINE__) +#include "ace/Mutex.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_MUTEX_H */ diff --git a/ace/Mutex.inl b/ace/Mutex.inl new file mode 100644 index 00000000000..33022dd651e --- /dev/null +++ b/ace/Mutex.inl @@ -0,0 +1,158 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE int +ACE_Mutex::acquire_read (void) +{ +// ACE_TRACE ("ACE_Mutex::acquire_read"); +#if defined (CHORUS) + if (this->process_lock_) + return ACE_OS::mutex_lock (this->process_lock_); +#endif /* CHORUS */ + return ACE_OS::mutex_lock (&this->lock_); +} + +ACE_INLINE int +ACE_Mutex::acquire_write (void) +{ +// ACE_TRACE ("ACE_Mutex::acquire_write"); +#if defined (CHORUS) + if (this->process_lock_) + return ACE_OS::mutex_lock (this->process_lock_); +#endif /* CHORUS */ + return ACE_OS::mutex_lock (&this->lock_); +} + +ACE_INLINE int +ACE_Mutex::tryacquire_read (void) +{ +// ACE_TRACE ("ACE_Mutex::tryacquire_read"); +#if defined (CHORUS) + if (this->process_lock_) + return ACE_OS::mutex_trylock (this->process_lock_); +#endif /* CHORUS */ + return ACE_OS::mutex_trylock (&this->lock_); +} + +ACE_INLINE const ACE_mutex_t & +ACE_Mutex::lock (void) const +{ +// ACE_TRACE ("ACE_Mutex::lock"); +#if defined (CHORUS) + if (this->process_lock_) + return *this->process_lock_; +#endif /* CHORUS */ + return this->lock_; +} + +ACE_INLINE int +ACE_Mutex::tryacquire_write (void) +{ +// ACE_TRACE ("ACE_Mutex::tryacquire_write"); +#if defined (CHORUS) + if (this->process_lock_) + return ACE_OS::mutex_trylock (this->process_lock_); +#endif /* CHORUS */ + return ACE_OS::mutex_trylock (&this->lock_); +} + +ACE_INLINE int +ACE_Mutex::tryacquire_write_upgrade (void) +{ +// ACE_TRACE ("ACE_Mutex::tryacquire_write_upgrade"); + return 0; +} + +ACE_INLINE int +ACE_Mutex::acquire (void) +{ +// ACE_TRACE ("ACE_Mutex::acquire"); +#if defined (CHORUS) + if (this->process_lock_) + return ACE_OS::mutex_lock (this->process_lock_); +#endif /* CHORUS */ + return ACE_OS::mutex_lock (&this->lock_); +} + +ACE_INLINE int +ACE_Mutex::acquire (ACE_Time_Value &tv) +{ + // ACE_TRACE ("ACE_Mutex::acquire"); + return ACE_OS::mutex_lock (&this->lock_, tv); +} + +ACE_INLINE int +ACE_Mutex::acquire (ACE_Time_Value *tv) +{ + // ACE_TRACE ("ACE_Mutex::acquire"); + return ACE_OS::mutex_lock (&this->lock_, tv); +} + +ACE_INLINE int +ACE_Mutex::tryacquire (void) +{ +// ACE_TRACE ("ACE_Mutex::tryacquire"); +#if defined (CHORUS) + if (this->process_lock_) + return ACE_OS::mutex_trylock (this->process_lock_); +#endif /* CHORUS */ + return ACE_OS::mutex_trylock (&this->lock_); +} + +ACE_INLINE int +ACE_Mutex::release (void) +{ +// ACE_TRACE ("ACE_Mutex::release"); +#if defined (CHORUS) + if (this->process_lock_) + return ACE_OS::mutex_unlock (this->process_lock_); +#endif /* CHORUS */ + return ACE_OS::mutex_unlock (&this->lock_); +} + +ACE_INLINE int +ACE_Mutex::remove (void) +{ +// ACE_TRACE ("ACE_Mutex::remove"); +#if defined (CHORUS) || defined (ACE_HAS_PTHREADS) || defined (ACE_HAS_STHREADS) + int result = 0; + // In the case of a interprocess mutex, the owner is the first + // process that created the shared memory object. In this case, the + // lockname_ pointer will be non-zero (points to allocated memory + // for the name). Owner or not, the memory needs to be unmapped + // from the process. If we are the owner, the file used for + // shm_open needs to be deleted as well. + if (this->process_lock_) + { + if (this->removed_ == 0) + { + this->removed_ = 1; + + // Only destroy the lock if we're the ones who initialized + // it. + if (!this->lockname_) + ACE_OS::munmap ((void *) this->process_lock_, + sizeof (ACE_mutex_t)); + else + { + result = ACE_OS::mutex_destroy (this->process_lock_); + ACE_OS::munmap ((void *) this->process_lock_, + sizeof (ACE_mutex_t)); + ACE_OS::shm_unlink (this->lockname_); + ACE_OS::free (ACE_static_cast (void *, + ACE_const_cast (ACE_TCHAR *, + this->lockname_))); + } + } + } + return result; +#else /* !CHORUS */ + int result = 0; + if (this->removed_ == 0) + { + this->removed_ = 1; + result = ACE_OS::mutex_destroy (&this->lock_); + } + return result; +#endif /* CHORUS */ +} diff --git a/ace/Name_Request_Reply.cpp b/ace/Name_Request_Reply.cpp index 4d2d90d317a..509b8f806d0 100644 --- a/ace/Name_Request_Reply.cpp +++ b/ace/Name_Request_Reply.cpp @@ -1,7 +1,7 @@ #include "ace/Name_Request_Reply.h" #include "ace/Log_Msg.h" #include "ace/Time_Value.h" - +#include "ace/OS.h" ACE_RCSID (ace, Name_Request_Reply, diff --git a/ace/Null_Barrier.h b/ace/Null_Barrier.h new file mode 100644 index 00000000000..b08016b79f6 --- /dev/null +++ b/ace/Null_Barrier.h @@ -0,0 +1,58 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Null_Barrier.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_NULL_BARRIER_H +#define ACE_NULL_BARRIER_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class ACE_Null_Barrier + * + * @brief Implements "NULL barrier synchronization". + */ +class ACE_Export ACE_Null_Barrier +{ +public: + /// Initialize the barrier to synchronize <count> threads. + ACE_Null_Barrier (unsigned int, + const char * = 0, + void * = 0) {}; + + /// Default dtor. + ~ACE_Null_Barrier (void) {}; + + /// Block the caller until all <count> threads have called <wait> and + /// then allow all the caller threads to continue in parallel. + int wait (void) { return 0; }; + + /// Dump the state of an object. + void dump (void) const {}; + + /// Declare the dynamic allocation hooks. + //ACE_ALLOC_HOOK_DECLARE; + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Null_Barrier &); + ACE_Null_Barrier (const ACE_Null_Barrier &); +}; + +#include /**/ "ace/post.h" +#endif /* ACE_NULL_BARRIER_H */ diff --git a/ace/Null_Condition.h b/ace/Null_Condition.h new file mode 100644 index 00000000000..7f098f5b8ef --- /dev/null +++ b/ace/Null_Condition.h @@ -0,0 +1,80 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Null_Condition.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_NULL_CONDITION_H +#define ACE_NULL_CONDITION_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Null_Mutex.h" +#include "ace/os_include/os_errno.h" + +class ACE_Time_Value; + +/** + * @class ACE_Null_Condition + * + * @brief Implement a do nothing <ACE_Condition> variable wrapper, + * i.e., all methods are no ops. This class is necessary since + * some C++ compilers are *very* lame... + */ +class ACE_Export ACE_Null_Condition +{ +public: + ACE_Null_Condition (const ACE_Null_Mutex &m, + const ACE_TCHAR * = 0, + void * = 0) + : mutex_ ((ACE_Null_Mutex &) m) {} + + ~ACE_Null_Condition (void) {} + + /// Returns 0. + int remove (void) {return 0;} + + /// Returns -1 with <errno> == <ETIME>. + int wait (const ACE_Time_Value * = 0) {errno = ETIME; return -1;} + + /// Returns -1 with <errno> == <ETIME>. + int wait (ACE_Null_Mutex &m, + const ACE_Time_Value * = 0) {errno = ETIME; return -1;} + + /// Returns 0. + int signal (void) {return 0;} + + /// Returns 0. + int broadcast (void) {return 0;} + ACE_Null_Mutex &mutex (void) {return this->mutex_;}; + + /// Dump the state of an object. + void dump (void) const {} + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + ACE_Null_Mutex &mutex_; // Reference to mutex lock. + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Null_Condition &); + ACE_Null_Condition (const ACE_Null_Condition &); +}; + +#include /**/ "ace/post.h" +#endif /* ACE_NULL_CONDITION_H */ diff --git a/ace/Null_Mutex.h b/ace/Null_Mutex.h new file mode 100644 index 00000000000..603b42a9a7c --- /dev/null +++ b/ace/Null_Mutex.h @@ -0,0 +1,199 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Null_Mutex.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_NULL_MUTEX_H +#define ACE_NULL_MUTEX_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_errno.h" +#include "ace/Global_Macros.h" + +class ACE_Time_Value; + +/** + * @class ACE_Null_Mutex + * + * @brief Implement a do nothing <ACE_Mutex>, i.e., all the methods are + * no ops. + */ +class ACE_Export ACE_Null_Mutex +{ +public: + ACE_Null_Mutex (const ACE_TCHAR * = 0) + : lock_ (0) {} + ~ACE_Null_Mutex (void) {} + /// Return 0. + int remove (void) {return 0;} + + /// Return 0. + int acquire (void) {return 0;} + + /// Return -1 with <errno> == <ETIME>. + int acquire (ACE_Time_Value &timeout) {errno = ETIME; return -1;} + + /// Return -1 with <errno> == <ETIME>. + int acquire (ACE_Time_Value *timeout) {errno = ETIME; return -1;} + + /// Return 0. + int tryacquire (void) {return 0;} + + /// Return 0. + int release (void) {return 0;} + + /// Return 0. + int acquire_write (void) {return 0;} + + /// Return 0. + int tryacquire_write (void) {return 0;} + + /// Return 0. + int tryacquire_write_upgrade (void) {return 0;} + + /// Return 0. + int acquire_read (void) {return 0;} + + /// Return 0. + int tryacquire_read (void) {return 0;} + + /// Dump the state of an object. + void dump (void) const {} + + /// Declare the dynamic allocation hooks. + //ACE_ALLOC_HOOK_DECLARE; + + int lock_; // A dummy lock. +}; + +#if defined (ACE_USES_OBSOLETE_GUARD_CLASSES) +/** + * @class ACE_Null_Mutex_Guard + * + * @brief This data structure is meant to be used within a method or + * function... It performs automatic aquisition and release of + * an ACE_Null_Mutex. + * + * This class is obsolete and should be replaced by + * ACE_Guard<ACE_Null_Mutex>. + */ +class ACE_Export ACE_Null_Mutex_Guard +{ +public: + ACE_Null_Mutex_Guard (ACE_Null_Mutex &) {} + ~ACE_Null_Mutex_Guard (void) {} + int remove (void) {return 0;} + int locked (void) {return 1;} + int acquire (void) {return 0;} + int tryacquire (void) {return 0;} + int release (void) {return 0:} + void dump (void) const {} + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Null_Mutex_Guard &); + ACE_Null_Mutex_Guard (const ACE_Null_Mutex_Guard &); +}; +#endif /* ACE_USES_OBSOLETE_GUARD_CLASSES */ + +template <class ACE_LOCK> +class ACE_Guard; + +ACE_TEMPLATE_SPECIALIZATION +/** + * @class ACE_Guard<ACE_Null_Mutex> + * + * @brief Template specialization of <ACE_Guard> for the + * <ACE_Null_Mutex>. + * + * This specialization is useful since it helps to speedup + * performance of the "Null_Mutex" considerably. + */ +class ACE_Export ACE_Guard<ACE_Null_Mutex> +{ +public: + // = Initialization and termination methods. + ACE_Guard (ACE_Null_Mutex &) {} + ACE_Guard (ACE_Null_Mutex &, int) {} + ACE_Guard (ACE_Null_Mutex &, int, int) {} +#if defined (ACE_WIN32) + ~ACE_Guard (void) {} +#endif /* ACE_WIN32 */ + + int acquire (void) { return 0; } + int tryacquire (void) { return 0; } + int release (void) { return 0; } + void disown (void) {} + int locked (void) { return 1; } + int remove (void) { return 0; } + void dump (void) const {} + +private: + // = Prevent assignment and initialization. + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Guard<ACE_Null_Mutex> &)) + ACE_UNIMPLEMENTED_FUNC (ACE_Guard (const ACE_Guard<ACE_Null_Mutex> &)) +}; + +template <class ACE_LOCK> +class ACE_Write_Guard; + +ACE_TEMPLATE_SPECIALIZATION +/** + * @class ACE_Write_Guard<ACE_Null_Mutex> + * + */ +class ACE_Export ACE_Write_Guard<ACE_Null_Mutex> : public ACE_Guard<ACE_Null_Mutex> +{ +public: + ACE_Write_Guard (ACE_Null_Mutex &m) + : ACE_Guard<ACE_Null_Mutex> (m) {} + ACE_Write_Guard (ACE_Null_Mutex &m, int blocked) + : ACE_Guard<ACE_Null_Mutex> (m, blocked) {} + + int acquire_write (void) { return 0; } + int acquire (void) { return 0; } + int tryacquire_write (void) { return 0; } + int tryacquire (void) { return 0; } + void dump (void) const {} +}; + +template <class ACE_LOCK> +class ACE_Read_Guard; + +ACE_TEMPLATE_SPECIALIZATION +/** + * @class ACE_Read_Guard<ACE_Null_Mutex> + * + */ +class ACE_Export ACE_Read_Guard<ACE_Null_Mutex> : public ACE_Guard<ACE_Null_Mutex> +{ +public: + ACE_Read_Guard (ACE_Null_Mutex &m) + : ACE_Guard<ACE_Null_Mutex> (m) {} + ACE_Read_Guard (ACE_Null_Mutex &m, int blocked) + : ACE_Guard<ACE_Null_Mutex> (m, blocked) {} + + int acquire_read (void) { return 0; } + int acquire (void) { return 0; } + int tryacquire_read (void) { return 0; } + int tryacquire (void) { return 0; } + void dump (void) const {} +}; + +#include /**/ "ace/post.h" +#endif /* ACE_NULL_MUTEX_H */ diff --git a/ace/Null_Semaphore.h b/ace/Null_Semaphore.h new file mode 100644 index 00000000000..fbd045f5455 --- /dev/null +++ b/ace/Null_Semaphore.h @@ -0,0 +1,100 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Null_Semaphore.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_NULL_SEMAPHORE_H +#define ACE_NULL_SEMAPHORE_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/os_include/os_errno.h" + +class ACE_Time_Value; + +/** + * @class ACE_Null_Semaphore + * + * @brief Implement a do nothing <ACE_Semaphore>, i.e., all the methods are + * no ops. + * + * Although the methods are no-ops, the return values are different for + * the blocking as opposed to timed acquires. The blocking version of + * acquire() is often used to serialize access to a critical section, + * whereas the timed version is often used to wait for another thread + * to update some condition or change some shared state. When using an + * ACE_Null_Semaphore, however, there's no other thread involved to + * change a state or condition (otherwise, a null semaphore would be + * inappropriate). Returning an error value signifies that the + * state or condition has not been (and can't be) changed, which is + * consistent with the behavior of the threaded case where a timeout + * occurs before the state or condition is changed. + */ +class ACE_Export ACE_Null_Semaphore +{ +public: + ACE_Null_Semaphore (unsigned int count = 1, // By default make this unlocked. + int type = 0, + const ACE_TCHAR *name = 0, + void * = 0, + int max = 0x7fffffff) {} + ~ACE_Null_Semaphore (void) {} + /// Return 0. + int remove (void) {return 0;} + + /// Return 0. + int acquire (void) {return 0;} + + /// Return -1 with <errno> == <ETIME>. + int acquire (ACE_Time_Value &) {errno = ETIME; return -1;} + + /// Return -1 with <errno> == <ETIME>. + int acquire (ACE_Time_Value *) {errno = ETIME; return -1;} + + /// Return 0. + int tryacquire (void) {return 0;} + + /// Return 0. + int release (void) {return 0;} + + /// Return 0. + int release (size_t) {return 0;} + + /// Return 0. + int acquire_write (void) {return 0;} + + /// Return 0. + int tryacquire_write (void) {return 0;} + + /// Return 0. + int tryacquire_write_upgrade (void) {return 0;} + + /// Return 0. + int acquire_read (void) {return 0;} + + /// Return 0. + int tryacquire_read (void) {return 0;} + + /// Dump the state of an object. + void dump (void) const {} + + /// Declare the dynamic allocation hooks. + //ACE_ALLOC_HOOK_DECLARE; +}; + +#include /**/ "ace/post.h" +#endif /* ACE_NULL_SEMAPHORE_H */ @@ -459,18 +459,6 @@ private: # define ACE_PAGEFILE_MEMORY_POOL ACE_Pagefile_Memory_Pool, ACE_Pagefile_Memory_Pool_Options # endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ -# if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) -# define ACE_TSS_TYPE(T) ACE_TSS< T > -# if defined (ACE_HAS_BROKEN_CONVERSIONS) -# define ACE_TSS_GET(I, T) (*(I)) -# else -# define ACE_TSS_GET(I, T) ((I)->operator T * ()) -# endif /* ACE_HAS_BROKEN_CONVERSIONS */ -# else -# define ACE_TSS_TYPE(T) T -# define ACE_TSS_GET(I, T) (I) -# endif /* ACE_HAS_THREADS && (ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATIOND) */ - # if defined (ACE_HAS_PROC_FS) # include /**/ <sys/procfs.h> # endif /* ACE_HAS_PROC_FS */ diff --git a/ace/Object_Manager.cpp b/ace/Object_Manager.cpp index aa1196471d6..541c1d59248 100644 --- a/ace/Object_Manager.cpp +++ b/ace/Object_Manager.cpp @@ -12,7 +12,6 @@ #include "ace/Signal.h" #include "ace/Log_Msg.h" #include "ace/Containers.h" -#include "ace/Synch.h" #include "ace/Malloc.h" #include "ace/Signal.h" #include "ace/Framework_Component.h" @@ -22,6 +21,10 @@ # include "ace/Object_Manager.i" #endif /* __ACE_INLINE__ */ +#include "ace/Null_Mutex.h" +#include "ace/Mutex.h" +#include "ace/RW_Thread_Mutex.h" + ACE_RCSID(ace, Object_Manager, "$Id$") #if ! defined (ACE_APPLICATION_PREALLOCATED_OBJECT_DEFINITIONS) diff --git a/ace/Object_Manager.h b/ace/Object_Manager.h index 24991910dc1..2101ca83c83 100644 --- a/ace/Object_Manager.h +++ b/ace/Object_Manager.h @@ -32,6 +32,13 @@ class ACE_Sig_Set; class ACE_Thread_Mutex; class ACE_Recursive_Thread_Mutex; class ACE_RW_Thread_Mutex; + + // This is included because Svc_conf_l.cpp needs it and I don't want to + // have to change it right now. :-( + // The worst thing about this, is that it still includes OS.h, but since we + // have to include it above anyway, it doesn't make a difference right now. + // dhinton. + #include "ace/Recursive_Thread_Mutex.h" #endif /* ACE_MT_SAFE */ class ACE_Cleanup_Info_Node; diff --git a/ace/POSIX_Asynch_IO.h b/ace/POSIX_Asynch_IO.h index ec5775b43cc..1ea2bb6e48b 100644 --- a/ace/POSIX_Asynch_IO.h +++ b/ace/POSIX_Asynch_IO.h @@ -38,6 +38,8 @@ #include "ace/ACE.h" #endif +#include "ace/Null_Mutex.h" + // Forward declarations class ACE_POSIX_Proactor; class ACE_Proactor_Impl; diff --git a/ace/POSIX_CB_Proactor.h b/ace/POSIX_CB_Proactor.h index e880cfe3315..3d4e1e1e7e8 100644 --- a/ace/POSIX_CB_Proactor.h +++ b/ace/POSIX_CB_Proactor.h @@ -21,6 +21,10 @@ #if defined (ACE_HAS_AIO_CALLS) && !defined(__sun) && !defined(__Lynx__) +#include "ace/Synch_Traits.h" +#include "ace/Thread_Semaphore.h" +#include "ace/Null_Semaphore.h" + #include "ace/POSIX_Proactor.h" /** diff --git a/ace/Proactor.cpp b/ace/Proactor.cpp index a2ed115ca66..1d22b43aae4 100644 --- a/ace/Proactor.cpp +++ b/ace/Proactor.cpp @@ -28,6 +28,8 @@ ACE_RCSID(ace, Proactor, "$Id$") #include "ace/Proactor.i" #endif /* __ACE_INLINE__ */ +#include "ace/Auto_Event.h" + /// Process-wide ACE_Proactor. ACE_Proactor *ACE_Proactor::proactor_ = 0; diff --git a/ace/Process_Manager.cpp b/ace/Process_Manager.cpp index 8e7b2307d9b..6a3cba11800 100644 --- a/ace/Process_Manager.cpp +++ b/ace/Process_Manager.cpp @@ -2,7 +2,6 @@ // Process_Manager.cpp #include "ace/ACE.h" -#include "ace/Synch_T.h" #include "ace/Process.h" #include "ace/Signal.h" #include "ace/Process_Manager.h" diff --git a/ace/Process_Manager.h b/ace/Process_Manager.h index 605542ed05b..8920cc487a2 100644 --- a/ace/Process_Manager.h +++ b/ace/Process_Manager.h @@ -14,7 +14,6 @@ #define ACE_PROCESS_MANAGER_H #include /**/ "ace/pre.h" -#include "ace/Synch.h" #include "ace/Reactor.h" #include "ace/Event_Handler.h" @@ -24,6 +23,10 @@ #include "ace/Process.h" +#if defined (ACE_HAS_THREADS) +# include "ace/Recursive_Thread_Mutex.h" +#endif /* ACE_HAS_THREADS */ + /** * @class ACE_Process_Descriptor * diff --git a/ace/Process_Mutex.cpp b/ace/Process_Mutex.cpp index 551887405de..211f91f183a 100644 --- a/ace/Process_Mutex.cpp +++ b/ace/Process_Mutex.cpp @@ -1,7 +1,6 @@ // $Id$ #include "ace/Process_Mutex.h" -#include "ace/Synch.h" #include "ace/Log_Msg.h" #include "ace/ACE.h" diff --git a/ace/Process_Mutex.h b/ace/Process_Mutex.h index eb77a8e36af..610e2d3cf66 100644 --- a/ace/Process_Mutex.h +++ b/ace/Process_Mutex.h @@ -29,11 +29,12 @@ #ifdef _ACE_USE_SV_SEM # undef _ACE_USE_SV_SEM #endif /* _ACE_USE_SV_SEM */ + #if defined (ACE_HAS_SYSV_IPC) && !defined (ACE_USES_MUTEX_FOR_PROCESS_MUTEX) # include "ace/SV_Semaphore_Complex.h" # define _ACE_USE_SV_SEM #else -# include "ace/Synch.h" +# include "ace/Mutex.h" #endif /* ACE_HAS_SYSV_IPC && !ACE_USES_MUTEX_FOR_PROCESS_MUTEX */ /** diff --git a/ace/Process_Semaphore.h b/ace/Process_Semaphore.h index b99981c4076..823af416422 100644 --- a/ace/Process_Semaphore.h +++ b/ace/Process_Semaphore.h @@ -19,7 +19,7 @@ #define ACE_PROCESS_SEMAPHORE_H #include /**/ "ace/pre.h" -#include "ace/Synch.h" +#include "ace/ACE_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/ace/RB_Tree.cpp b/ace/RB_Tree.cpp index 8cf9fd364ec..5b5e0cabadd 100644 --- a/ace/RB_Tree.cpp +++ b/ace/RB_Tree.cpp @@ -16,6 +16,8 @@ #include "ace/RB_Tree.i" #endif /* __ACE_INLINE__ */ +#include "ace/Log_Msg.h" + ACE_RCSID(ace, RB_Tree, "$Id$") // Constructor. diff --git a/ace/RB_Tree.i b/ace/RB_Tree.i index 31a3222dfbe..c442f8099e2 100644 --- a/ace/RB_Tree.i +++ b/ace/RB_Tree.i @@ -1,7 +1,7 @@ /* -*- C++ -*- */ // $Id$ -#include "ace/Synch.h" +#include "ace/Guard_T.h" #include "ace/Malloc_Base.h" ///////////////////////////////////////////////////// diff --git a/ace/RW_Mutex.cpp b/ace/RW_Mutex.cpp new file mode 100644 index 00000000000..fd076c414dd --- /dev/null +++ b/ace/RW_Mutex.cpp @@ -0,0 +1,48 @@ +/* -*- C++ -*- */ +/** + * @file RW_Mutex.cpp + * + * $Id$ + * + * Originally in Synch.cpp + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ + +#if defined (ACE_HAS_THREADS) + +#if !defined (__ACE_INLINE__) +#include "ace/RW_Mutex.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, RW_Mutex, "$Id$") + +void +ACE_RW_Mutex::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_RW_Mutex::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_RW_Mutex::ACE_RW_Mutex (int type, const ACE_TCHAR *name, void *arg) + : removed_ (0) +{ +// ACE_TRACE ("ACE_RW_Mutex::ACE_RW_Mutex"); + if (ACE_OS::rwlock_init (&this->lock_, type, name, arg) != 0) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("ACE_RW_Mutex::ACE_RW_Mutex"))); +} + +ACE_RW_Mutex::~ACE_RW_Mutex (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::~ACE_RW_Mutex"); + this->remove (); +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ace/RW_Mutex.h b/ace/RW_Mutex.h new file mode 100644 index 00000000000..56aec6db13f --- /dev/null +++ b/ace/RW_Mutex.h @@ -0,0 +1,135 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Mutex.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_RW_MUTEX_H +#define ACE_RW_MUTEX_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// ACE platform supports some form of threading. +#if defined (ACE_HAS_THREADS) + +#include "ace/OS.h" + +/** + * @class ACE_RW_Mutex + * + * @brief Wrapper for readers/writer locks. + * + * These are most useful for applications that have many more + * parallel readers than writers... + */ +class ACE_Export ACE_RW_Mutex +{ +public: + /// Initialize a readers/writer lock. + ACE_RW_Mutex (int type = USYNC_THREAD, + const ACE_TCHAR *name = 0, + void *arg = 0); + + /// Implicitly destroy a readers/writer lock + ~ACE_RW_Mutex (void); + + /** + * Explicitly destroy a readers/writer lock. Note that only one + * thread should call this method since it doesn't protect against + * race conditions. + */ + int remove (void); + + /// Acquire a read lock, but block if a writer hold the lock. + int acquire_read (void); + + /// Acquire a write lock, but block if any readers or a + /// writer hold the lock. + int acquire_write (void); + + /** + * Conditionally acquire a read lock (i.e., won't block). Returns + * -1 on failure. If we "failed" because someone else already had + * the lock, <errno> is set to <EBUSY>. + */ + int tryacquire_read (void); + + /// Conditionally acquire a write lock (i.e., won't block). + int tryacquire_write (void); + + /** + * Conditionally upgrade a read lock to a write lock. This only + * works if there are no other readers present, in which case the + * method returns 0. Otherwise, the method returns -1 and sets + * <errno> to <EBUSY>. Note that the caller of this method *must* + * already possess this lock as a read lock (but this condition is + * not checked by the current implementation). + */ + int tryacquire_write_upgrade (void); + + /** + * Note, for interface uniformity with other synchronization + * wrappers we include the <acquire> method. This is implemented as + * a write-lock to safe... + */ + int acquire (void); + + /** + * Note, for interface uniformity with other synchronization + * wrappers we include the <tryacquire> method. This is implemented + * as a write-lock to be safe... Returns -1 on failure. If we + * "failed" because someone else already had the lock, <errno> is + * set to <EBUSY>. + */ + int tryacquire (void); + + /// Unlock a readers/writer lock. + int release (void); + + /// Return the underlying lock. + const ACE_rwlock_t &lock (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// Readers/writer lock. + ACE_rwlock_t lock_; + + /// Keeps track of whether <remove> has been called yet to avoid + /// multiple <remove> calls, e.g., explicitly and implicitly in the + /// destructor. This flag isn't protected by a lock, so make sure + /// that you don't have multiple threads simultaneously calling + /// <remove> on the same object, which is a bad idea anyway... + int removed_; + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_RW_Mutex &); + ACE_RW_Mutex (const ACE_RW_Mutex &); +}; + +#if defined (__ACE_INLINE__) +#include "ace/RW_Mutex.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_RW_MUTEX_H */ diff --git a/ace/RW_Mutex.inl b/ace/RW_Mutex.inl new file mode 100644 index 00000000000..4d5fb16be2c --- /dev/null +++ b/ace/RW_Mutex.inl @@ -0,0 +1,78 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE const ACE_rwlock_t & +ACE_RW_Mutex::lock (void) const +{ +// ACE_TRACE ("ACE_RW_Mutex::lock"); + return this->lock_; +} + +ACE_INLINE int +ACE_RW_Mutex::remove (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::remove"); + int result = 0; + if (this->removed_ == 0) + { + this->removed_ = 1; + result = ACE_OS::rwlock_destroy (&this->lock_); + } + return result; +} + +ACE_INLINE int +ACE_RW_Mutex::acquire_read (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::acquire_read"); + return ACE_OS::rw_rdlock (&this->lock_); +} + +ACE_INLINE int +ACE_RW_Mutex::acquire_write (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::acquire_write"); + return ACE_OS::rw_wrlock (&this->lock_); +} + +ACE_INLINE int +ACE_RW_Mutex::acquire (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::acquire"); + return ACE_OS::rw_wrlock (&this->lock_); +} + +ACE_INLINE int +ACE_RW_Mutex::tryacquire_read (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::tryacquire_read"); + return ACE_OS::rw_tryrdlock (&this->lock_); +} + +ACE_INLINE int +ACE_RW_Mutex::tryacquire_write (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::tryacquire_write"); + return ACE_OS::rw_trywrlock (&this->lock_); +} + +ACE_INLINE int +ACE_RW_Mutex::tryacquire_write_upgrade (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::tryacquire_write_upgrade"); + return ACE_OS::rw_trywrlock_upgrade (&this->lock_); +} + +ACE_INLINE int +ACE_RW_Mutex::tryacquire (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::tryacquire"); + return this->tryacquire_write (); +} + +ACE_INLINE int +ACE_RW_Mutex::release (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::release"); + return ACE_OS::rw_unlock (&this->lock_); +} diff --git a/ace/RW_Thread_Mutex.cpp b/ace/RW_Thread_Mutex.cpp new file mode 100644 index 00000000000..e5c66318903 --- /dev/null +++ b/ace/RW_Thread_Mutex.cpp @@ -0,0 +1,38 @@ +/* -*- C++ -*- */ +/** + * @file RW_Thread_Mutex.cpp + * + * $Id$ + * + * Originally in Synch.cpp + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ + +#if defined (ACE_HAS_THREADS) + +#if !defined (__ACE_INLINE__) +#include "ace/RW_Thread_Mutex.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, RW_Thread_Mutex, "$Id$") + +ACE_ALLOC_HOOK_DEFINE(ACE_RW_Thread_Mutex) + +ACE_RW_Thread_Mutex::ACE_RW_Thread_Mutex (const ACE_TCHAR *name, + void *arg) + : ACE_RW_Mutex (USYNC_THREAD, name, arg) +{ +// ACE_TRACE ("ACE_RW_Thread_Mutex::ACE_RW_Thread_Mutex"); +} + +void +ACE_RW_Thread_Mutex::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_RW_Thread_Mutex::dump"); + ACE_RW_Mutex::dump (); +#endif /* ACE_HAS_DUMP */ +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ace/RW_Thread_Mutex.h b/ace/RW_Thread_Mutex.h new file mode 100644 index 00000000000..171006ad11a --- /dev/null +++ b/ace/RW_Thread_Mutex.h @@ -0,0 +1,70 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file RW_Thread_Mutex.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_RW_THREAD_MUTEX_H +#define ACE_RW_THREAD_MUTEX_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_HAS_THREADS) +# include "ace/Null_Mutex.h" +#else /* ACE_HAS_THREADS */ +// ACE platform supports some form of threading. + +#include "ace/RW_Mutex.h" + +/** + * @class ACE_RW_Thread_Mutex + * + * @brief Wrapper for readers/writer locks that exist within a process. + */ +class ACE_Export ACE_RW_Thread_Mutex : public ACE_RW_Mutex +{ +public: + ACE_RW_Thread_Mutex (const ACE_TCHAR *name = 0, + void *arg = 0); + + /// Default dtor. + ~ACE_RW_Thread_Mutex (void); + + /** + * Conditionally upgrade a read lock to a write lock. This only + * works if there are no other readers present, in which case the + * method returns 0. Otherwise, the method returns -1 and sets + * <errno> to <EBUSY>. Note that the caller of this method *must* + * already possess this lock as a read lock (but this condition is + * not checked by the current implementation). + */ + int tryacquire_write_upgrade (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + +#if defined (__ACE_INLINE__) +#include "ace/RW_Thread_Mutex.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* !ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_RW_THREAD_MUTEX_H */ diff --git a/ace/RW_Thread_Mutex.inl b/ace/RW_Thread_Mutex.inl new file mode 100644 index 00000000000..82b4beb7f15 --- /dev/null +++ b/ace/RW_Thread_Mutex.inl @@ -0,0 +1,14 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE int +ACE_RW_Thread_Mutex::tryacquire_write_upgrade (void) +{ +// ACE_TRACE ("ACE_RW_Thread_Mutex::tryacquire_write_upgrade"); + return ACE_OS::rw_trywrlock_upgrade (&this->lock_); +} + +ACE_INLINE +ACE_RW_Thread_Mutex::~ACE_RW_Thread_Mutex (void) +{ +} diff --git a/ace/Recursive_Thread_Mutex.cpp b/ace/Recursive_Thread_Mutex.cpp new file mode 100644 index 00000000000..0644e4ba6f7 --- /dev/null +++ b/ace/Recursive_Thread_Mutex.cpp @@ -0,0 +1,143 @@ +/* -*- C++ -*- */ +/** + * @file Recursive_Thread_Mutex.cpp + * + * $Id$ + * + * Originally in Synch.cpp + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ + +#include "ace/Recursive_Thread_Mutex.h" + +#if defined (ACE_HAS_THREADS) + +#if !defined (__ACE_INLINE__) +#include "ace/Recursive_Thread_Mutex.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Recursive_Thread_Mutex, "$Id$") + +ACE_ALLOC_HOOK_DEFINE(ACE_Recursive_Thread_Mutex) + +ACE_Recursive_Thread_Mutex::ACE_Recursive_Thread_Mutex (const ACE_TCHAR *name, + ACE_mutexattr_t *arg) + : removed_ (0) +{ + // ACE_TRACE ("ACE_Recursive_Thread_Mutex::ACE_Recursive_Thread_Mutex"); +#if defined (ACE_HAS_FSU_PTHREADS) && ! defined (ACE_WIN32) + // Initialize FSU pthreads package. If called more than once, + // pthread_init does nothing and so does no harm. + pthread_init (); +#endif /* ACE_HAS_FSU_PTHREADS && ! ACE_WIN32 */ + if (ACE_OS::recursive_mutex_init (&this->lock_, + name, + arg) == -1) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("recursive_mutex_init"))); +} + +ACE_Recursive_Thread_Mutex::~ACE_Recursive_Thread_Mutex (void) +{ + // ACE_TRACE ("ACE_Recursive_Thread_Mutex::~ACE_Recursive_Thread_Mutex"); + this->remove (); +} + +int +ACE_Recursive_Thread_Mutex::remove (void) +{ +// ACE_TRACE ("ACE_Recursive_Thread_Mutex::remove"); + int result = 0; + if (this->removed_ == 0) + { + this->removed_ = 1; + result = ACE_OS::recursive_mutex_destroy (&this->lock_); + } + return result; +} + +// The counter part of the following two functions for Win32 are +// located in file Synch.i +ACE_thread_t +ACE_Recursive_Thread_Mutex::get_thread_id (void) +{ + // ACE_TRACE ("ACE_Recursive_Thread_Mutex::get_thread_id"); +#if defined (ACE_HAS_RECURSIVE_MUTEXES) + // @@ The structure CriticalSection in Win32 doesn't hold the thread + // handle of the thread that owns the lock. However it is still not + // clear at this point how to translate a thread handle to its + // corresponding thread id. + errno = ENOTSUP; + return ACE_OS::NULL_thread; +#else + ACE_thread_t owner_id; + ACE_OS::mutex_lock (&this->lock_.nesting_mutex_); + owner_id = this->lock_.owner_id_; + ACE_OS::mutex_unlock (&this->lock_.nesting_mutex_); + return owner_id; +#endif /* ACE_WIN32 */ +} + +int +ACE_Recursive_Thread_Mutex::get_nesting_level (void) +{ + // ACE_TRACE ("ACE_Recursive_Thread_Mutex::get_nesting_level"); +#if defined (ACE_HAS_WINCE) || defined (VXWORKS) || defined (ACE_PSOS) + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_RECURSIVE_MUTEXES) + // Nothing inside of a CRITICAL_SECTION object should ever be + // accessed directly. It is documented to change at any time. +# if defined (ACE_WIN64) + // Things are different on Windows XP 64-bit + return this->lock_.LockCount + 1; +# elif defined (ACE_WIN32) + // This is really a Win32-ism... + return this->lock_.RecursionCount; +# else + ACE_NOTSUP_RETURN (-1); +# endif /* ACE_HAS_RECURSIVE_MUTEXES */ +#else + int nesting_level = 0; + ACE_OS::mutex_lock (&this->lock_.nesting_mutex_); + nesting_level = this->lock_.nesting_level_; + ACE_OS::mutex_unlock (&this->lock_.nesting_mutex_); + return nesting_level; +#endif /* !ACE_HAS_WINCE */ +} + +ACE_Recursive_Thread_Mutex::ACE_Recursive_Thread_Mutex (const ACE_Recursive_Thread_Mutex &) +{ +} + +int +ACE_Recursive_Thread_Mutex::acquire (void) +{ + return ACE_OS::recursive_mutex_lock (&this->lock_); +} + +int +ACE_Recursive_Thread_Mutex::release (void) +{ + return ACE_OS::recursive_mutex_unlock (&this->lock_); +} + +int +ACE_Recursive_Thread_Mutex::tryacquire (void) +{ + return ACE_OS::recursive_mutex_trylock (&this->lock_); +} + +void +ACE_Recursive_Thread_Mutex::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Recursive_Thread_Mutex::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ace/Recursive_Thread_Mutex.h b/ace/Recursive_Thread_Mutex.h new file mode 100644 index 00000000000..a5b90c59ca8 --- /dev/null +++ b/ace/Recursive_Thread_Mutex.h @@ -0,0 +1,168 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Recursive_Thread_Mutex.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_RECURSIVE_THREAD_MUTEX_H +#define ACE_RECURSIVE_THREAD_MUTEX_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_HAS_THREADS) +# include "ace/Null_Mutex.h" +#else /* ACE_HAS_THREADS */ +// ACE platform supports some form of threading. + +#include "ace/OS.h" + +/** + * @class ACE_Recursive_Thread_Mutex + * + * @brief Implement a C++ wrapper that allows nested acquisition and + * release of a mutex that occurs in the same thread. + */ +class ACE_Export ACE_Recursive_Thread_Mutex +{ +public: + /// Initialize a recursive mutex. + ACE_Recursive_Thread_Mutex (const ACE_TCHAR *name = 0, + ACE_mutexattr_t *arg = 0); + + /// Implicitly release a recursive mutex. + ~ACE_Recursive_Thread_Mutex (void); + + /** + * Implicitly release a recursive mutex. Note that only one thread + * should call this method since it doesn't protect against race + * conditions. + */ + int remove (void); + + /** + * Acquire a recursive mutex (will increment the nesting level and + * not deadmutex if the owner of the mutex calls this method more + * than once). + */ + int acquire (void); + + /** + * Conditionally acquire a recursive mutex (i.e., won't block). + * Returns -1 on failure. If we "failed" because someone else + * already had the lock, <errno> is set to <EBUSY>. + */ + int tryacquire (void); + + /** + * Acquire mutex ownership. This calls <acquire> and is only + * here to make the <ACE_Recusive_Thread_Mutex> interface consistent + * with the other synchronization APIs. + */ + int acquire_read (void); + + /** + * Acquire mutex ownership. This calls <acquire> and is only + * here to make the <ACE_Recusive_Thread_Mutex> interface consistent + * with the other synchronization APIs. + */ + int acquire_write (void); + + /** + * Conditionally acquire mutex (i.e., won't block). This calls + * <tryacquire> and is only here to make the + * <ACE_Recusive_Thread_Mutex> interface consistent with the other + * synchronization APIs. Returns -1 on failure. If we "failed" + * because someone else already had the lock, <errno> is set to + * <EBUSY>. + */ + int tryacquire_read (void); + + /** + * Conditionally acquire mutex (i.e., won't block). This calls + * <tryacquire> and is only here to make the + * <ACE_Recusive_Thread_Mutex> interface consistent with the other + * synchronization APIs. Returns -1 on failure. If we "failed" + * because someone else already had the lock, <errno> is set to + * <EBUSY>. + */ + int tryacquire_write (void); + + /** + * This is only here to make the <ACE_Recursive_Thread_Mutex> + * interface consistent with the other synchronization APIs. + * Assumes the caller has already acquired the mutex using one of + * the above calls, and returns 0 (success) always. + */ + int tryacquire_write_upgrade (void); + + /** + * Releases a recursive mutex (will not release mutex until all the + * nesting level drops to 0, which means the mutex is no longer + * held). + */ + int release (void); + + /// Return the id of the thread that currently owns the mutex. + ACE_thread_t get_thread_id (void); + + /** + * Return the nesting level of the recursion. When a thread has + * acquired the mutex for the first time, the nesting level == 1. + * The nesting level is incremented every time the thread acquires + * the mutex recursively. + */ + int get_nesting_level (void); + + /// Returns a reference to the recursive mutex; + ACE_recursive_thread_mutex_t &mutex (void); + + /// Returns a reference to the recursive mutex's internal mutex; + ACE_thread_mutex_t &get_nesting_mutex (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + // = This method should *not* be public (they hold no locks...) + void set_thread_id (ACE_thread_t t); + + /// Recursive mutex. + ACE_recursive_thread_mutex_t lock_; + + /// Keeps track of whether <remove> has been called yet to avoid + /// multiple <remove> calls, e.g., explicitly and implicitly in the + /// destructor. This flag isn't protected by a lock, so make sure + /// that you don't have multiple threads simultaneously calling + /// <remove> on the same object, which is a bad idea anyway... + int removed_; + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Recursive_Thread_Mutex &); + ACE_Recursive_Thread_Mutex (const ACE_Recursive_Thread_Mutex &); +}; + +#if defined (__ACE_INLINE__) +#include "ace/Recursive_Thread_Mutex.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* !ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_RECURSIVE_THREAD_MUTEX_H */ diff --git a/ace/Recursive_Thread_Mutex.inl b/ace/Recursive_Thread_Mutex.inl new file mode 100644 index 00000000000..312aa98b3c7 --- /dev/null +++ b/ace/Recursive_Thread_Mutex.inl @@ -0,0 +1,60 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE ACE_recursive_thread_mutex_t & +ACE_Recursive_Thread_Mutex::mutex (void) +{ + return lock_; +} + +ACE_INLINE ACE_thread_mutex_t & +ACE_Recursive_Thread_Mutex::get_nesting_mutex (void) +{ +#if defined (ACE_HAS_RECURSIVE_MUTEXES) + return ACE_static_cast (ACE_thread_mutex_t &, + lock_); +#else + return lock_.nesting_mutex_; +#endif /* ACE_HAS_RECURSIVE_MUTEXES */ +} + +ACE_INLINE void +ACE_Recursive_Thread_Mutex::set_thread_id (ACE_thread_t t) +{ +// ACE_TRACE ("ACE_Recursive_Thread_Mutex::set_thread_id"); +#if defined (ACE_HAS_RECURSIVE_MUTEXES) + ACE_UNUSED_ARG (t); +#else /* ! ACE_HAS_RECURSIVE_MUTEXES */ + this->lock_.owner_id_ = t; +#endif /* ! ACE_HAS_RECURSIVE_MUTEXES */ +} + +ACE_INLINE int +ACE_Recursive_Thread_Mutex::acquire_read (void) +{ + return this->acquire (); +} + +ACE_INLINE int +ACE_Recursive_Thread_Mutex::acquire_write (void) +{ + return this->acquire (); +} + +ACE_INLINE int +ACE_Recursive_Thread_Mutex::tryacquire_read (void) +{ + return this->tryacquire (); +} + +ACE_INLINE int +ACE_Recursive_Thread_Mutex::tryacquire_write (void) +{ + return this->tryacquire (); +} + +ACE_INLINE int +ACE_Recursive_Thread_Mutex::tryacquire_write_upgrade (void) +{ + return 0; +} diff --git a/ace/Reverse_Lock_T.cpp b/ace/Reverse_Lock_T.cpp new file mode 100644 index 00000000000..b2f6cef8c64 --- /dev/null +++ b/ace/Reverse_Lock_T.cpp @@ -0,0 +1,23 @@ +// $Id$ + +#ifndef ACE_REVERSE_LOCK_T_C +#define ACE_REVERSE_LOCK_T_C + +#include "ace/Reverse_Lock_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_RCSID(ace, Reverse_Lock_T, "$Id$") + +#if !defined (__ACE_INLINE__) +#include "ace/Reverse_Lock_T.inl" +#endif /* __ACE_INLINE__ */ + +template <class ACE_LOCKING_MECHANISM> +ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::~ACE_Reverse_Lock (void) +{ +} + +#endif /* ACE_REVERSE_LOCK_T_C */ diff --git a/ace/Reverse_Lock_T.h b/ace/Reverse_Lock_T.h new file mode 100644 index 00000000000..29f23b08c08 --- /dev/null +++ b/ace/Reverse_Lock_T.h @@ -0,0 +1,136 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Reverse_Lock_T.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_REVERSE_LOCK_T_H +#define ACE_REVERSE_LOCK_T_H +#include /**/ "ace/pre.h" + +#include "ace/Lock.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class ACE_Acquire_Method + * + * @brief An enum class. + * + * These enums should have been inside the reverse lock class, but + * some lame compilers cannot handle enums inside template classes. + * + * The METHOD_TYPE is used to indicate which acquire() method will be + * called on the real lock when the release() method is called on the + * reverse lock. REGULAR indicated the acquire() method, READ + * indicates the acquire_read() method, and WRITE indicates the + * acquire_write() method. Note that the try_*() methods are not + * represented here because we have to make sure that the release() + * method on the reverse lock acquires a lock on the real lock. + **/ +class ACE_Acquire_Method +{ +public: + enum METHOD_TYPE + { + ACE_REGULAR, + ACE_READ, + ACE_WRITE + }; +}; + +/** + * @class ACE_Reverse_Lock + * + * @brief A reverse (or anti) lock. + * + * This is an interesting adapter class that changes a lock into + * a reverse lock, i.e., <acquire> on this class calls <release> + * on the lock, and <release> on this class calls <acquire> on + * the lock. + * One motivation for this class is when we temporarily want to + * release a lock (which we have already acquired) but then + * reacquire it soon after. An alternative design would be to + * add a Anti_Guard or Reverse_Guard class which would <release> + * on construction and <acquire> destruction. However, there + * are *many* varieties of the Guard class and this design + * choice would lead to at least 6 new classes. One new + * ACE_Reverse_Lock class seemed more reasonable. + */ +template <class ACE_LOCKING_MECHANISM> +class ACE_Reverse_Lock : public ACE_Lock +{ +public: + + typedef ACE_LOCKING_MECHANISM ACE_LOCK; + + // = Initialization/Finalization methods. + + /// Constructor. All locking requests will be forwarded to <lock>. + ACE_Reverse_Lock (ACE_LOCKING_MECHANISM &lock, + ACE_Acquire_Method::METHOD_TYPE acquire_method = ACE_Acquire_Method::ACE_REGULAR); + + /// Destructor. If <lock_> was not passed in by the user, it will be + /// deleted. + virtual ~ACE_Reverse_Lock (void); + + // = Lock accessors. + /// Release the lock. + virtual int acquire (void); + + /// Release the lock. + virtual int tryacquire (void); + + /// Acquire the lock. + virtual int release (void); + + /// Release the lock. + virtual int acquire_read (void); + + /// Release the lock. + virtual int acquire_write (void); + + /// Release the lock. + virtual int tryacquire_read (void); + + /// Release the lock. + virtual int tryacquire_write (void); + + /// Release the lock. + virtual int tryacquire_write_upgrade (void); + + /// Explicitly destroy the lock. + virtual int remove (void); + +private: + /// The concrete locking mechanism that all the methods delegate to. + ACE_LOCKING_MECHANISM &lock_; + + /// This indicates what kind of acquire method will be called. + ACE_Acquire_Method::METHOD_TYPE acquire_method_; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Reverse_Lock_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Reverse_Lock_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Reverse_Lock_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_REVERSE_LOCK_T_H */ diff --git a/ace/Reverse_Lock_T.inl b/ace/Reverse_Lock_T.inl new file mode 100644 index 00000000000..4cc06975c51 --- /dev/null +++ b/ace/Reverse_Lock_T.inl @@ -0,0 +1,78 @@ +/* -*- C++ -*- */ +// $Id$ + +template <class ACE_LOCKING_MECHANISM> ACE_INLINE +ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::ACE_Reverse_Lock (ACE_LOCKING_MECHANISM &lock, + ACE_Acquire_Method::METHOD_TYPE acquire_method) + : lock_ (lock), + acquire_method_ (acquire_method) +{ +} + +// Explicitly destroy the lock. +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::remove (void) +{ + return this->lock_.remove (); +} + +// Release the lock. +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::acquire (void) +{ + return this->lock_.release (); +} + +// Release the lock. +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::tryacquire (void) +{ + ACE_NOTSUP_RETURN (-1); +} + +// Acquire the lock. +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::release (void) +{ + if (this->acquire_method_ == ACE_Acquire_Method::ACE_READ) + return this->lock_.acquire_read (); + else if (this->acquire_method_ == ACE_Acquire_Method::ACE_WRITE) + return this->lock_.acquire_write (); + else + return this->lock_.acquire (); +} + +// Release the lock. +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::acquire_read (void) +{ + ACE_NOTSUP_RETURN (-1); +} + +// Release the lock. +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::acquire_write (void) +{ + ACE_NOTSUP_RETURN (-1); +} + +// Release the lock. +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::tryacquire_read (void) +{ + ACE_NOTSUP_RETURN (-1); +} + +// Release the lock. +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::tryacquire_write (void) +{ + ACE_NOTSUP_RETURN (-1); +} + +// Release the lock. +template <class ACE_LOCKING_MECHANISM> ACE_INLINE int +ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::tryacquire_write_upgrade (void) +{ + ACE_NOTSUP_RETURN (-1); +} diff --git a/ace/SOCK_Acceptor.cpp b/ace/SOCK_Acceptor.cpp index 8ab06f01694..898bffd60ba 100644 --- a/ace/SOCK_Acceptor.cpp +++ b/ace/SOCK_Acceptor.cpp @@ -12,8 +12,6 @@ #include "ace/SOCK_Acceptor.i" #endif /* ACE_LACKS_INLINE_FUNCTIONS */ -#include "ace/Synch.h" - ACE_RCSID(ace, SOCK_Acceptor, "$Id$") ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Acceptor) diff --git a/ace/SOCK_Dgram.cpp b/ace/SOCK_Dgram.cpp index 6d8377a55c2..3f93f73fa92 100644 --- a/ace/SOCK_Dgram.cpp +++ b/ace/SOCK_Dgram.cpp @@ -1,6 +1,5 @@ #include "ace/SOCK_Dgram.h" #include "ace/Handle_Set.h" -#include "ace/Synch.h" #include "ace/Log_Msg.h" #include "ace/INET_Addr.h" #include "ace/ACE.h" diff --git a/ace/SOCK_Dgram_Mcast.h b/ace/SOCK_Dgram_Mcast.h index 19683059adf..078728e7a55 100644 --- a/ace/SOCK_Dgram_Mcast.h +++ b/ace/SOCK_Dgram_Mcast.h @@ -29,7 +29,8 @@ #if defined (ACE_SOCK_DGRAM_MCAST_DUMPABLE) # include "ace/Containers_T.h" -# include "ace/Synch_T.h" +# include "ace/Synch_Traits.h" +# include "ace/Thread_Mutex.h" # if !defined (ACE_SDM_LOCK) # define ACE_SDM_LOCK ACE_SYNCH_MUTEX # endif /* ACE_SDM_LOCK */ diff --git a/ace/SOCK_SEQPACK_Acceptor.cpp b/ace/SOCK_SEQPACK_Acceptor.cpp index c73d6e70985..c1cd487605e 100644 --- a/ace/SOCK_SEQPACK_Acceptor.cpp +++ b/ace/SOCK_SEQPACK_Acceptor.cpp @@ -9,7 +9,6 @@ #include "ace/SOCK_SEQPACK_Acceptor.i" #endif /* ACE_LACKS_INLINE_FUNCTIONS */ -#include "ace/Synch.h" #include "ace/Auto_Ptr.h" ACE_RCSID(ace, SOCK_SEQPACK_Acceptor, "SOCK_SEQPACK_Acceptor.cpp,v 4.30 2002/03/08 23:18:09 spark Exp") diff --git a/ace/SPIPE_Acceptor.h b/ace/SPIPE_Acceptor.h index b5e1f6ceabb..0b73d2be05d 100644 --- a/ace/SPIPE_Acceptor.h +++ b/ace/SPIPE_Acceptor.h @@ -22,8 +22,8 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#if defined (ACE_WIN32) -#include "ace/Synch.h" +#if (defined (ACE_WIN32) && defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) +#include "ace/Manual_Event.h" #endif /* ACE_WIN32 */ /** diff --git a/ace/Select_Reactor_Base.cpp b/ace/Select_Reactor_Base.cpp index 9018a2c9e53..329882049a9 100644 --- a/ace/Select_Reactor_Base.cpp +++ b/ace/Select_Reactor_Base.cpp @@ -3,7 +3,6 @@ #include "ace/Select_Reactor_Base.h" #include "ace/Reactor.h" #include "ace/Thread.h" -#include "ace/Synch_T.h" #include "ace/SOCK_Acceptor.h" #include "ace/SOCK_Connector.h" #include "ace/Timer_Heap.h" diff --git a/ace/Select_Reactor_T.cpp b/ace/Select_Reactor_T.cpp index 7391f687bc2..f62b7b85b2a 100644 --- a/ace/Select_Reactor_T.cpp +++ b/ace/Select_Reactor_T.cpp @@ -14,6 +14,9 @@ #include "ace/Thread.h" #include "ace/Timer_Heap.h" +// For timer_queue_ +#include "ace/Recursive_Thread_Mutex.h" + // @@ The latest version of SunCC can't grok the code if we put inline // function here. Therefore, we temporarily disable the code here. // We shall turn this back on once we know the problem gets fixed. diff --git a/ace/Select_Reactor_T.h b/ace/Select_Reactor_T.h index 6cbd13c2b2c..630c3cc587d 100644 --- a/ace/Select_Reactor_T.h +++ b/ace/Select_Reactor_T.h @@ -20,6 +20,8 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ +#include "ace/Lock_Adapter_T.h" + /** * @class ACE_Select_Reactor_Token_T * diff --git a/ace/Semaphore.cpp b/ace/Semaphore.cpp new file mode 100644 index 00000000000..44f3fa6e882 --- /dev/null +++ b/ace/Semaphore.cpp @@ -0,0 +1,55 @@ +// $Id$ + +#include "ace/Semaphore.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Semaphore.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (ace, + Semaphore, + "$Id$") + +ACE_ALLOC_HOOK_DEFINE(ACE_Semaphore) + +void +ACE_Semaphore::dump (void) const +{ +// ACE_TRACE ("ACE_Semaphore::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Semaphore::ACE_Semaphore (u_int count, + int type, + const ACE_TCHAR *name, + void *arg, + int max) + : removed_ (0) +{ +// ACE_TRACE ("ACE_Semaphore::ACE_Semaphore"); +#if defined(ACE_LACKS_UNNAMED_SEMAPHORE) +// if the user does not provide a name, we generate a unique name here + ACE_TCHAR iname[ACE_UNIQUE_NAME_LEN]; + if (name == 0) + ACE::unique_name (this, iname, ACE_UNIQUE_NAME_LEN); + if (ACE_OS::sema_init (&this->semaphore_, count, type, + name ? name : iname, + arg, max) != 0) +#else + if (ACE_OS::sema_init (&this->semaphore_, count, type, + name, arg, max) != 0) +#endif + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("ACE_Semaphore::ACE_Semaphore"))); +} + +ACE_Semaphore::~ACE_Semaphore (void) +{ +// ACE_TRACE ("ACE_Semaphore::~ACE_Semaphore"); + + this->remove (); +} diff --git a/ace/Semaphore.h b/ace/Semaphore.h new file mode 100644 index 00000000000..b152f2ac5a9 --- /dev/null +++ b/ace/Semaphore.h @@ -0,0 +1,178 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Semaphore.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_SEMAPHORE_H +#define ACE_SEMAPHORE_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/OS.h" + +class ACE_Time_Value; + +/** + * @class ACE_Semaphore + * + * @brief Wrapper for Dijkstra style general semaphores. + */ +class ACE_Export ACE_Semaphore +{ +public: + // = Initialization and termination. + /// Initialize the semaphore, with initial value of "count". + ACE_Semaphore (unsigned int count = 1, // By default make this unlocked. + int type = USYNC_THREAD, + const ACE_TCHAR *name = 0, + void * = 0, + int max = 0x7fffffff); + + /// Implicitly destroy the semaphore. + ~ACE_Semaphore (void); + + /** + * Explicitly destroy the semaphore. Note that only one thread + * should call this method since it doesn't protect against race + * conditions. + */ + int remove (void); + + /// Block the thread until the semaphore count becomes + /// greater than 0, then decrement it. + int acquire (void); + + /** + * Block the thread until the semaphore count becomes greater than 0 + * (at which point it is decremented) or until <tv> times out (in + * which case -1 is returned and <errno> == <ETIME>). Note that <tv> + * is assumed to be in "absolute" rather than "relative" time. The + * value of <tv> is updated upon return to show the actual + * (absolute) acquisition time. + * + * NOTE: Solaris threads do not support timed semaphores. + * Therefore, if you're running on Solaris you might want to + * consider using the ACE POSIX pthreads implementation instead, + * which can be enabled by compiling ACE with + * -DACE_HAS_PTHREADS, rather than -DACE_HAS_STHREADS or + * -DACE_HAS_POSIX_SEM. */ + int acquire (ACE_Time_Value &tv); + + /** + * If <tv> == 0 then call <acquire()> directly. Otherwise, Block + * the thread until the semaphore count becomes greater than 0 + * (at which point it is decremented) or until <tv> times out (in + * which case -1 is returned and <errno> == <ETIME>). Note that + * <*tv> is assumed to be in "absolute" rather than "relative" time. + * The value of <*tv> is updated upon return to show the actual + * (absolute) acquisition time. + * + * NOTE: Solaris threads do not support timed semaphores. + * Therefore, if you're running on Solaris you might want to + * consider using the ACE POSIX pthreads implementation instead, + * which can be enabled by compiling ACE with + * -DACE_HAS_PTHREADS, rather than -DACE_HAS_STHREADS or + * -DACE_HAS_POSIX_SEM. */ + int acquire (ACE_Time_Value *tv); + + /** + * Conditionally decrement the semaphore if count is greater than 0 + * (i.e., won't block). Returns -1 on failure. If we "failed" + * because someone else already had the lock, <errno> is set to + * <EBUSY>. + */ + int tryacquire (void); + + /// Increment the semaphore by 1, potentially unblocking a waiting + /// thread. + int release (void); + + /// Increment the semaphore by <release_count>, potentially + /// unblocking waiting threads. + int release (u_int release_count); + + /** + * Acquire semaphore ownership. This calls <acquire> and is only + * here to make the <ACE_Semaphore> interface consistent with the + * other synchronization APIs. + */ + int acquire_read (void); + + /** + * Acquire semaphore ownership. This calls <acquire> and is only + * here to make the <ACE_Semaphore> interface consistent with the + * other synchronization APIs. + */ + int acquire_write (void); + + /** + * Conditionally acquire semaphore (i.e., won't block). This calls + * <tryacquire> and is only here to make the <ACE_Semaphore> + * interface consistent with the other synchronization APIs. + * Returns -1 on failure. If we "failed" because someone else + * already had the lock, <errno> is set to <EBUSY>. + */ + int tryacquire_read (void); + + /** + * Conditionally acquire semaphore (i.e., won't block). This calls + * <tryacquire> and is only here to make the <ACE_Semaphore> + * interface consistent with the other synchronization APIs. + * Returns -1 on failure. If we "failed" because someone else + * already had the lock, <errno> is set to <EBUSY>. + */ + int tryacquire_write (void); + + /** + * This is only here to make the <ACE_Semaphore> + * interface consistent with the other synchronization APIs. + * Assumes the caller has already acquired the semaphore using one of + * the above calls, and returns 0 (success) always. + */ + int tryacquire_write_upgrade (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + /// Return the underlying lock. + const ACE_sema_t &lock (void) const; + +protected: + ACE_sema_t semaphore_; + + /// Keeps track of whether <remove> has been called yet to avoid + /// multiple <remove> calls, e.g., explicitly and implicitly in the + /// destructor. This flag isn't protected by a lock, so make sure + /// that you don't have multiple threads simultaneously calling + /// <remove> on the same object, which is a bad idea anyway... + int removed_; + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Semaphore &); + ACE_Semaphore (const ACE_Semaphore &); +}; + +#if defined (__ACE_INLINE__) +#include "ace/Semaphore.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_SEMAPHORE_H */ diff --git a/ace/Semaphore.inl b/ace/Semaphore.inl new file mode 100644 index 00000000000..0702173fc78 --- /dev/null +++ b/ace/Semaphore.inl @@ -0,0 +1,114 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE const ACE_sema_t & +ACE_Semaphore::lock (void) const +{ +// ACE_TRACE ("ACE_Semaphore::lock"); + return this->semaphore_; +} + +ACE_INLINE int +ACE_Semaphore::remove (void) +{ +// ACE_TRACE ("ACE_Semaphore::remove"); + int result = 0; + if (this->removed_ == 0) + { + this->removed_ = 1; + result = ACE_OS::sema_destroy (&this->semaphore_); + } + return result; +} + +ACE_INLINE int +ACE_Semaphore::acquire (void) +{ +// ACE_TRACE ("ACE_Semaphore::acquire"); + return ACE_OS::sema_wait (&this->semaphore_); +} + +ACE_INLINE int +ACE_Semaphore::acquire (ACE_Time_Value &tv) +{ +// ACE_TRACE ("ACE_Semaphore::acquire"); + return ACE_OS::sema_wait (&this->semaphore_, tv); +} + +ACE_INLINE int +ACE_Semaphore::acquire (ACE_Time_Value *tv) +{ +// ACE_TRACE ("ACE_Semaphore::acquire"); + return ACE_OS::sema_wait (&this->semaphore_, tv); +} + +ACE_INLINE int +ACE_Semaphore::tryacquire (void) +{ +// ACE_TRACE ("ACE_Semaphore::tryacquire"); + return ACE_OS::sema_trywait (&this->semaphore_); +} + +ACE_INLINE int +ACE_Semaphore::release (void) +{ +// ACE_TRACE ("ACE_Semaphore::release"); + return ACE_OS::sema_post (&this->semaphore_); +} + +ACE_INLINE int +ACE_Semaphore::release (u_int release_count) +{ +// ACE_TRACE ("ACE_Semaphore::release"); + return ACE_OS::sema_post (&this->semaphore_, release_count); +} + +// Acquire semaphore ownership. This calls <acquire> and is only +// here to make the <ACE_Semaphore> interface consistent with the +// other synchronization APIs. + +ACE_INLINE int +ACE_Semaphore::acquire_read (void) +{ + return this->acquire (); +} + +// Acquire semaphore ownership. This calls <acquire> and is only +// here to make the <ACE_Semaphore> interface consistent with the +// other synchronization APIs. + +ACE_INLINE int +ACE_Semaphore::acquire_write (void) +{ + return this->acquire (); +} + +// Conditionally acquire semaphore (i.e., won't block). This calls +// <tryacquire> and is only here to make the <ACE_Semaphore> +// interface consistent with the other synchronization APIs. + +ACE_INLINE int +ACE_Semaphore::tryacquire_read (void) +{ + return this->tryacquire (); +} + +// Conditionally acquire semaphore (i.e., won't block). This calls +// <tryacquire> and is only here to make the <ACE_Semaphore> +// interface consistent with the other synchronization APIs. + +ACE_INLINE int +ACE_Semaphore::tryacquire_write (void) +{ + return this->tryacquire (); +} + +// This is only here to make the <ACE_Semaphore> interface consistent +// with the other synchronization APIs. Assumes the caller has +// already acquired the semaphore using one of the above calls, and +// returns 0 (success) always. +ACE_INLINE int +ACE_Semaphore::tryacquire_write_upgrade (void) +{ + return 0; +} diff --git a/ace/Service_Repository.h b/ace/Service_Repository.h index e5049ef41a9..3942bcaed04 100644 --- a/ace/Service_Repository.h +++ b/ace/Service_Repository.h @@ -22,7 +22,7 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/Default_Constants.h" -#include "ace/Synch.h" +#include "ace/Thread_Mutex.h" class ACE_Service_Type; diff --git a/ace/Service_Repository.i b/ace/Service_Repository.i index 053ff2673a8..6872433596e 100644 --- a/ace/Service_Repository.i +++ b/ace/Service_Repository.i @@ -6,6 +6,11 @@ // Returns a count of the number of currently valid entries (counting // both resumed and suspended entries). +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) +#include "ace/Guard_T.h" +#include "ace/Thread_Mutex.h" +#endif /* ACE_MT_SAFE */ + ACE_INLINE int ACE_Service_Repository::current_size (void) const { diff --git a/ace/Service_Types.h b/ace/Service_Types.h index 2bd8119034f..10f05cfdfbd 100644 --- a/ace/Service_Types.h +++ b/ace/Service_Types.h @@ -21,9 +21,6 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/ACE.h" -#include "ace/Synch.h" - /** * @class ACE_Service_Type_Impl * diff --git a/ace/Service_Types.i b/ace/Service_Types.i index 78eb127cbfc..6df8fe65f1a 100644 --- a/ace/Service_Types.i +++ b/ace/Service_Types.i @@ -1,6 +1,8 @@ /* -*- C++ -*- */ // $Id$ +#include "ace/ACE.h" + ACE_INLINE void * ACE_Service_Type_Impl::object (void) const { @@ -20,7 +22,7 @@ ACE_Service_Type_Impl::name (const ACE_TCHAR *n) { ACE_TRACE ("ACE_Service_Type_Impl::name"); - delete [] (ACE_TCHAR *) this->name_; + ACE::strdelete (ACE_const_cast (ACE_TCHAR*, this->name_)); this->name_ = ACE::strnew (n); } diff --git a/ace/Signal.cpp b/ace/Signal.cpp index 349efeb6ec1..319931adc8a 100644 --- a/ace/Signal.cpp +++ b/ace/Signal.cpp @@ -1,6 +1,6 @@ // $Id$ -#include "ace/Synch_T.h" +#include "ace/Recursive_Thread_Mutex.h" #include "ace/Signal.h" #include "ace/Object_Manager.h" #include "ace/Log_Msg.h" diff --git a/ace/Signal.h b/ace/Signal.h index b724239712d..63e4ad05c9c 100644 --- a/ace/Signal.h +++ b/ace/Signal.h @@ -18,7 +18,7 @@ # error ace/Signal.h was #included instead of signal.h by ace/OS.h: fix!!!! #endif /* ACE_DONT_INCLUDE_ACE_SIGNAL_H */ -#include "ace/Synch.h" +#include "ace/ACE_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/ace/Singleton.cpp b/ace/Singleton.cpp index a1b19187964..366048c9416 100644 --- a/ace/Singleton.cpp +++ b/ace/Singleton.cpp @@ -13,7 +13,6 @@ #include "ace/Singleton.i" #endif /* __ACE_INLINE__ */ -#include "ace/Synch_T.h" #include "ace/Object_Manager.h" #include "ace/Log_Msg.h" #include "ace/Framework_Component.h" diff --git a/ace/Singleton.h b/ace/Singleton.h index c477fd87fc2..818e93cbc8e 100644 --- a/ace/Singleton.h +++ b/ace/Singleton.h @@ -21,7 +21,9 @@ #define ACE_SINGLETON_H #include /**/ "ace/pre.h" -#include "ace/Synch.h" +#include "ace/config-all.h" +#include "ace/TSS_T.h" +#include "ace/OS.h" // for ACE_Cleanup #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/ace/Strategies_T.cpp b/ace/Strategies_T.cpp index f7225976bf0..7ef82922f3b 100644 --- a/ace/Strategies_T.cpp +++ b/ace/Strategies_T.cpp @@ -8,7 +8,6 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/Service_Repository.h" -#include "ace/Synch.h" #include "ace/Service_Types.h" #include "ace/Thread_Manager.h" #include "ace/WFMO_Reactor.h" diff --git a/ace/Strategies_T.h b/ace/Strategies_T.h index adec2821c87..ed72a28547a 100644 --- a/ace/Strategies_T.h +++ b/ace/Strategies_T.h @@ -27,7 +27,7 @@ #include "ace/Refcountable.h" #include "ace/Hashable.h" #include "ace/Recyclable.h" - +#include "ace/Reverse_Lock_T.h" // Needed for broken linkers that can't grok long symbols. #define ACE_Refcounted_Hash_Recyclable ARHR diff --git a/ace/Synch.cpp b/ace/Synch.cpp index 9b1d8cb4561..d401c6edfd9 100644 --- a/ace/Synch.cpp +++ b/ace/Synch.cpp @@ -21,1015 +21,28 @@ ACE_RCSID (ace, #include "ace/Synch.i" #endif /* __ACE_INLINE__ */ +#include "ace/TSS_Adapter.cpp" +#include "ace/Auto_Event.cpp" +#include "ace/Manual_Event.cpp" +#include "ace/Barrier.cpp" +#include "ace/Condition_Thread_Mutex.cpp" +#include "ace/Condition_Recursive_Thread_Mutex.cpp" +#include "ace/Event.cpp" +#include "ace/Lock.cpp" +#include "ace/Mutex.cpp" +#include "ace/RW_Mutex.cpp" +#include "ace/RW_Thread_Mutex.cpp" +#include "ace/Recursive_Thread_Mutex.cpp" +#include "ace/Semaphore.cpp" +#include "ace/Thread_Mutex.cpp" +#include "ace/Thread_Semaphore.cpp" -ACE_ALLOC_HOOK_DEFINE(ACE_Null_Mutex) + //ACE_ALLOC_HOOK_DEFINE(ACE_Null_Mutex) -ACE_Lock::~ACE_Lock (void) -{ -} -ACE_Adaptive_Lock::ACE_Adaptive_Lock (void) - : lock_ (0) -{ -} -ACE_Adaptive_Lock::~ACE_Adaptive_Lock (void) -{ -} -int -ACE_Adaptive_Lock::remove (void) -{ - return this->lock_->remove (); -} -int -ACE_Adaptive_Lock::acquire (void) -{ - return this->lock_->acquire (); -} - -int -ACE_Adaptive_Lock::tryacquire (void) -{ - return this->lock_->tryacquire (); -} - -int -ACE_Adaptive_Lock::release (void) -{ - return this->lock_->release (); -} - -int -ACE_Adaptive_Lock::acquire_read (void) -{ - return this->lock_->acquire_read (); -} - -int -ACE_Adaptive_Lock::acquire_write (void) -{ - return this->lock_->acquire_write (); -} - -int -ACE_Adaptive_Lock::tryacquire_read (void) -{ - return this->lock_->tryacquire_read (); -} - -int -ACE_Adaptive_Lock::tryacquire_write (void) -{ - return this->lock_->tryacquire_write (); -} - -int -ACE_Adaptive_Lock::tryacquire_write_upgrade (void) -{ - return this->lock_->tryacquire_write_upgrade (); -} - -void -ACE_Adaptive_Lock::dump (void) const -{ -#if defined (ACE_HAS_DUMP) - // return this->lock_->dump (); -#endif /* ACE_HAS_DUMP */ -} - -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::cleanup"); - (*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; - } -} - -ACE_ALLOC_HOOK_DEFINE(ACE_Semaphore) - -void -ACE_Semaphore::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Semaphore::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -#endif /* ACE_HAS_DUMP */ -} - -ACE_Semaphore::ACE_Semaphore (u_int count, - int type, - const ACE_TCHAR *name, - void *arg, - int max) - : removed_ (0) -{ -// ACE_TRACE ("ACE_Semaphore::ACE_Semaphore"); -#if defined(ACE_LACKS_UNNAMED_SEMAPHORE) -// if the user does not provide a name, we generate a unique name here - ACE_TCHAR iname[ACE_UNIQUE_NAME_LEN]; - if (name == 0) - ACE::unique_name (this, iname, ACE_UNIQUE_NAME_LEN); - if (ACE_OS::sema_init (&this->semaphore_, count, type, - name ? name : iname, - arg, max) != 0) -#else - if (ACE_OS::sema_init (&this->semaphore_, count, type, - name, arg, max) != 0) -#endif - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("%p\n"), - ACE_LIB_TEXT ("ACE_Semaphore::ACE_Semaphore"))); -} - -ACE_Semaphore::~ACE_Semaphore (void) -{ -// ACE_TRACE ("ACE_Semaphore::~ACE_Semaphore"); - - this->remove (); -} - -ACE_ALLOC_HOOK_DEFINE(ACE_Mutex) - -void -ACE_Mutex::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Mutex::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); -#if defined (CHORUS) - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("lockname_ = %s\n"), this->lockname_)); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("process_lock_ = %x\n"), this->process_lock_)); -#endif /* CHORUS */ - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -#endif /* ACE_HAS_DUMP */ -} - -ACE_Mutex::ACE_Mutex (int type, const ACE_TCHAR *name, - ACE_mutexattr_t *arg, mode_t mode) - : -#if defined (CHORUS) || defined (ACE_HAS_PTHREADS) || defined(ACE_HAS_STHREADS) - process_lock_ (0), - lockname_ (0), -#endif /* CHORUS */ - removed_ (0) -{ - // ACE_TRACE ("ACE_Mutex::ACE_Mutex"); - - // These platforms need process-wide mutex to be in shared memory. -#if defined (CHORUS) || defined(ACE_HAS_PTHREADS) || defined (ACE_HAS_STHREADS) - if (type == USYNC_PROCESS) - { - // Let's see if the shared memory entity already exists. - ACE_HANDLE fd = ACE_OS::shm_open (name, O_RDWR | O_CREAT | O_EXCL, mode); - if (fd == ACE_INVALID_HANDLE) - { - if (errno == EEXIST) - fd = ACE_OS::shm_open (name, O_RDWR | O_CREAT, mode); - else - return; - } - else - { - // We own this shared memory object! Let's set its size. - if (ACE_OS::ftruncate (fd, - sizeof (ACE_mutex_t)) == -1) - { - ACE_OS::close (fd); - return; - } - this->lockname_ = ACE_OS::strdup (name); - if (this->lockname_ == 0) - { - ACE_OS::close (fd); - return; - } - } - - this->process_lock_ = - (ACE_mutex_t *) ACE_OS::mmap (0, - sizeof (ACE_mutex_t), - PROT_RDWR, - MAP_SHARED, - fd, - 0); - ACE_OS::close (fd); - if (this->process_lock_ == MAP_FAILED) - return; - - if (this->lockname_ - && ACE_OS::mutex_init (this->process_lock_, - type, - name, - arg) != 0) - return; - } - // It is ok to fall through into the <mutex_init> below if the - // USYNC_PROCESS flag is not enabled. -#else - ACE_UNUSED_ARG (mode); -#endif /* CHORUS */ - - if (ACE_OS::mutex_init (&this->lock_, - type, - name, - arg) != 0) - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("%p\n"), - ACE_LIB_TEXT ("ACE_Mutex::ACE_Mutex"))); -} - -ACE_Mutex::~ACE_Mutex (void) -{ -// ACE_TRACE ("ACE_Mutex::~ACE_Mutex"); - this->remove (); -} - -ACE_Event::ACE_Event (int manual_reset, - int initial_state, - int type, - const ACE_TCHAR *name, - void *arg) - : removed_ (0) -{ - if (ACE_OS::event_init (&this->handle_, - manual_reset, - initial_state, - type, - name, - arg) != 0) - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("%p\n"), - ACE_LIB_TEXT ("ACE_Event::ACE_Event"))); -} - -ACE_Event::~ACE_Event (void) -{ - this->remove (); -} - -int -ACE_Event::remove (void) -{ - int result = 0; - if (this->removed_ == 0) - { - this->removed_ = 1; - result = ACE_OS::event_destroy (&this->handle_); - } - return result; -} - -ACE_event_t -ACE_Event::handle (void) const -{ - return this->handle_; -} - -void -ACE_Event::handle (ACE_event_t new_handle) -{ - this->handle_ = new_handle; -} - -int -ACE_Event::wait (void) -{ - return ACE_OS::event_wait (&this->handle_); -} - -int -ACE_Event::wait (const ACE_Time_Value *abstime, int use_absolute_time) -{ - return ACE_OS::event_timedwait (&this->handle_, - (ACE_Time_Value *) abstime, - use_absolute_time); -} - -int -ACE_Event::signal (void) -{ - return ACE_OS::event_signal (&this->handle_); -} - -int -ACE_Event::pulse (void) -{ - return ACE_OS::event_pulse (&this->handle_); -} - -int -ACE_Event::reset (void) -{ - return ACE_OS::event_reset (&this->handle_); -} - -void -ACE_Event::dump (void) const -{ -#if defined (ACE_HAS_DUMP) - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -#endif /* ACE_HAS_DUMP */ -} - -ACE_Manual_Event::ACE_Manual_Event (int initial_state, - int type, - const char *name, - void *arg) - : ACE_Event (1, - initial_state, - type, - ACE_TEXT_CHAR_TO_TCHAR (name), - arg) -{ -} - -#if defined (ACE_HAS_WCHAR) -ACE_Manual_Event::ACE_Manual_Event (int initial_state, - int type, - const wchar_t *name, - void *arg) - : ACE_Event (1, - initial_state, - type, - ACE_TEXT_WCHAR_TO_TCHAR (name), - arg) -{ -} -#endif /* ACE_HAS_WCHAR */ - -void -ACE_Manual_Event::dump (void) const -{ -#if defined (ACE_HAS_DUMP) - ACE_Event::dump (); -#endif /* ACE_HAS_DUMP */ -} - -ACE_Auto_Event::ACE_Auto_Event (int initial_state, - int type, - const char *name, - void *arg) - : ACE_Event (0, - initial_state, - type, - ACE_TEXT_CHAR_TO_TCHAR (name), - arg) -{ -} - -#if defined (ACE_HAS_WCHAR) -ACE_Auto_Event::ACE_Auto_Event (int initial_state, - int type, - const wchar_t *name, - void *arg) - : ACE_Event (0, - initial_state, - type, - ACE_TEXT_WCHAR_TO_TCHAR (name), - arg) -{ -} -#endif /* ACE_HAS_WCHAR */ - -void -ACE_Auto_Event::dump (void) const -{ -#if defined (ACE_HAS_DUMP) - ACE_Event::dump (); -#endif /* ACE_HAS_DUMP */ -} - -#if defined (ACE_HAS_THREADS) - -ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Mutex_Guard) - -void -ACE_Thread_Semaphore::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Thread_Semaphore::dump"); - - ACE_Semaphore::dump (); -#endif /* ACE_HAS_DUMP */ -} - -ACE_Thread_Semaphore::ACE_Thread_Semaphore (u_int count, - const ACE_TCHAR *name, - void *arg, - int max) - : ACE_Semaphore (count, USYNC_THREAD, name, arg, max) -{ -// ACE_TRACE ("ACE_Thread_Semaphore::ACE_Thread_Semaphore"); -} - -#if defined (ACE_USES_OBSOLETE_GUARD_CLASSES) -void -ACE_Thread_Mutex_Guard::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Thread_Mutex_Guard::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -#endif /* ACE_HAS_DUMP */ -} -#endif /* ACE_USES_OBSOLETE_GUARD_CLASSES */ - -ACE_Recursive_Thread_Mutex::ACE_Recursive_Thread_Mutex (const ACE_TCHAR *name, - ACE_mutexattr_t *arg) - : removed_ (0) -{ - // ACE_TRACE ("ACE_Recursive_Thread_Mutex::ACE_Recursive_Thread_Mutex"); -#if defined (ACE_HAS_FSU_PTHREADS) && ! defined (ACE_WIN32) - // Initialize FSU pthreads package. If called more than once, - // pthread_init does nothing and so does no harm. - pthread_init (); -#endif /* ACE_HAS_FSU_PTHREADS && ! ACE_WIN32 */ - if (ACE_OS::recursive_mutex_init (&this->lock_, - name, - arg) == -1) - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("%p\n"), - ACE_LIB_TEXT ("recursive_mutex_init"))); -} - -ACE_ALLOC_HOOK_DEFINE(ACE_Recursive_Thread_Mutex) - -ACE_Recursive_Thread_Mutex::~ACE_Recursive_Thread_Mutex (void) -{ - // ACE_TRACE ("ACE_Recursive_Thread_Mutex::~ACE_Recursive_Thread_Mutex"); - this->remove (); -} - -int -ACE_Recursive_Thread_Mutex::remove (void) -{ -// ACE_TRACE ("ACE_Recursive_Thread_Mutex::remove"); - int result = 0; - if (this->removed_ == 0) - { - this->removed_ = 1; - result = ACE_OS::recursive_mutex_destroy (&this->lock_); - } - return result; -} - -// The counter part of the following two functions for Win32 are -// located in file Synch.i -ACE_thread_t -ACE_Recursive_Thread_Mutex::get_thread_id (void) -{ - // ACE_TRACE ("ACE_Recursive_Thread_Mutex::get_thread_id"); -#if defined (ACE_HAS_RECURSIVE_MUTEXES) - // @@ The structure CriticalSection in Win32 doesn't hold the thread - // handle of the thread that owns the lock. However it is still not - // clear at this point how to translate a thread handle to its - // corresponding thread id. - errno = ENOTSUP; - return ACE_OS::NULL_thread; -#else - ACE_thread_t owner_id; - ACE_OS::mutex_lock (&this->lock_.nesting_mutex_); - owner_id = this->lock_.owner_id_; - ACE_OS::mutex_unlock (&this->lock_.nesting_mutex_); - return owner_id; -#endif /* ACE_WIN32 */ -} - -int -ACE_Recursive_Thread_Mutex::get_nesting_level (void) -{ - // ACE_TRACE ("ACE_Recursive_Thread_Mutex::get_nesting_level"); -#if defined (ACE_HAS_WINCE) || defined (VXWORKS) || defined (ACE_PSOS) - ACE_NOTSUP_RETURN (-1); -#elif defined (ACE_HAS_RECURSIVE_MUTEXES) - // Nothing inside of a CRITICAL_SECTION object should ever be - // accessed directly. It is documented to change at any time. -# if defined (ACE_WIN64) - // Things are different on Windows XP 64-bit - return this->lock_.LockCount + 1; -# elif defined (ACE_WIN32) - // This is really a Win32-ism... - return this->lock_.RecursionCount; -# else - ACE_NOTSUP_RETURN (-1); -# endif /* ACE_HAS_RECURSIVE_MUTEXES */ -#else - int nesting_level = 0; - ACE_OS::mutex_lock (&this->lock_.nesting_mutex_); - nesting_level = this->lock_.nesting_level_; - ACE_OS::mutex_unlock (&this->lock_.nesting_mutex_); - return nesting_level; -#endif /* !ACE_HAS_WINCE */ -} - -ACE_Recursive_Thread_Mutex::ACE_Recursive_Thread_Mutex (const ACE_Recursive_Thread_Mutex &) -{ -} - -int -ACE_Recursive_Thread_Mutex::acquire (void) -{ - return ACE_OS::recursive_mutex_lock (&this->lock_); -} - -int -ACE_Recursive_Thread_Mutex::release (void) -{ - return ACE_OS::recursive_mutex_unlock (&this->lock_); -} - -int -ACE_Recursive_Thread_Mutex::tryacquire (void) -{ - return ACE_OS::recursive_mutex_trylock (&this->lock_); -} - -void -ACE_Recursive_Thread_Mutex::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Recursive_Thread_Mutex::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -#endif /* ACE_HAS_DUMP */ -} - -ACE_ALLOC_HOOK_DEFINE(ACE_Condition_Thread_Mutex) - -void -ACE_Condition_Thread_Mutex::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Condition_Thread_Mutex::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); -#if defined (ACE_WIN32) - ACE_DEBUG ((LM_DEBUG, - ACE_LIB_TEXT ("waiters = %d\n"), - this->cond_.waiters ())); -#endif /* ACE_WIN32 */ - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -#endif /* ACE_HAS_DUMP */ -} - -ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex (const ACE_Thread_Mutex &m, - const ACE_TCHAR *name, - void *arg) - : mutex_ ((ACE_Thread_Mutex &) m), - removed_ (0) -{ -#if defined (ACE_HAS_FSU_PTHREADS) -// Initialize FSU pthreads package. -// If called more than once, pthread_init does nothing -// and so does no harm. - pthread_init (); -#endif /* ACE_HAS_FSU_PTHREADS */ - -// ACE_TRACE ("ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex"); - if (ACE_OS::cond_init (&this->cond_, - (short) USYNC_THREAD, - name, - arg) != 0) - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("%p\n"), - ACE_LIB_TEXT ("ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex"))); -} - -ACE_Condition_Thread_Mutex:: -ACE_Condition_Thread_Mutex (const ACE_Thread_Mutex &m, - ACE_Condition_Attributes &attributes, - const ACE_TCHAR *name, - void *arg) - : mutex_ ((ACE_Thread_Mutex &) m), - removed_ (0) -{ -#if defined (ACE_HAS_FSU_PTHREADS) -// Initialize FSU pthreads package. -// If called more than once, pthread_init does nothing -// and so does no harm. - pthread_init (); -#endif /* ACE_HAS_FSU_PTHREADS */ - -// ACE_TRACE ("ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex"); - if (ACE_OS::cond_init (&this->cond_, attributes.attributes_, - name, arg) != 0) - ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("%p\n"), - ACE_LIB_TEXT ("ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex"))); -} - -ACE_Condition_Thread_Mutex::~ACE_Condition_Thread_Mutex (void) -{ -// ACE_TRACE ("ACE_Condition_Thread_Mutex::~ACE_Condition_Thread_Mutex"); - this->remove (); -} - -// Peform an "alertable" timed wait. If the argument <abstime> == 0 -// then we do a regular <cond_wait>, else we do a timed wait for up to -// <abstime> using the <cond_timedwait> function. - -int -ACE_Condition_Thread_Mutex::wait (void) -{ -// ACE_TRACE ("ACE_Condition_Thread_Mutex::wait"); - return ACE_OS::cond_wait (&this->cond_, &this->mutex_.lock_); -} - -int -ACE_Condition_Thread_Mutex::wait (ACE_Thread_Mutex &mutex, - const ACE_Time_Value *abstime) -{ -// ACE_TRACE ("ACE_Condition_Thread_Mutex::wait"); - return ACE_OS::cond_timedwait (&this->cond_, - &mutex.lock_, - (ACE_Time_Value *) abstime); -} - -int -ACE_Condition_Thread_Mutex::wait (const ACE_Time_Value *abstime) -{ -// ACE_TRACE ("ACE_Condition_Thread_Mutex::wait"); - return this->wait (this->mutex_, abstime); -} - -int -ACE_Condition_Thread_Mutex::signal (void) -{ -// ACE_TRACE ("ACE_Condition_Thread_Mutex::signal"); - return ACE_OS::cond_signal (&this->cond_); -} - -int -ACE_Condition_Thread_Mutex::broadcast (void) -{ -// ACE_TRACE ("ACE_Condition_Thread_Mutex::broadcast"); - return ACE_OS::cond_broadcast (&this->cond_); -} - -ACE_ALLOC_HOOK_DEFINE(ACE_Sub_Barrier) - -void -ACE_Sub_Barrier::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Sub_Barrier::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - this->barrier_finished_.dump (); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("running_threads_ = %d"), this->running_threads_)); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -#endif /* ACE_HAS_DUMP */ -} - -ACE_Sub_Barrier::ACE_Sub_Barrier (u_int count, - ACE_Thread_Mutex &lock, - const ACE_TCHAR *name, - void *arg) - : barrier_finished_ (lock, name, arg), - running_threads_ (count) -{ -// ACE_TRACE ("ACE_Sub_Barrier::ACE_Sub_Barrier"); -} - -ACE_ALLOC_HOOK_DEFINE(ACE_Barrier) -ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Barrier) -ACE_ALLOC_HOOK_DEFINE(ACE_Process_Barrier) - -void -ACE_Barrier::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Barrier::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - this->lock_.dump (); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("current_generation_ = %d"), this->current_generation_)); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ncount_ = %d"), this->count_)); - this->sub_barrier_1_.dump (); - this->sub_barrier_2_.dump (); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -#endif /* ACE_HAS_DUMP */ -} - -ACE_Barrier::ACE_Barrier (u_int count, - const ACE_TCHAR *name, - void *arg) - : lock_ (name, (ACE_mutexattr_t *) arg), - current_generation_ (0), - count_ (count), - sub_barrier_1_ (count, lock_, name, arg), - sub_barrier_2_ (count, lock_, name, arg) -{ -// ACE_TRACE ("ACE_Barrier::ACE_Barrier"); - this->sub_barrier_[0] = &this->sub_barrier_1_; - this->sub_barrier_[1] = &this->sub_barrier_2_; -} - -int -ACE_Barrier::wait (void) -{ -// ACE_TRACE ("ACE_Barrier::wait"); - ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); - - ACE_Sub_Barrier *sbp = - this->sub_barrier_[this->current_generation_]; - - // Check for shutdown... - if (sbp == 0) - return -1; - - if (sbp->running_threads_ == 1) - { - // We're the last running thread, so swap generations and tell - // all the threads waiting on the barrier to continue on their - // way. - - sbp->running_threads_ = this->count_; - // Swap generations. - this->current_generation_ = 1 - this->current_generation_; - sbp->barrier_finished_.broadcast (); - } - else - { - --sbp->running_threads_; - - // Block until all the other threads wait(). - while (sbp->running_threads_ != this->count_) - sbp->barrier_finished_.wait (); - } - - return 0; -} - -ACE_Thread_Barrier::ACE_Thread_Barrier (u_int count, const ACE_TCHAR *name) - : ACE_Barrier (count, name) -{ -// ACE_TRACE ("ACE_Thread_Barrier::ACE_Thread_Barrier"); -} - -void -ACE_Thread_Barrier::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Thread_Barrier::dump"); - ACE_Barrier::dump (); -#endif /* ACE_HAS_DUMP */ -} - -#if 0 -ACE_Process_Barrier::ACE_Process_Barrier (u_int count, const ACE_TCHAR *name) - : ACE_Barrier (count, USYNC_PROCESS, name) -{ -// ACE_TRACE ("ACE_Process_Barrier::ACE_Process_Barrier"); -} - -void -ACE_Process_Barrier::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Process_Barrier::dump"); - ACE_Barrier::dump (); -#endif /* ACE_HAS_DUMP */ -} - -template <class MUTEX> void -ACE_Process_Condition<MUTEX>::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Process_Condition<MUTEX>::dump"); - - ACE_Condition<MUTEX>::dump (); -#endif /* ACE_HAS_DUMP */ -} - -template <class MUTEX> -ACE_Process_Condition<MUTEX>::ACE_Process_Condition (MUTEX &m, - const ACE_TCHAR *name, - void *arg) - : ACE_Condition<MUTEX> (m, USYNC_PROCESS, name, arg) -{ -// ACE_TRACE ("ACE_Process_Condition<MUTEX>::ACE_Process_Condition"); -} -#endif /* 0 */ - -ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Mutex) - -void -ACE_Thread_Mutex::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Thread_Mutex::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -#endif /* ACE_HAS_DUMP */ -} - -ACE_Thread_Mutex::~ACE_Thread_Mutex (void) -{ -// ACE_TRACE ("ACE_Thread_Mutex::~ACE_Thread_Mutex"); - this->remove (); -} - -ACE_Thread_Mutex::ACE_Thread_Mutex (const ACE_TCHAR *name, ACE_mutexattr_t *arg) - : removed_ (0) -{ -// ACE_TRACE ("ACE_Thread_Mutex::ACE_Thread_Mutex"); - - if (ACE_OS::thread_mutex_init (&this->lock_, - USYNC_THREAD, - name, - arg) != 0) - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("%p\n"), - ACE_LIB_TEXT ("ACE_Thread_Mutex::ACE_Thread_Mutex"))); -} - -void -ACE_RW_Mutex::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_RW_Mutex::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -#endif /* ACE_HAS_DUMP */ -} - -ACE_RW_Mutex::ACE_RW_Mutex (int type, const ACE_TCHAR *name, void *arg) - : removed_ (0) -{ -// ACE_TRACE ("ACE_RW_Mutex::ACE_RW_Mutex"); - if (ACE_OS::rwlock_init (&this->lock_, type, name, arg) != 0) - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("%p\n"), - ACE_LIB_TEXT ("ACE_RW_Mutex::ACE_RW_Mutex"))); -} - -ACE_RW_Mutex::~ACE_RW_Mutex (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::~ACE_RW_Mutex"); - this->remove (); -} - -ACE_ALLOC_HOOK_DEFINE(ACE_RW_Thread_Mutex) - -ACE_RW_Thread_Mutex::ACE_RW_Thread_Mutex (const ACE_TCHAR *name, - void *arg) - : ACE_RW_Mutex (USYNC_THREAD, name, arg) -{ -// ACE_TRACE ("ACE_RW_Thread_Mutex::ACE_RW_Thread_Mutex"); -} - -void -ACE_RW_Thread_Mutex::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_RW_Thread_Mutex::dump"); - ACE_RW_Mutex::dump (); -#endif /* ACE_HAS_DUMP */ -} - - -//ACE_TEMPLATE_METHOD_SPECIALIZATION -int -ACE_Condition<ACE_Recursive_Thread_Mutex>::remove (void) -{ - return ACE_OS::cond_destroy (&this->cond_); -} - -void -ACE_Condition<ACE_Recursive_Thread_Mutex>::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Condition<MUTEX>::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - // No dump method for ACE_cond_t even in emulated mode. - // cond_.dump (); - this->mutex_.dump (); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -#endif /* ACE_HAS_DUMP */ -} - -//ACE_TEMPLATE_METHOD_SPECIALIZATION -ACE_Condition<ACE_Recursive_Thread_Mutex>::~ACE_Condition (void) -{ - this->remove (); -} - -//ACE_TEMPLATE_METHOD_SPECIALIZATION -ACE_Condition<ACE_Recursive_Thread_Mutex>::ACE_Condition (ACE_Recursive_Thread_Mutex &m) - : mutex_ (m) -{ - ACE_OS::cond_init (&this->cond_); -} - -//ACE_TEMPLATE_METHOD_SPECIALIZATION -int -ACE_Condition<ACE_Recursive_Thread_Mutex>::wait (const ACE_Time_Value *abstime) -{ - return this->wait (this->mutex_, abstime); -} - -//ACE_TEMPLATE_METHOD_SPECIALIZATION -int -ACE_Condition<ACE_Recursive_Thread_Mutex>::wait (ACE_Recursive_Thread_Mutex &mutex, - const ACE_Time_Value *abstime) -{ - ACE_recursive_mutex_state mutex_state_holder; - ACE_recursive_thread_mutex_t &recursive_mutex = mutex.mutex (); - - if (ACE_OS::recursive_mutex_cond_unlock (&recursive_mutex, - mutex_state_holder) == -1) - return -1; - - // We wait on the condition, specifying the nesting mutex. For platforms - // with ACE_HAS_RECURSIVE_MUTEXES, this is the recursive mutex itself, - // and is the same as recursive_mutex, above. The caller should have been - // holding the lock on entry to this method, and it is still held. - // For other platforms, this is the nesting mutex that guards the - // ACE_recursive_mutex_t internals, and recursive_mutex_cond_unlock() - // returned with the lock held, but waiters primed and waiting to be - // released. At cond_wait below, the mutex will be released. - // On return, it will be reacquired. - const int result = abstime == 0 - ? ACE_OS::cond_wait (&this->cond_, - &mutex.get_nesting_mutex ()) - : ACE_OS::cond_timedwait (&this->cond_, - &mutex.get_nesting_mutex (), - (ACE_Time_Value *) abstime); - // We are holding the mutex, whether the wait succeeded or failed. - // Stash errno (in case it failed) and then we need to reset the - // recursive mutex state to what it was on entry to this method. - // Resetting it may require a wait for another thread to release - // the ACE_recursive_thread_mutex_t if this is a platform without - // ACE_HAS_RECURSIVE_MUTEXES, and recursive_mutex_cond_relock() takes - // care of that. - { - ACE_Errno_Guard error (errno); - ACE_OS::recursive_mutex_cond_relock (&recursive_mutex, - mutex_state_holder); - } - - return result; -} - -//ACE_TEMPLATE_METHOD_SPECIALIZATION -int -ACE_Condition<ACE_Recursive_Thread_Mutex>::signal (void) -{ - return ACE_OS::cond_signal (&this->cond_); -} - -//ACE_TEMPLATE_METHOD_SPECIALIZATION -int -ACE_Condition<ACE_Recursive_Thread_Mutex>::broadcast (void) -{ - return ACE_OS::cond_broadcast (&this->cond_); -} - -//ACE_TEMPLATE_METHOD_SPECIALIZATION -ACE_Recursive_Thread_Mutex & -ACE_Condition<ACE_Recursive_Thread_Mutex>::mutex (void) -{ - return this->mutex_; -} #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) // These are only instantiated with ACE_HAS_THREADS. @@ -1049,5 +62,4 @@ template class ACE_Write_Guard<ACE_Thread_Mutex>; #pragma instantiate ACE_Write_Guard<ACE_Thread_Mutex> #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ -#endif /* ACE_HAS_THREADS */ #endif /* ACE_SYNCH_C */ diff --git a/ace/Synch.h b/ace/Synch.h index c988bb7a85b..dd6e8a3363a 100644 --- a/ace/Synch.h +++ b/ace/Synch.h @@ -16,1668 +16,34 @@ #define ACE_SYNCH_H #include /**/ "ace/pre.h" -#include "ace/ACE_export.h" +#include "ace/config-all.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/OS.h" - - -/** - * @class ACE_Lock - * - * @brief This is the abstract base class that contains the uniform - * locking API that is supported by all the ACE synchronization - * mechanisms. - * - * This class is typically used in conjunction with the - * <ACE_Lock_Adapter> in order to provide a polymorphic - * interface to the ACE synchronization mechanisms (e.g., - * <ACE_Mutex>, <ACE_Semaphore>, <ACE_RW_Mutex>, etc). Note that - * the reason that all of ACE doesn't use polymorphic locks is - * that (1) they add ~20% extra overhead for virtual function - * calls and (2) objects with virtual functions can't be placed - * into shared memory. - */ -class ACE_Export ACE_Lock -{ -public: - /// CE needs a default ctor here. - ACE_Lock (void); - - /// Noop virtual destructor - virtual ~ACE_Lock (void); - - /** - * Explicitly destroy the lock. Note that only one thread should - * call this method since it doesn't protect against race - * conditions. - */ - virtual int remove (void) = 0; - - /// Block the thread until the lock is acquired. Returns -1 on - /// failure. - virtual int acquire (void) = 0; - - /** - * Conditionally acquire the lock (i.e., won't block). Returns -1 - * on failure. If we "failed" because someone else already had the - * lock, <errno> is set to <EBUSY>. - */ - virtual int tryacquire (void) = 0; - - /// Release the lock. Returns -1 on failure. - virtual int release (void) = 0; - - /** - * Block until the thread acquires a read lock. If the locking - * mechanism doesn't support read locks then this just calls - * <acquire>. Returns -1 on failure. - */ - virtual int acquire_read (void) = 0; - - /** - * Block until the thread acquires a write lock. If the locking - * mechanism doesn't support read locks then this just calls - * <acquire>. Returns -1 on failure. - */ - virtual int acquire_write (void) = 0; - - /** - * Conditionally acquire a read lock. If the locking mechanism - * doesn't support read locks then this just calls <acquire>. - * Returns -1 on failure. If we "failed" because someone else - * already had the lock, <errno> is set to <EBUSY>. - */ - virtual int tryacquire_read (void) = 0; - - /** - * Conditionally acquire a write lock. If the locking mechanism - * doesn't support read locks then this just calls <acquire>. - * Returns -1 on failure. If we "failed" because someone else - * already had the lock, <errno> is set to <EBUSY>. - */ - virtual int tryacquire_write (void) = 0; - - /** - * Conditionally try to upgrade a lock held for read to a write lock. - * If the locking mechanism doesn't support read locks then this just - * calls <acquire>. Returns 0 on success, -1 on failure. - */ - virtual int tryacquire_write_upgrade (void) = 0; -}; - -/** - * @class ACE_Adaptive_Lock - * - * @brief An adaptive general locking class that defers the decision of - * lock type to run time. - * - * This class, as ACE_Lock, provide a set of general locking APIs. - * However, it defers our decision of what kind of lock to use - * to the run time and delegates all locking operations to the actual - * lock. Users must define a constructor in their subclass to - * initialize <lock_>. - */ -class ACE_Export ACE_Adaptive_Lock : public ACE_Lock -{ -public: - /// You must also override the destructor function to match with how - /// you construct the underneath <lock_>. - virtual ~ACE_Adaptive_Lock (void); - - // = Lock/unlock operations. - - virtual int remove (void); - virtual int acquire (void); - virtual int tryacquire (void); - virtual int release (void); - virtual int acquire_read (void); - virtual int acquire_write (void); - virtual int tryacquire_read (void); - virtual int tryacquire_write (void); - virtual int tryacquire_write_upgrade (void); - void dump (void) const; - -protected: - /** - * Create and initialize create the actual lcok used in the class. - * The default constructor simply set the <lock_> to 0 (null). You - * must overwrite this method for this class to work. - */ - ACE_Adaptive_Lock (void); - - ACE_Lock *lock_; -}; - -/** - * @class ACE_Semaphore - * - * @brief Wrapper for Dijkstra style general semaphores. - */ -class ACE_Export ACE_Semaphore -{ -public: - // = Initialization and termination. - /// Initialize the semaphore, with initial value of "count". - ACE_Semaphore (u_int count = 1, // By default make this unlocked. - int type = USYNC_THREAD, - const ACE_TCHAR *name = 0, - void * = 0, - int max = 0x7fffffff); - - /// Implicitly destroy the semaphore. - ~ACE_Semaphore (void); - - /** - * Explicitly destroy the semaphore. Note that only one thread - * should call this method since it doesn't protect against race - * conditions. - */ - int remove (void); - - /// Block the thread until the semaphore count becomes - /// greater than 0, then decrement it. - int acquire (void); - - /** - * Block the thread until the semaphore count becomes greater than 0 - * (at which point it is decremented) or until <tv> times out (in - * which case -1 is returned and <errno> == <ETIME>). Note that <tv> - * is assumed to be in "absolute" rather than "relative" time. The - * value of <tv> is updated upon return to show the actual - * (absolute) acquisition time. - * - * NOTE: Solaris threads do not support timed semaphores. - * Therefore, if you're running on Solaris you might want to - * consider using the ACE POSIX pthreads implementation instead, - * which can be enabled by compiling ACE with - * -DACE_HAS_PTHREADS, rather than -DACE_HAS_STHREADS or - * -DACE_HAS_POSIX_SEM. */ - int acquire (ACE_Time_Value &tv); - - /** - * If <tv> == 0 then call <acquire()> directly. Otherwise, Block - * the thread until the semaphore count becomes greater than 0 - * (at which point it is decremented) or until <tv> times out (in - * which case -1 is returned and <errno> == <ETIME>). Note that - * <*tv> is assumed to be in "absolute" rather than "relative" time. - * The value of <*tv> is updated upon return to show the actual - * (absolute) acquisition time. - * - * NOTE: Solaris threads do not support timed semaphores. - * Therefore, if you're running on Solaris you might want to - * consider using the ACE POSIX pthreads implementation instead, - * which can be enabled by compiling ACE with - * -DACE_HAS_PTHREADS, rather than -DACE_HAS_STHREADS or - * -DACE_HAS_POSIX_SEM. */ - int acquire (ACE_Time_Value *tv); - - /** - * Conditionally decrement the semaphore if count is greater than 0 - * (i.e., won't block). Returns -1 on failure. If we "failed" - * because someone else already had the lock, <errno> is set to - * <EBUSY>. - */ - int tryacquire (void); - - /// Increment the semaphore by 1, potentially unblocking a waiting - /// thread. - int release (void); - - /// Increment the semaphore by <release_count>, potentially - /// unblocking waiting threads. - int release (u_int release_count); - - /** - * Acquire semaphore ownership. This calls <acquire> and is only - * here to make the <ACE_Semaphore> interface consistent with the - * other synchronization APIs. - */ - int acquire_read (void); - - /** - * Acquire semaphore ownership. This calls <acquire> and is only - * here to make the <ACE_Semaphore> interface consistent with the - * other synchronization APIs. - */ - int acquire_write (void); - - /** - * Conditionally acquire semaphore (i.e., won't block). This calls - * <tryacquire> and is only here to make the <ACE_Semaphore> - * interface consistent with the other synchronization APIs. - * Returns -1 on failure. If we "failed" because someone else - * already had the lock, <errno> is set to <EBUSY>. - */ - int tryacquire_read (void); - - /** - * Conditionally acquire semaphore (i.e., won't block). This calls - * <tryacquire> and is only here to make the <ACE_Semaphore> - * interface consistent with the other synchronization APIs. - * Returns -1 on failure. If we "failed" because someone else - * already had the lock, <errno> is set to <EBUSY>. - */ - int tryacquire_write (void); - - /** - * This is only here to make the <ACE_Semaphore> - * interface consistent with the other synchronization APIs. - * Assumes the caller has already acquired the semaphore using one of - * the above calls, and returns 0 (success) always. - */ - int tryacquire_write_upgrade (void); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; - - /// Return the underlying lock. - const ACE_sema_t &lock (void) const; - -protected: - ACE_sema_t semaphore_; - - /// Keeps track of whether <remove> has been called yet to avoid - /// multiple <remove> calls, e.g., explicitly and implicitly in the - /// destructor. This flag isn't protected by a lock, so make sure - /// that you don't have multiple threads simultaneously calling - /// <remove> on the same object, which is a bad idea anyway... - int removed_; - -private: - // = Prevent assignment and initialization. - void operator= (const ACE_Semaphore &); - ACE_Semaphore (const ACE_Semaphore &); -}; - -/** - * @class ACE_Null_Semaphore - * - * @brief Implement a do nothing <ACE_Semaphore>, i.e., all the methods are - * no ops. - * - * Although the methods are no-ops, the return values are different for - * the blocking as opposed to timed acquires. The blocking version of - * acquire() is often used to serialize access to a critical section, - * whereas the timed version is often used to wait for another thread - * to update some condition or change some shared state. When using an - * ACE_Null_Semaphore, however, there's no other thread involved to - * change a state or condition (otherwise, a null semaphore would be - * inappropriate). Returning an error value signifies that the - * state or condition has not been (and can't be) changed, which is - * consistent with the behavior of the threaded case where a timeout - * occurs before the state or condition is changed. - */ -class ACE_Export ACE_Null_Semaphore -{ -public: - ACE_Null_Semaphore (u_int count = 1, // By default make this unlocked. - int type = USYNC_THREAD, - const ACE_TCHAR *name = 0, - void * = 0, - int max = 0x7fffffff); - ~ACE_Null_Semaphore (void); - /// Return 0. - int remove (void); - - /// Return 0. - int acquire (void); - - /// Return -1 with <errno> == <ETIME>. - int acquire (ACE_Time_Value &); - - /// Return -1 with <errno> == <ETIME>. - int acquire (ACE_Time_Value *); - - /// Return 0. - int tryacquire (void); - - /// Return 0. - int release (void); - - /// Return 0. - int release (size_t); - - /// Return 0. - int acquire_write (void); - - /// Return 0. - int tryacquire_write (void); - - /// Return 0. - int tryacquire_write_upgrade (void); - - /// Return 0. - int acquire_read (void); - - /// Return 0. - int tryacquire_read (void); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; -}; - -/** - * @class ACE_RW_Mutex - * - * @brief Wrapper for readers/writer locks. - * - * These are most useful for applications that have many more - * parallel readers than writers... - */ -class ACE_Export ACE_RW_Mutex -{ -public: - /// Initialize a readers/writer lock. - ACE_RW_Mutex (int type = USYNC_THREAD, - const ACE_TCHAR *name = 0, - void *arg = 0); - - /// Implicitly destroy a readers/writer lock - ~ACE_RW_Mutex (void); - - /** - * Explicitly destroy a readers/writer lock. Note that only one - * thread should call this method since it doesn't protect against - * race conditions. - */ - int remove (void); - - /// Acquire a read lock, but block if a writer hold the lock. - int acquire_read (void); - - /// Acquire a write lock, but block if any readers or a - /// writer hold the lock. - int acquire_write (void); - - /** - * Conditionally acquire a read lock (i.e., won't block). Returns - * -1 on failure. If we "failed" because someone else already had - * the lock, <errno> is set to <EBUSY>. - */ - int tryacquire_read (void); - - /// Conditionally acquire a write lock (i.e., won't block). - int tryacquire_write (void); - - /** - * Conditionally upgrade a read lock to a write lock. This only - * works if there are no other readers present, in which case the - * method returns 0. Otherwise, the method returns -1 and sets - * <errno> to <EBUSY>. Note that the caller of this method *must* - * already possess this lock as a read lock (but this condition is - * not checked by the current implementation). - */ - int tryacquire_write_upgrade (void); - - /** - * Note, for interface uniformity with other synchronization - * wrappers we include the <acquire> method. This is implemented as - * a write-lock to safe... - */ - int acquire (void); - - /** - * Note, for interface uniformity with other synchronization - * wrappers we include the <tryacquire> method. This is implemented - * as a write-lock to be safe... Returns -1 on failure. If we - * "failed" because someone else already had the lock, <errno> is - * set to <EBUSY>. - */ - int tryacquire (void); - - /// Unlock a readers/writer lock. - int release (void); - - /// Return the underlying lock. - const ACE_rwlock_t &lock (void) const; - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; - -protected: - /// Readers/writer lock. - ACE_rwlock_t lock_; - - /// Keeps track of whether <remove> has been called yet to avoid - /// multiple <remove> calls, e.g., explicitly and implicitly in the - /// destructor. This flag isn't protected by a lock, so make sure - /// that you don't have multiple threads simultaneously calling - /// <remove> on the same object, which is a bad idea anyway... - int removed_; - -private: - // = Prevent assignment and initialization. - void operator= (const ACE_RW_Mutex &); - ACE_RW_Mutex (const ACE_RW_Mutex &); -}; - -/** - * @class ACE_Mutex - * - * @brief <ACE_Mutex> wrapper (valid in same process or across - * processes (depending on TYPE flag)). - */ -class ACE_Export ACE_Mutex -{ -public: - /// Initialize the mutex. - ACE_Mutex (int type = USYNC_THREAD, - const ACE_TCHAR *name = 0, - ACE_mutexattr_t *arg = 0, - mode_t mode = ACE_DEFAULT_FILE_PERMS); - - /// Implicitly destroy the mutex. - ~ACE_Mutex (void); - - /** - * Explicitly destroy the mutex. Note that only one thread should - * call this method since it doesn't protect against race - * conditions. - */ - int remove (void); - - /// Acquire lock ownership (wait on queue if necessary). - int acquire (void); - - /** - * Block the thread until the mutex is acquired or <tv> times out, - * in which case -1 is returned and <errno> == <ETIME>. Note that - * <tv> is assumed to be in "absolute" rather than "relative" time. - * The value of <tv> is updated upon return to show the actual - * (absolute) acquisition time. - */ - int acquire (ACE_Time_Value &tv); - - /** - * If <tv> == 0 then call <acquire()> directly. Otherwise, block - * the thread until the mutex is acquired or <tv> times out, in - * which case -1 is returned and <errno> == <ETIME>. Note that - * <*tv> is assumed to be in "absolute" rather than "relative" time. - * The value of <*tv> is updated upon return to show the actual - * (absolute) acquisition time. */ - int acquire (ACE_Time_Value *tv); - - /** - * Conditionally acquire lock (i.e., don't wait on queue). Returns - * -1 on failure. If we "failed" because someone else already had - * the lock, <errno> is set to <EBUSY>. - */ - int tryacquire (void); - - /// Release lock and unblock a thread at head of queue. - int release (void); - - /** - * Acquire mutex ownership. This calls <acquire> and is only - * here to make the <ACE_Mutex> interface consistent with the - * other synchronization APIs. - */ - int acquire_read (void); - - /** - * Acquire mutex ownership. This calls <acquire> and is only - * here to make the <ACE_Mutex> interface consistent with the - * other synchronization APIs. - */ - int acquire_write (void); - - /** - * Conditionally acquire mutex (i.e., won't block). This calls - * <tryacquire> and is only here to make the <ACE_Mutex> interface - * consistent with the other synchronization APIs. Returns -1 on - * failure. If we "failed" because someone else already had the - * lock, <errno> is set to <EBUSY>. - */ - int tryacquire_read (void); - - /** - * Conditionally acquire mutex (i.e., won't block). This calls - * <tryacquire> and is only here to make the <ACE_Mutex> interface - * consistent with the other synchronization APIs. Returns -1 on - * failure. If we "failed" because someone else already had the - * lock, <errno> is set to <EBUSY>. - */ - int tryacquire_write (void); - - /** - * This is only here for consistency with the other synchronization - * APIs and usability with Lock adapters. Assumes the caller already has - * acquired the mutex and returns 0 in all cases. - */ - int tryacquire_write_upgrade (void); - - /// Return the underlying mutex. - const ACE_mutex_t &lock (void) const; - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; - - // = This should be protected but some C++ compilers complain... -public: -#if defined (CHORUS) || defined(ACE_HAS_PTHREADS) || defined(ACE_HAS_STHREADS) - /// This lock resides in shared memory. - ACE_mutex_t *process_lock_; - - /** - * Remember the name of the mutex if we created it so we can unlink - * it when we go away (only the actor that initialized the memory - * can destroy it). - */ - const ACE_TCHAR *lockname_; -#endif /* CHORUS || ACE_HAS_PTHREADS */ - - /// Mutex type supported by the OS. - ACE_mutex_t lock_; - - /// Keeps track of whether <remove> has been called yet to avoid - /// multiple <remove> calls, e.g., explicitly and implicitly in the - /// destructor. This flag isn't protected by a lock, so make sure - /// that you don't have multiple threads simultaneously calling - /// <remove> on the same object, which is a bad idea anyway... - int removed_; - -private: - // = Prevent assignment and initialization. - void operator= (const ACE_Mutex &); - ACE_Mutex (const ACE_Mutex &); -}; - -/** - * @class ACE_Null_Barrier - * - * @brief Implements "NULL barrier synchronization". - */ -class ACE_Export ACE_Null_Barrier -{ -public: - /// Initialize the barrier to synchronize <count> threads. - ACE_Null_Barrier (u_int, - const char * = 0, - void * = 0); - - /// Default dtor. - ~ACE_Null_Barrier (void); - - /// Block the caller until all <count> threads have called <wait> and - /// then allow all the caller threads to continue in parallel. - int wait (void); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; - -private: - // = Prevent assignment and initialization. - void operator= (const ACE_Null_Barrier &); - ACE_Null_Barrier (const ACE_Null_Barrier &); -}; - -/** - * @class ACE_Null_Mutex - * - * @brief Implement a do nothing <ACE_Mutex>, i.e., all the methods are - * no ops. - */ -class ACE_Export ACE_Null_Mutex -{ -public: - ACE_Null_Mutex (const ACE_TCHAR * = 0); - ~ACE_Null_Mutex (void); - /// Return 0. - int remove (void); - - /// Return 0. - int acquire (void); - - /// Return -1 with <errno> == <ETIME>. - int acquire (ACE_Time_Value &timeout); - - /// Return -1 with <errno> == <ETIME>. - int acquire (ACE_Time_Value *timeout); - - /// Return 0. - int tryacquire (void); - - /// Return 0. - int release (void); - - /// Return 0. - int acquire_write (void); - - /// Return 0. - int tryacquire_write (void); - - /// Return 0. - int tryacquire_write_upgrade (void); - - /// Return 0. - int acquire_read (void); - - /// Return 0. - int tryacquire_read (void); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; - - int lock_; // A dummy lock. -}; - -class ACE_Export ACE_Noop_Token : public ACE_Null_Mutex -{ -public: - /// Queueing strategy - enum QUEUEING_STRATEGY - { - FIFO = -1, - LIFO = 0 - }; - - /// Get queueing strategy. - int queueing_strategy (void); - - /// Set queueing strategy. - void queueing_strategy (int queueing_strategy); - - int renew (int = 0, ACE_Time_Value * =0); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; -}; - -/** - * @class ACE_Null_Condition - * - * @brief Implement a do nothing <ACE_Condition> variable wrapper, - * i.e., all methods are no ops. This class is necessary since - * some C++ compilers are *very* lame... - */ -class ACE_Export ACE_Null_Condition -{ -public: - ACE_Null_Condition (const ACE_Null_Mutex &m, - const ACE_TCHAR * = 0, - void * = 0); - ~ACE_Null_Condition (void); - - /// Returns 0. - int remove (void); - - /// Returns -1 with <errno> == <ETIME>. - int wait (const ACE_Time_Value * = 0); - - /// Returns -1 with <errno> == <ETIME>. - int wait (ACE_Null_Mutex &m, - const ACE_Time_Value * = 0); - - /// Returns 0. - int signal (void); - - /// Returns 0. - int broadcast (void); - ACE_Null_Mutex &mutex (void); - - /// Dump the state of an object. - void dump (void) const; - - // ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. - -protected: - ACE_Null_Mutex &mutex_; // Reference to mutex lock. - -private: - // = Prevent assignment and initialization. - void operator= (const ACE_Null_Condition &); - ACE_Null_Condition (const ACE_Null_Condition &); -}; - -#if defined (ACE_USES_OBSOLETE_GUARD_CLASSES) -/** - * @class ACE_Null_Mutex_Guard - * - * @brief This data structure is meant to be used within a method or - * function... It performs automatic aquisition and release of - * an ACE_Null_Mutex. - * - * This class is obsolete and should be replaced by - * ACE_Guard<ACE_Null_Mutex>. - */ -class ACE_Export ACE_Null_Mutex_Guard -{ -public: - ACE_Null_Mutex_Guard (ACE_Null_Mutex &); - ~ACE_Null_Mutex_Guard (void); - int remove (void); - int locked (void); - int acquire (void); - int tryacquire (void); - int release (void); - void dump (void) const; - -private: - // = Prevent assignment and initialization. - void operator= (const ACE_Null_Mutex_Guard &); - ACE_Null_Mutex_Guard (const ACE_Null_Mutex_Guard &); -}; -#endif /* ACE_USES_OBSOLETE_GUARD_CLASSES */ - -/** - * @class ACE_TSS_Adapter - * - * @brief 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. - * - * 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_. - */ -class ACE_Export ACE_TSS_Adapter -{ -public: - /// Initialize the adapter. - ACE_TSS_Adapter (void *object, ACE_THR_DEST f); - - /// Default dtor. - ~ACE_TSS_Adapter (void); - - /// Perform the cleanup operation. - void cleanup (void); - -//private: - - /// The real TS object. - void *ts_obj_; - - /// The real cleanup routine for ts_obj; - ACE_THR_DEST func_; -}; - -/** - * @class ACE_Event - * - * @brief A wrapper around the Win32 event locking mechanism. - * - * Portable implementation of an Event mechanism, which is native to - * Win32, but must be emulated on UNIX. All platforms support - * process-scope locking support. However, only Win32 platforms - * support global naming and system-scope locking support. - */ -class ACE_Export ACE_Event -{ -public: - /// Constructor that creates event. - ACE_Event (int manual_reset = 0, - int initial_state = 0, - int type = USYNC_THREAD, - const ACE_TCHAR *name = 0, - void *arg = 0); - - /// Implicitly destroy the event variable. - ~ACE_Event (void); - - /** - * Explicitly destroy the event variable. Note that only one thread - * should call this method since it doesn't protect against race - * conditions. - */ - int remove (void); - - /// Underlying handle to event. - ACE_event_t handle (void) const; - - /** - * Set the underlying handle to event. Note that this method assumes - * ownership of the <handle> and will close it down in <remove>. If - * you want the <handle> to stay open when <remove> is called make - * sure to call <dup> on the <handle> before closing it. You are - * responsible for the closing the existing <handle> before - * overwriting it. - */ - void handle (ACE_event_t new_handle); - - /** - * if MANUAL reset - * sleep till the event becomes signaled - * event remains signaled after wait() completes. - * else AUTO reset - * sleep till the event becomes signaled - * event resets wait() completes. - */ - int wait (void); - - /// Same as wait() above, but this one can be timed - /// <abstime> is absolute time-of-day if if <use_absolute_time> - /// is non-0, else it is relative time. - int wait (const ACE_Time_Value *abstime, - int use_absolute_time = 1); - - /** - * if MANUAL reset - * wake up all waiting threads - * set to signaled state - * else AUTO reset - * if no thread is waiting, set to signaled state - * if thread(s) are waiting, wake up one waiting thread and - * reset event - */ - int signal (void); - - /** - * if MANUAL reset - * wakeup all waiting threads and - * reset event - * else AUTO reset - * wakeup one waiting thread (if present) and - * reset event - */ - int pulse (void); - - /// Set to nonsignaled state. - int reset (void); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks - ACE_ALLOC_HOOK_DECLARE; - -protected: - /// The underlying handle. - ACE_event_t handle_; - - /// Keeps track of whether <remove> has been called yet to avoid - /// multiple <remove> calls, e.g., explicitly and implicitly in the - /// destructor. This flag isn't protected by a lock, so make sure - /// that you don't have multiple threads simultaneously calling - /// <remove> on the same object, which is a bad idea anyway... - int removed_; - -private: - // = Prevent copying. - ACE_Event (const ACE_Event& event); - const ACE_Event &operator= (const ACE_Event &rhs); -}; - -/** - * @class ACE_Manual_Event - * - * @brief Manual Events. - * - * Specialization of Event mechanism which wakes up all waiting - * thread on <signal>. All platforms support process-scope locking - * support. However, only Win32 platforms support global naming and - * system-scope locking support. - */ -class ACE_Export ACE_Manual_Event : public ACE_Event -{ -public: - /// constructor which will create manual event - ACE_Manual_Event (int initial_state = 0, - int type = USYNC_THREAD, - const char *name = 0, - void *arg = 0); - -#if defined (ACE_HAS_WCHAR) - /// constructor which will create manual event (wchar_t version) - ACE_Manual_Event (int initial_state, - int type, - const wchar_t *name, - void *arg = 0); -#endif /* ACE_HAS_WCHAR */ - - /// Default dtor. - ~ACE_Manual_Event (void); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks - ACE_ALLOC_HOOK_DECLARE; -}; - -/** - * @class ACE_Auto_Event - * - * @brief Auto Events. - * - * Specialization of Event mechanism which wakes up one waiting - * thread on <signal>. All platforms support process-scope locking - * support. However, only Win32 platforms support global naming and - * system-scope locking support. - */ -class ACE_Export ACE_Auto_Event : public ACE_Event -{ -public: - /// constructor which will create auto event - ACE_Auto_Event (int initial_state = 0, - int type = USYNC_THREAD, - const char *name = 0, - void *arg = 0); - -#if defined (ACE_HAS_WCHAR) - /// constructor which will create auto event (wchar_t version) - ACE_Auto_Event (int initial_state, - int type, - const wchar_t *name, - void *arg = 0); -#endif /* ACE_HAS_WCHAR */ - - /// Default dtor. - ~ACE_Auto_Event (void); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks - ACE_ALLOC_HOOK_DECLARE; -}; - -// ACE platform supports some form of threading. -#if !defined (ACE_HAS_THREADS) -/** - * @class ACE_Barrier - * - * @brief This is a no-op to make ACE "syntactically consistent." - */ -class ACE_Barrier -{ -public: - ACE_Barrier (u_int, const ACE_TCHAR * = 0, void * = 0) {} - ~ACE_Barrier (void) {} - int wait (void) { ACE_NOTSUP_RETURN (-1); } - void dump (void) const {} -}; -#else - /** - * @class ACE_Thread_Mutex - * - * @brief ACE_Thread_Mutex wrapper (only valid for threads in the same - * process). - * - * This implementation is optimized for locking threads that are - * in the same process. It maps to <CRITICAL_SECTION>s on NT - * and <ACE_mutex_t> with <type> set to <USYNC_THREAD> on UNIX. - * ACE_Thread_Mutex is recursive on some platforms (like - * Win32). However, on most platforms (like Solaris) it is not - * recursive. To be totally safe and portable, developers - * should use <ACE_Recursive_Thread_Mutex> when they need a - * recursive mutex. - */ -class ACE_Export ACE_Thread_Mutex -{ - friend class ACE_Condition_Thread_Mutex; -public: - /// Constructor. - ACE_Thread_Mutex (const ACE_TCHAR *name = 0, - ACE_mutexattr_t *attributes = 0); - - /// Implicitly destroy the mutex. - ~ACE_Thread_Mutex (void); - - /** - * Explicitly destroy the mutex. Note that only one thread should - * call this method since it doesn't protect against race - * conditions. - */ - int remove (void); - - /// Acquire lock ownership (wait on queue if necessary). - int acquire (void); - - /** - * Block the thread until we acquire the mutex or until <tv> times - * out, in which case -1 is returned with <errno> == <ETIME>. Note - * that <tv> is assumed to be in "absolute" rather than "relative" - * time. The value of <tv> is updated upon return to show the - * actual (absolute) acquisition time. - */ - int acquire (ACE_Time_Value &tv); - - /** - * If <tv> == 0 the call <acquire()> directly. Otherwise, Block the - * thread until we acquire the mutex or until <tv> times out, in - * which case -1 is returned with <errno> == <ETIME>. Note that - * <*tv> is assumed to be in "absolute" rather than "relative" time. - * The value of <*tv> is updated upon return to show the actual - * (absolute) acquisition time. - */ - int acquire (ACE_Time_Value *tv); - - /** - * Conditionally acquire lock (i.e., don't wait on queue). Returns - * -1 on failure. If we "failed" because someone else already had - * the lock, <errno> is set to <EBUSY>. - */ - int tryacquire (void); - - /// Release lock and unblock a thread at head of queue. - int release (void); - - /** - * Acquire mutex ownership. This calls <acquire> and is only here - * to make the <ACE_Thread_Mutex> interface consistent with the - * other synchronization APIs. - */ - int acquire_read (void); - - /** - * Acquire mutex ownership. This calls <acquire> and is only here - * to make the <ACE_Thread_Mutex> interface consistent with the - * other synchronization APIs. - */ - int acquire_write (void); - - /** - * Conditionally acquire mutex (i.e., won't block). This calls - * <tryacquire> and is only here to make the <ACE_Thread_Mutex> - * interface consistent with the other synchronization APIs. - * Returns -1 on failure. If we "failed" because someone else - * already had the lock, <errno> is set to <EBUSY>. - */ - int tryacquire_read (void); - - /** - * Conditionally acquire mutex (i.e., won't block). This calls - * <tryacquire> and is only here to make the <ACE_Thread_Mutex> - * interface consistent with the other synchronization APIs. - * Returns -1 on failure. If we "failed" because someone else - * already had the lock, <errno> is set to <EBUSY>. - */ - int tryacquire_write (void); - - /** - * This is only here to make the <ACE_Thread_Mutex> - * interface consistent with the other synchronization APIs. - * Assumes the caller has already acquired the mutex using one of - * the above calls, and returns 0 (success) always. - */ - int tryacquire_write_upgrade (void); - - /// Return the underlying mutex. - const ACE_thread_mutex_t &lock (void) const; - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; - - // protected: - /// Mutex type that supports single-process locking efficiently. - ACE_thread_mutex_t lock_; - - /// Keeps track of whether <remove> has been called yet to avoid - /// multiple <remove> calls, e.g., explicitly and implicitly in the - /// destructor. This flag isn't protected by a lock, so make sure - /// that you don't have multiple threads simultaneously calling - /// <remove> on the same object, which is a bad idea anyway... - int removed_; - -private: - // = Prevent assignment and initialization. - void operator= (const ACE_Thread_Mutex &); - ACE_Thread_Mutex (const ACE_Thread_Mutex &); -}; - -#if defined (ACE_USES_OBSOLETE_GUARD_CLASSES) -/** - * @class ACE_Thread_Mutex_Guard - * - * @brief This data structure is meant to be used within a method or - * function... It performs automatic aquisition and release of - * an <ACE_Thread_Mutex>. - * - * This class is obsolete and should be replaced by - * ACE_Guard<ACE_Thread_Mutex>. - */ -class ACE_Export ACE_Thread_Mutex_Guard -{ -public: - /// Implicitly and automatically acquire the lock. - ACE_Thread_Mutex_Guard (ACE_Thread_Mutex &m, int block = 1); - - /// Implicitly release the lock. - ~ACE_Thread_Mutex_Guard (void); - - /// 1 if locked, 0 if couldn't acquire the lock (errno will contain - /// the reason for this). - int locked (void); - - /** - * Explicitly release the lock. Note that only one thread should - * call this method since it doesn't protect against race - * conditions. - */ - int remove (void); - - /// Explicitly acquire the lock. - int acquire (void); - - /** - * Conditionally acquire the lock (i.e., won't block). Returns -1 - * on failure. If we "failed" because someone else already had the - * lock, <errno> is set to <EBUSY>. - */ - int tryacquire (void); - - /// Explicitly release the lock. - int release (void); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; - -protected: - /// Reference to the mutex. - ACE_Thread_Mutex &lock_; - - /// Keeps track of whether we acquired the lock or failed. - int owner_; - -private: - // = Prevent assignment and initialization. - void operator= (const ACE_Thread_Mutex_Guard &); - ACE_Thread_Mutex_Guard (const ACE_Thread_Mutex_Guard &); -}; -#endif /* ACE_USES_OBSOLETE_GUARD_CLASSES */ - -class ACE_Export ACE_Condition_Attributes -{ -public: - /// Constructor - ACE_Condition_Attributes (int type = ACE_DEFAULT_SYNCH_TYPE); - - /// Destructor - ~ACE_Condition_Attributes (void); - -private: - friend class ACE_Condition_Thread_Mutex; - - /// The attributes - ACE_condattr_t attributes_; - -private: - // = Prevent assignment and initialization. - void operator= (const ACE_Condition_Attributes &); - ACE_Condition_Attributes (const ACE_Condition_Attributes &); -}; - -/** - * @class ACE_Condition_Thread_Mutex - * - * @brief ACE_Condition variable wrapper written using ACE_Mutexes This - * allows threads to block until shared data changes state. - * A condition variable enables threads to atomically block and - * test the condition under the protection of a mutual exclu- - * sion lock (mutex) until the condition is satisfied. That is, - * the mutex must have been held by the thread before calling - * wait or signal on the condition. If the condition is false, - * a thread blocks on a condition variable and atomically - * releases the mutex that is waiting for the condition to - * change. If another thread changes the condition, it may wake - * up waiting threads by signaling the associated condition - * variable. The waiting threads, upon awakening, reacquire the - * mutex and re-evaluate the condition. - * - * This should be an instantiation of ACE_Condition but problems - * with compilers precludes this... - */ -class ACE_Export ACE_Condition_Thread_Mutex -{ -public: - /// Initialize the condition variable. - ACE_Condition_Thread_Mutex (const ACE_Thread_Mutex &m, - const ACE_TCHAR *name = 0, - void *arg = 0); - - /// Initialize the condition variable. - ACE_Condition_Thread_Mutex (const ACE_Thread_Mutex &m, - ACE_Condition_Attributes &attributes, - const ACE_TCHAR *name = 0, - void *arg = 0); - - /// Implicitly destroy the condition variable. - ~ACE_Condition_Thread_Mutex (void); - - /** - * Explicitly destroy the condition variable. Note that only one - * thread should call this method since it doesn't protect against - * race conditions. - */ - int remove (void); - - /** - * Block on condition, or until absolute time-of-day has passed. If - * abstime == 0 use "blocking" <wait> semantics. Else, if <abstime> - * != 0 and the call times out before the condition is signaled - * <wait> returns -1 and sets errno to ETIME. - */ - int wait (const ACE_Time_Value *abstime); - - /// Block on condition. - int wait (void); - - /** - * Block on condition or until absolute time-of-day has passed. If - * abstime == 0 use "blocking" wait() semantics on the <mutex> - * passed as a parameter (this is useful if you need to store the - * <Condition> in shared memory). Else, if <abstime> != 0 and the - * call times out before the condition is signaled <wait> returns -1 - * and sets errno to ETIME. - */ - int wait (ACE_Thread_Mutex &mutex, const ACE_Time_Value *abstime = 0); - - /// Signal one waiting thread. - int signal (void); - - /// Signal *all* waiting threads. - int broadcast (void); - - /// Returns a reference to the underlying mutex; - ACE_Thread_Mutex &mutex (void); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; - -protected: - /// Condition variable. - ACE_cond_t cond_; - - /// Reference to mutex lock. - ACE_Thread_Mutex &mutex_; - - /// Keeps track of whether <remove> has been called yet to avoid - /// multiple <remove> calls, e.g., explicitly and implicitly in the - /// destructor. This flag isn't protected by a lock, so make sure - /// that you don't have multiple threads simultaneously calling - /// <remove> on the same object, which is a bad idea anyway... - int removed_; - -private: - // = Prevent assignment and initialization. - void operator= (const ACE_Condition_Thread_Mutex &); - ACE_Condition_Thread_Mutex (const ACE_Condition_Thread_Mutex &); -}; - -/** - * @class ACE_Recursive_Thread_Mutex - * - * @brief Implement a C++ wrapper that allows nested acquisition and - * release of a mutex that occurs in the same thread. - */ -class ACE_Export ACE_Recursive_Thread_Mutex -{ -public: - /// Initialize a recursive mutex. - ACE_Recursive_Thread_Mutex (const ACE_TCHAR *name = 0, - ACE_mutexattr_t *arg = 0); - - /// Implicitly release a recursive mutex. - ~ACE_Recursive_Thread_Mutex (void); - - /** - * Implicitly release a recursive mutex. Note that only one thread - * should call this method since it doesn't protect against race - * conditions. - */ - int remove (void); - - /** - * Acquire a recursive mutex (will increment the nesting level and - * not deadmutex if the owner of the mutex calls this method more - * than once). - */ - int acquire (void); - - /** - * Conditionally acquire a recursive mutex (i.e., won't block). - * Returns -1 on failure. If we "failed" because someone else - * already had the lock, <errno> is set to <EBUSY>. - */ - int tryacquire (void); - - /** - * Acquire mutex ownership. This calls <acquire> and is only - * here to make the <ACE_Recusive_Thread_Mutex> interface consistent - * with the other synchronization APIs. - */ - int acquire_read (void); - - /** - * Acquire mutex ownership. This calls <acquire> and is only - * here to make the <ACE_Recusive_Thread_Mutex> interface consistent - * with the other synchronization APIs. - */ - int acquire_write (void); - - /** - * Conditionally acquire mutex (i.e., won't block). This calls - * <tryacquire> and is only here to make the - * <ACE_Recusive_Thread_Mutex> interface consistent with the other - * synchronization APIs. Returns -1 on failure. If we "failed" - * because someone else already had the lock, <errno> is set to - * <EBUSY>. - */ - int tryacquire_read (void); - - /** - * Conditionally acquire mutex (i.e., won't block). This calls - * <tryacquire> and is only here to make the - * <ACE_Recusive_Thread_Mutex> interface consistent with the other - * synchronization APIs. Returns -1 on failure. If we "failed" - * because someone else already had the lock, <errno> is set to - * <EBUSY>. - */ - int tryacquire_write (void); - - /** - * This is only here to make the <ACE_Recursive_Thread_Mutex> - * interface consistent with the other synchronization APIs. - * Assumes the caller has already acquired the mutex using one of - * the above calls, and returns 0 (success) always. - */ - int tryacquire_write_upgrade (void); - - /** - * Releases a recursive mutex (will not release mutex until all the - * nesting level drops to 0, which means the mutex is no longer - * held). - */ - int release (void); - - /// Return the id of the thread that currently owns the mutex. - ACE_thread_t get_thread_id (void); - - /** - * Return the nesting level of the recursion. When a thread has - * acquired the mutex for the first time, the nesting level == 1. - * The nesting level is incremented every time the thread acquires - * the mutex recursively. - */ - int get_nesting_level (void); - - /// Returns a reference to the recursive mutex; - ACE_recursive_thread_mutex_t &mutex (void); - - /// Returns a reference to the recursive mutex's internal mutex; - ACE_thread_mutex_t &get_nesting_mutex (void); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; - -protected: - // = This method should *not* be public (they hold no locks...) - void set_thread_id (ACE_thread_t t); - - /// Recursive mutex. - ACE_recursive_thread_mutex_t lock_; - - /// Keeps track of whether <remove> has been called yet to avoid - /// multiple <remove> calls, e.g., explicitly and implicitly in the - /// destructor. This flag isn't protected by a lock, so make sure - /// that you don't have multiple threads simultaneously calling - /// <remove> on the same object, which is a bad idea anyway... - int removed_; - -private: - // = Prevent assignment and initialization. - void operator= (const ACE_Recursive_Thread_Mutex &); - ACE_Recursive_Thread_Mutex (const ACE_Recursive_Thread_Mutex &); -}; - -/** - * @class ACE_RW_Thread_Mutex - * - * @brief Wrapper for readers/writer locks that exist within a process. - */ -class ACE_Export ACE_RW_Thread_Mutex : public ACE_RW_Mutex -{ -public: - ACE_RW_Thread_Mutex (const ACE_TCHAR *name = 0, - void *arg = 0); - - /// Default dtor. - ~ACE_RW_Thread_Mutex (void); - - /** - * Conditionally upgrade a read lock to a write lock. This only - * works if there are no other readers present, in which case the - * method returns 0. Otherwise, the method returns -1 and sets - * <errno> to <EBUSY>. Note that the caller of this method *must* - * already possess this lock as a read lock (but this condition is - * not checked by the current implementation). - */ - int tryacquire_write_upgrade (void); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; -}; - -/** - * @class ACE_Thread_Semaphore - * - * @brief Wrapper for Dijkstra style general semaphores that work - * only within one process. - */ -class ACE_Export ACE_Thread_Semaphore : public ACE_Semaphore -{ -public: - /// Initialize the semaphore, with an initial value of <count>, - /// maximum value of <max>, and unlocked by default. - ACE_Thread_Semaphore (u_int count = 1, // By default make this unlocked. - const ACE_TCHAR *name = 0, - void * = 0, - int max = 0x7FFFFFFF); - - /// Default dtor. - ~ACE_Thread_Semaphore (void); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; -}; - -struct ACE_Export ACE_Sub_Barrier -{ - // = Initialization. - ACE_Sub_Barrier (u_int count, - ACE_Thread_Mutex &lock, - const ACE_TCHAR *name = 0, - void *arg = 0); - - ~ACE_Sub_Barrier (void); - - /// True if this generation of the barrier is done. - ACE_Condition_Thread_Mutex barrier_finished_; - - /// Number of threads that are still running. - int running_threads_; - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; -}; - -/** - * @class ACE_Barrier - * - * @brief Implements "barrier synchronization". - * - * This class allows <count> number of threads to synchronize - * their completion of (one round of) a task, which is known as - * "barrier synchronization". After all the threads call <wait()> - * on the barrier they are all atomically released and can begin a new - * round. - * - * This implementation uses a "sub-barrier generation numbering" - * scheme to avoid overhead and to ensure that all threads wait to - * leave the barrier correct. This code is based on an article from - * SunOpsis Vol. 4, No. 1 by Richard Marejka - * (Richard.Marejka@canada.sun.com). - */ -class ACE_Export ACE_Barrier -{ -public: - /// Initialize the barrier to synchronize <count> threads. - ACE_Barrier (u_int count, - const ACE_TCHAR *name = 0, - void *arg = 0); - - /// Default dtor. - ~ACE_Barrier (void); - - /// Block the caller until all <count> threads have called <wait> and - /// then allow all the caller threads to continue in parallel. - int wait (void); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; - -protected: - /// Serialize access to the barrier state. - ACE_Thread_Mutex lock_; - - /// Either 0 or 1, depending on whether we are the first generation - /// of waiters or the next generation of waiters. - int current_generation_; - - /// Total number of threads that can be waiting at any one time. - int count_; - - /** - * We keep two <sub_barriers>, one for the first "generation" of - * waiters, and one for the next "generation" of waiters. This - * efficiently solves the problem of what to do if all the first - * generation waiters don't leave the barrier before one of the - * threads calls wait() again (i.e., starts up the next generation - * barrier). - */ - ACE_Sub_Barrier sub_barrier_1_; - ACE_Sub_Barrier sub_barrier_2_; - ACE_Sub_Barrier *sub_barrier_[2]; - -private: - // = Prevent assignment and initialization. - void operator= (const ACE_Barrier &); - ACE_Barrier (const ACE_Barrier &); -}; - -#if 0 -// The following two classes are commented out since there doesn't -// appear to be a portable and robust means of implementing this -// functionality across platforms. If you know of a portable and -// robust way to implement this functionality please let us know. - -/** - * @class ACE_Process_Condition - * - * @brief ACE_Condition variable wrapper that works across processes. - */ -class ACE_Export ACE_Process_Condition -{ -public: - ACE_Process_Condition (MUTEX &m, const ACE_TCHAR *name = 0, void *arg = 0); - - /// Dump the state of an object. - void dump (void) const; - - // ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. -}; -#endif /* 0 */ - -#if 0 -/** - * @class ACE_Process_Barrier - * - * @brief Implements "barrier synchronization" using ACE_Process_Mutexes! - * - * This class is just a simple wrapper for ACE_Barrier that - * selects the USYNC_PROCESS variant for the locks. - */ -class ACE_Export ACE_Process_Barrier : public ACE_Barrier -{ -public: - /// Create a Process_Barrier, passing in the optional <name>. - ACE_Process_Barrier (u_int count, const ACE_TCHAR *name = 0); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; -}; -#endif /* 0 */ - -/** - * @class ACE_Thread_Barrier - * - * @brief Implements "barrier synchronization" using ACE_Thread_Mutexes! - * - * This class is just a simple wrapper for ACE_Barrier that - * selects the USYNC_THREAD variant for the locks. - */ -class ACE_Export ACE_Thread_Barrier : public ACE_Barrier -{ -public: - /// Create a Thread_Barrier, passing in the optional <name>. - ACE_Thread_Barrier (u_int count, const ACE_TCHAR *name = 0); - - /// Default dtor. - ~ACE_Thread_Barrier (void); - - /// Dump the state of an object. - void dump (void) const; - - /// Declare the dynamic allocation hooks. - ACE_ALLOC_HOOK_DECLARE; -}; -#endif /* ACE_HAS_THREADS */ +/* All the classes have been moved out into their own headers as part of + the compile-time and footprint reduction effort. */ + +#include "ace/Auto_Event.h" +#include "ace/Barrier.h" +#include "ace/Condition_Thread_Mutex.h" +#include "ace/Condition_Recursive_Thread_Mutex.h" +#include "ace/Event.h" +#include "ace/Lock.h" +#include "ace/Manual_Event.h" +#include "ace/Mutex.h" +#include "ace/Null_Barrier.h" +#include "ace/Null_Condition.h" +#include "ace/Null_Mutex.h" +#include "ace/Null_Semaphore.h" +#include "ace/RW_Mutex.h" +#include "ace/RW_Thread_Mutex.h" +#include "ace/Recursive_Thread_Mutex.h" +#include "ace/Semaphore.h" +#include "ace/Thread_Mutex.h" +#include "ace/Thread_Semaphore.h" +#include "ace/TSS_Adapter.h" #if defined (__ACE_INLINE__) #include "ace/Synch.i" @@ -1686,172 +52,6 @@ public: // Include the templates here. #include "ace/Synch_T.h" -template <class ACE_LOCK> -class ACE_Guard; - -ACE_TEMPLATE_SPECIALIZATION -/** - * @class ACE_Guard<ACE_Null_Mutex> - * - * @brief Template specialization of <ACE_Guard> for the - * <ACE_Null_Mutex>. - * - * This specialization is useful since it helps to speedup - * performance of the "Null_Mutex" considerably. - */ -class ACE_Export ACE_Guard<ACE_Null_Mutex> -{ -public: - // = Initialization and termination methods. - ACE_Guard (ACE_Null_Mutex &) {} - ACE_Guard (ACE_Null_Mutex &, int) {} - ACE_Guard (ACE_Null_Mutex &, int, int) {} -#if defined (ACE_WIN32) - ~ACE_Guard (void) {} -#endif /* ACE_WIN32 */ - - int acquire (void) { return 0; } - int tryacquire (void) { return 0; } - int release (void) { return 0; } - void disown (void) {} - int locked (void) { return 1; } - int remove (void) { return 0; } - void dump (void) const {} - -private: - // = Prevent assignment and initialization. - ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Guard<ACE_Null_Mutex> &)) - ACE_UNIMPLEMENTED_FUNC (ACE_Guard (const ACE_Guard<ACE_Null_Mutex> &)) -}; - -template <class ACE_LOCK> -class ACE_Write_Guard; - -ACE_TEMPLATE_SPECIALIZATION -/** - * @class ACE_Write_Guard<ACE_Null_Mutex> - * - */ -class ACE_Export ACE_Write_Guard<ACE_Null_Mutex> : public ACE_Guard<ACE_Null_Mutex> -{ -public: - ACE_Write_Guard (ACE_Null_Mutex &m) - : ACE_Guard<ACE_Null_Mutex> (m) {} - ACE_Write_Guard (ACE_Null_Mutex &m, int blocked) - : ACE_Guard<ACE_Null_Mutex> (m, blocked) {} - - int acquire_write (void) { return 0; } - int acquire (void) { return 0; } - int tryacquire_write (void) { return 0; } - int tryacquire (void) { return 0; } - void dump (void) const {} -}; - -template <class ACE_LOCK> -class ACE_Read_Guard; - -ACE_TEMPLATE_SPECIALIZATION -/** - * @class ACE_Read_Guard<ACE_Null_Mutex> - * - */ -class ACE_Export ACE_Read_Guard<ACE_Null_Mutex> : public ACE_Guard<ACE_Null_Mutex> -{ -public: - ACE_Read_Guard (ACE_Null_Mutex &m) - : ACE_Guard<ACE_Null_Mutex> (m) {} - ACE_Read_Guard (ACE_Null_Mutex &m, int blocked) - : ACE_Guard<ACE_Null_Mutex> (m, blocked) {} - - int acquire_read (void) { return 0; } - int acquire (void) { return 0; } - int tryacquire_read (void) { return 0; } - int tryacquire (void) { return 0; } - void dump (void) const {} -}; - -#if defined (ACE_HAS_THREADS) - -template <class ACE_LOCK> -class ACE_Condition; - -ACE_TEMPLATE_SPECIALIZATION -/** - * @class ACE_Condition<ACE_Recursive_Thread_Mutex> - * - * @brief ACE_Condition template specialization written using - * @a ACE_Recursive_Thread_Mutex. This allows threads to block until - * shared data changes state using recursive mutexes. - */ -class ACE_Export ACE_Condition<ACE_Recursive_Thread_Mutex> -{ -public: - /// Initialize the condition variable with a recursive mutex. - ACE_Condition (ACE_Recursive_Thread_Mutex &m); - - /// Implicitly destroy the condition variable. - ~ACE_Condition (void); - - /** - * Explicitly destroy the condition variable. Note that only one - * thread should call this method since it doesn't protect against - * race conditions. - */ - int remove (void); - - /** - * Block on condition, or until absolute time-of-day has passed. If - * abstime == 0 use "blocking" <wait> semantics. Else, if <abstime> - * != 0 and the call times out before the condition is signaled - * <wait> returns -1 and sets errno to ETIME. - */ - int wait (const ACE_Time_Value *abstime = 0); - - /** - * Block on condition or until absolute time-of-day has passed. If - * abstime == 0 use "blocking" wait() semantics on the recursive @a mutex - * passed as a parameter (this is useful if you need to store the - * <Condition> in shared memory). Else, if <abstime> != 0 and the - * call times out before the condition is signaled <wait> returns -1 - * and sets errno to ETIME. - */ - int wait (ACE_Recursive_Thread_Mutex &mutex, - const ACE_Time_Value *abstime = 0); - - /// Signal one waiting thread. - int signal (void); - - /// Signal *all* waiting threads. - int broadcast (void); - - /// Returns a reference to the underlying mutex; - ACE_Recursive_Thread_Mutex &mutex (void); - - /// Dump the state of an object. - void dump (void) const; - -private: - /// A normal (i.e., non-recursive) condition variable. - ACE_cond_t cond_; - - /// Reference to the recursive mutex. - ACE_Recursive_Thread_Mutex &mutex_; - - // = Prevent assignment and initialization. - ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Condition<ACE_Recursive_Thread_Mutex> &)) - ACE_UNIMPLEMENTED_FUNC (ACE_Condition (const ACE_Condition<ACE_Recursive_Thread_Mutex> &)) -}; - -class ACE_Export ACE_Condition_Recursive_Thread_Mutex - : public ACE_Condition<ACE_Recursive_Thread_Mutex> -{ -public: - /// Initialize the condition variable with a recursive mutex. - ACE_Condition_Recursive_Thread_Mutex (ACE_Recursive_Thread_Mutex &m): - ACE_Condition<ACE_Recursive_Thread_Mutex> (m) {} -}; -#endif /* ACE_HAS_THREADS */ - #if defined (ACE_LEGACY_MODE) # include "ace/File_Lock.h" # include "ace/Process_Semaphore.h" diff --git a/ace/Synch.i b/ace/Synch.i index b424bf2e3dd..6318deb79a0 100644 --- a/ace/Synch.i +++ b/ace/Synch.i @@ -1,1014 +1,2 @@ /* -*- C++ -*- */ // $Id$ - -ACE_INLINE -ACE_Lock::ACE_Lock (void) -{ -} - -ACE_INLINE const ACE_rwlock_t & -ACE_RW_Mutex::lock (void) const -{ -// ACE_TRACE ("ACE_RW_Mutex::lock"); - return this->lock_; -} - -ACE_INLINE int -ACE_RW_Mutex::remove (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::remove"); - int result = 0; - if (this->removed_ == 0) - { - this->removed_ = 1; - result = ACE_OS::rwlock_destroy (&this->lock_); - } - return result; -} - -ACE_INLINE int -ACE_RW_Mutex::acquire_read (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::acquire_read"); - return ACE_OS::rw_rdlock (&this->lock_); -} - -ACE_INLINE int -ACE_RW_Mutex::acquire_write (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::acquire_write"); - return ACE_OS::rw_wrlock (&this->lock_); -} - -ACE_INLINE int -ACE_RW_Mutex::acquire (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::acquire"); - return ACE_OS::rw_wrlock (&this->lock_); -} - -ACE_INLINE int -ACE_RW_Mutex::tryacquire_read (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::tryacquire_read"); - return ACE_OS::rw_tryrdlock (&this->lock_); -} - -ACE_INLINE int -ACE_RW_Mutex::tryacquire_write (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::tryacquire_write"); - return ACE_OS::rw_trywrlock (&this->lock_); -} - -ACE_INLINE int -ACE_RW_Mutex::tryacquire_write_upgrade (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::tryacquire_write_upgrade"); - return ACE_OS::rw_trywrlock_upgrade (&this->lock_); -} - -ACE_INLINE int -ACE_RW_Mutex::tryacquire (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::tryacquire"); - return this->tryacquire_write (); -} - -ACE_INLINE int -ACE_RW_Mutex::release (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::release"); - return ACE_OS::rw_unlock (&this->lock_); -} - -#if defined (ACE_HAS_THREADS) -ACE_INLINE int -ACE_RW_Thread_Mutex::tryacquire_write_upgrade (void) -{ -// ACE_TRACE ("ACE_RW_Thread_Mutex::tryacquire_write_upgrade"); - return ACE_OS::rw_trywrlock_upgrade (&this->lock_); -} -#endif /* ACE_HAS_THREADS */ - -ACE_INLINE int -ACE_Mutex::acquire_read (void) -{ -// ACE_TRACE ("ACE_Mutex::acquire_read"); -#if defined (CHORUS) - if (this->process_lock_) - return ACE_OS::mutex_lock (this->process_lock_); -#endif /* CHORUS */ - return ACE_OS::mutex_lock (&this->lock_); -} - -ACE_INLINE int -ACE_Mutex::acquire_write (void) -{ -// ACE_TRACE ("ACE_Mutex::acquire_write"); -#if defined (CHORUS) - if (this->process_lock_) - return ACE_OS::mutex_lock (this->process_lock_); -#endif /* CHORUS */ - return ACE_OS::mutex_lock (&this->lock_); -} - -ACE_INLINE int -ACE_Mutex::tryacquire_read (void) -{ -// ACE_TRACE ("ACE_Mutex::tryacquire_read"); -#if defined (CHORUS) - if (this->process_lock_) - return ACE_OS::mutex_trylock (this->process_lock_); -#endif /* CHORUS */ - return ACE_OS::mutex_trylock (&this->lock_); -} - -ACE_INLINE const ACE_mutex_t & -ACE_Mutex::lock (void) const -{ -// ACE_TRACE ("ACE_Mutex::lock"); -#if defined (CHORUS) - if (this->process_lock_) - return *this->process_lock_; -#endif /* CHORUS */ - return this->lock_; -} - -ACE_INLINE int -ACE_Mutex::tryacquire_write (void) -{ -// ACE_TRACE ("ACE_Mutex::tryacquire_write"); -#if defined (CHORUS) - if (this->process_lock_) - return ACE_OS::mutex_trylock (this->process_lock_); -#endif /* CHORUS */ - return ACE_OS::mutex_trylock (&this->lock_); -} - -ACE_INLINE int -ACE_Mutex::tryacquire_write_upgrade (void) -{ -// ACE_TRACE ("ACE_Mutex::tryacquire_write_upgrade"); - return 0; -} - -ACE_INLINE int -ACE_Mutex::acquire (void) -{ -// ACE_TRACE ("ACE_Mutex::acquire"); -#if defined (CHORUS) - if (this->process_lock_) - return ACE_OS::mutex_lock (this->process_lock_); -#endif /* CHORUS */ - return ACE_OS::mutex_lock (&this->lock_); -} - -ACE_INLINE int -ACE_Mutex::acquire (ACE_Time_Value &tv) -{ - // ACE_TRACE ("ACE_Mutex::acquire"); - return ACE_OS::mutex_lock (&this->lock_, tv); -} - -ACE_INLINE int -ACE_Mutex::acquire (ACE_Time_Value *tv) -{ - // ACE_TRACE ("ACE_Mutex::acquire"); - return ACE_OS::mutex_lock (&this->lock_, tv); -} - -ACE_INLINE int -ACE_Mutex::tryacquire (void) -{ -// ACE_TRACE ("ACE_Mutex::tryacquire"); -#if defined (CHORUS) - if (this->process_lock_) - return ACE_OS::mutex_trylock (this->process_lock_); -#endif /* CHORUS */ - return ACE_OS::mutex_trylock (&this->lock_); -} - -ACE_INLINE int -ACE_Mutex::release (void) -{ -// ACE_TRACE ("ACE_Mutex::release"); -#if defined (CHORUS) - if (this->process_lock_) - return ACE_OS::mutex_unlock (this->process_lock_); -#endif /* CHORUS */ - return ACE_OS::mutex_unlock (&this->lock_); -} - -ACE_INLINE int -ACE_Mutex::remove (void) -{ -// ACE_TRACE ("ACE_Mutex::remove"); -#if defined (CHORUS) || defined (ACE_HAS_PTHREADS) || defined (ACE_HAS_STHREADS) - int result = 0; - // In the case of a interprocess mutex, the owner is the first - // process that created the shared memory object. In this case, the - // lockname_ pointer will be non-zero (points to allocated memory - // for the name). Owner or not, the memory needs to be unmapped - // from the process. If we are the owner, the file used for - // shm_open needs to be deleted as well. - if (this->process_lock_) - { - if (this->removed_ == 0) - { - this->removed_ = 1; - - // Only destroy the lock if we're the ones who initialized - // it. - if (!this->lockname_) - ACE_OS::munmap ((void *) this->process_lock_, - sizeof (ACE_mutex_t)); - else - { - result = ACE_OS::mutex_destroy (this->process_lock_); - ACE_OS::munmap ((void *) this->process_lock_, - sizeof (ACE_mutex_t)); - ACE_OS::shm_unlink (this->lockname_); - ACE_OS::free (ACE_static_cast (void *, - ACE_const_cast (ACE_TCHAR *, - this->lockname_))); - } - } - } - return result; -#else /* !CHORUS */ - int result = 0; - if (this->removed_ == 0) - { - this->removed_ = 1; - result = ACE_OS::mutex_destroy (&this->lock_); - } - return result; -#endif /* CHORUS */ -} - -ACE_INLINE const ACE_sema_t & -ACE_Semaphore::lock (void) const -{ -// ACE_TRACE ("ACE_Semaphore::lock"); - return this->semaphore_; -} - -ACE_INLINE int -ACE_Semaphore::remove (void) -{ -// ACE_TRACE ("ACE_Semaphore::remove"); - int result = 0; - if (this->removed_ == 0) - { - this->removed_ = 1; - result = ACE_OS::sema_destroy (&this->semaphore_); - } - return result; -} - -ACE_INLINE int -ACE_Semaphore::acquire (void) -{ -// ACE_TRACE ("ACE_Semaphore::acquire"); - return ACE_OS::sema_wait (&this->semaphore_); -} - -ACE_INLINE int -ACE_Semaphore::acquire (ACE_Time_Value &tv) -{ -// ACE_TRACE ("ACE_Semaphore::acquire"); - return ACE_OS::sema_wait (&this->semaphore_, tv); -} - -ACE_INLINE int -ACE_Semaphore::acquire (ACE_Time_Value *tv) -{ -// ACE_TRACE ("ACE_Semaphore::acquire"); - return ACE_OS::sema_wait (&this->semaphore_, tv); -} - -ACE_INLINE int -ACE_Semaphore::tryacquire (void) -{ -// ACE_TRACE ("ACE_Semaphore::tryacquire"); - return ACE_OS::sema_trywait (&this->semaphore_); -} - -ACE_INLINE int -ACE_Semaphore::release (void) -{ -// ACE_TRACE ("ACE_Semaphore::release"); - return ACE_OS::sema_post (&this->semaphore_); -} - -ACE_INLINE int -ACE_Semaphore::release (u_int release_count) -{ -// ACE_TRACE ("ACE_Semaphore::release"); - return ACE_OS::sema_post (&this->semaphore_, release_count); -} - -// Acquire semaphore ownership. This calls <acquire> and is only -// here to make the <ACE_Semaphore> interface consistent with the -// other synchronization APIs. - -ACE_INLINE int -ACE_Semaphore::acquire_read (void) -{ - return this->acquire (); -} - -// Acquire semaphore ownership. This calls <acquire> and is only -// here to make the <ACE_Semaphore> interface consistent with the -// other synchronization APIs. - -ACE_INLINE int -ACE_Semaphore::acquire_write (void) -{ - return this->acquire (); -} - -// Conditionally acquire semaphore (i.e., won't block). This calls -// <tryacquire> and is only here to make the <ACE_Semaphore> -// interface consistent with the other synchronization APIs. - -ACE_INLINE int -ACE_Semaphore::tryacquire_read (void) -{ - return this->tryacquire (); -} - -// Conditionally acquire semaphore (i.e., won't block). This calls -// <tryacquire> and is only here to make the <ACE_Semaphore> -// interface consistent with the other synchronization APIs. - -ACE_INLINE int -ACE_Semaphore::tryacquire_write (void) -{ - return this->tryacquire (); -} - -// This is only here to make the <ACE_Semaphore> interface consistent -// with the other synchronization APIs. Assumes the caller has -// already acquired the semaphore using one of the above calls, and -// returns 0 (success) always. -ACE_INLINE int -ACE_Semaphore::tryacquire_write_upgrade (void) -{ - return 0; -} - -// Null ACE_Semaphore implementation - -ACE_INLINE -ACE_Null_Semaphore::ACE_Null_Semaphore (u_int, - int, - const ACE_TCHAR *, - void *, - int) -{ -} - -ACE_INLINE -ACE_Null_Semaphore::~ACE_Null_Semaphore (void) -{ -} - -ACE_INLINE int -ACE_Null_Semaphore::remove (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Semaphore::acquire (ACE_Time_Value &) -{ - errno = ETIME; - return -1; -} - -ACE_INLINE int -ACE_Null_Semaphore::acquire (ACE_Time_Value *) -{ - errno = ETIME; - return -1; -} - -ACE_INLINE int -ACE_Null_Semaphore::acquire (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Semaphore::tryacquire (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Semaphore::release (size_t) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Semaphore::release (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Semaphore::acquire_write (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Semaphore::tryacquire_write (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Semaphore::tryacquire_write_upgrade (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Semaphore::acquire_read (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Semaphore::tryacquire_read (void) -{ - return 0; -} - -ACE_INLINE void -ACE_Null_Semaphore::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -#endif /* ACE_HAS_DUMP */ -} - -#if defined (ACE_HAS_THREADS) - -ACE_INLINE const ACE_thread_mutex_t & -ACE_Thread_Mutex::lock (void) const -{ -// ACE_TRACE ("ACE_Thread_Mutex::lock"); - return this->lock_; -} - -ACE_INLINE int -ACE_Thread_Mutex::acquire_read (void) -{ -// ACE_TRACE ("ACE_Thread_Mutex::acquire_read"); - return ACE_OS::thread_mutex_lock (&this->lock_); -} - -ACE_INLINE int -ACE_Thread_Mutex::acquire_write (void) -{ -// ACE_TRACE ("ACE_Thread_Mutex::acquire_write"); - return ACE_OS::thread_mutex_lock (&this->lock_); -} - -ACE_INLINE int -ACE_Thread_Mutex::tryacquire_read (void) -{ -// ACE_TRACE ("ACE_Thread_Mutex::tryacquire_read"); - return ACE_OS::thread_mutex_trylock (&this->lock_); -} - -ACE_INLINE int -ACE_Thread_Mutex::tryacquire_write (void) -{ -// ACE_TRACE ("ACE_Thread_Mutex::tryacquire_write"); - return ACE_OS::thread_mutex_trylock (&this->lock_); -} - -ACE_INLINE int -ACE_Thread_Mutex::tryacquire_write_upgrade (void) -{ -// ACE_TRACE ("ACE_Thread_Mutex::tryacquire_write_upgrade"); - return 0; -} - -ACE_INLINE int -ACE_Thread_Mutex::acquire (void) -{ -// ACE_TRACE ("ACE_Thread_Mutex::acquire"); - return ACE_OS::thread_mutex_lock (&this->lock_); -} - -ACE_INLINE int -ACE_Thread_Mutex::acquire (ACE_Time_Value &tv) -{ - // ACE_TRACE ("ACE_Thread_Mutex::acquire"); - return ACE_OS::thread_mutex_lock (&this->lock_, tv); -} - -ACE_INLINE int -ACE_Thread_Mutex::acquire (ACE_Time_Value *tv) -{ - // ACE_TRACE ("ACE_Thread_Mutex::acquire"); - return ACE_OS::thread_mutex_lock (&this->lock_, tv); -} - -ACE_INLINE int -ACE_Thread_Mutex::tryacquire (void) -{ -// ACE_TRACE ("ACE_Thread_Mutex::tryacquire"); - return ACE_OS::thread_mutex_trylock (&this->lock_); -} - -ACE_INLINE int -ACE_Thread_Mutex::release (void) -{ -// ACE_TRACE ("ACE_Thread_Mutex::release"); - return ACE_OS::thread_mutex_unlock (&this->lock_); -} - -ACE_INLINE int -ACE_Thread_Mutex::remove (void) -{ -// ACE_TRACE ("ACE_Thread_Mutex::remove"); - int result = 0; - if (this->removed_ == 0) - { - this->removed_ = 1; - result = ACE_OS::thread_mutex_destroy (&this->lock_); - } - return result; -} - -#if defined (ACE_USES_OBSOLETE_GUARD_CLASSES) -ACE_INLINE int -ACE_Thread_Mutex_Guard::locked (void) -{ -// ACE_TRACE ("ACE_Thread_Mutex_Guard::locked"); - return this->owner_ != -1; -} - -// Explicitly acquire the lock. - -ACE_INLINE int -ACE_Thread_Mutex_Guard::acquire (void) -{ -// ACE_TRACE ("ACE_Thread_Mutex_Guard::acquire"); - return this->owner_ = this->lock_.acquire (); -} - -// Conditionally acquire the lock (i.e., won't block). - -ACE_INLINE int -ACE_Thread_Mutex_Guard::tryacquire (void) -{ -// ACE_TRACE ("ACE_Thread_Mutex_Guard::tryacquire"); - return this->owner_ = this->lock_.tryacquire (); -} - -// Implicitly and automatically acquire the lock. - -ACE_INLINE -ACE_Thread_Mutex_Guard::ACE_Thread_Mutex_Guard (ACE_Thread_Mutex &m, - int block) - : lock_ (m) -{ -// ACE_TRACE ("ACE_Thread_Mutex_Guard::ACE_Thread_Mutex_Guard"); - if (block) - this->acquire (); - else - this->tryacquire (); -} - -// Explicitly release the lock. - -ACE_INLINE int -ACE_Thread_Mutex_Guard::release (void) -{ -// ACE_TRACE ("ACE_Thread_Mutex_Guard::release"); - if (this->owner_ != -1) - { - this->owner_ = -1; - return this->lock_.release (); - } - else - return 0; -} - -// Implicitly release the lock. - -ACE_INLINE -ACE_Thread_Mutex_Guard::~ACE_Thread_Mutex_Guard (void) -{ -// ACE_TRACE ("ACE_Thread_Mutex_Guard::~ACE_Thread_Mutex_Guard"); - this->release (); -} - -// Explicitly release the lock. - -ACE_INLINE int -ACE_Thread_Mutex_Guard::remove (void) -{ -// ACE_TRACE ("ACE_Thread_Mutex_Guard::remove"); - this->owner_ = -1; - return this->release (); -} -#endif /* ACE_USES_OBSOLETE_GUARD_CLASSES */ - -ACE_INLINE -ACE_Condition_Attributes::ACE_Condition_Attributes (int type) -{ - (void) ACE_OS::condattr_init (this->attributes_, type); -} - -ACE_INLINE -ACE_Condition_Attributes::~ACE_Condition_Attributes (void) -{ - ACE_OS::condattr_destroy (this->attributes_); -} - -ACE_INLINE int -ACE_Condition_Thread_Mutex::remove (void) -{ -// ACE_TRACE ("ACE_Condition_Thread_Mutex::remove"); - - // <cond_destroy> is called in a loop if the condition variable is - // BUSY. This avoids a condition where a condition is signaled and - // because of some timing problem, the thread that is to be signaled - // has called the cond_wait routine after the signal call. Since - // the condition signal is not queued in any way, deadlock occurs. - - int result = 0; - - if (this->removed_ == 0) - { - this->removed_ = 1; - - while ((result = ACE_OS::cond_destroy (&this->cond_)) == -1 - && errno == EBUSY) - { - ACE_OS::cond_broadcast (&this->cond_); - ACE_OS::thr_yield (); - } - } - return result; -} - -ACE_INLINE ACE_Thread_Mutex & -ACE_Condition_Thread_Mutex::mutex (void) -{ -// ACE_TRACE ("ACE_Condition_Thread_Mutex::mutex"); - return this->mutex_; -} - -ACE_INLINE ACE_recursive_thread_mutex_t & -ACE_Recursive_Thread_Mutex::mutex (void) -{ - return lock_; -} - -ACE_INLINE ACE_thread_mutex_t & -ACE_Recursive_Thread_Mutex::get_nesting_mutex (void) -{ -#if defined (ACE_HAS_RECURSIVE_MUTEXES) - return ACE_static_cast (ACE_thread_mutex_t &, - lock_); -#else - return lock_.nesting_mutex_; -#endif /* ACE_HAS_RECURSIVE_MUTEXES */ -} - -ACE_INLINE void -ACE_Recursive_Thread_Mutex::set_thread_id (ACE_thread_t t) -{ -// ACE_TRACE ("ACE_Recursive_Thread_Mutex::set_thread_id"); -#if defined (ACE_HAS_RECURSIVE_MUTEXES) - ACE_UNUSED_ARG (t); -#else /* ! ACE_HAS_RECURSIVE_MUTEXES */ - this->lock_.owner_id_ = t; -#endif /* ! ACE_HAS_RECURSIVE_MUTEXES */ -} - -ACE_INLINE int -ACE_Recursive_Thread_Mutex::acquire_read (void) -{ - return this->acquire (); -} - -ACE_INLINE int -ACE_Recursive_Thread_Mutex::acquire_write (void) -{ - return this->acquire (); -} - -ACE_INLINE int -ACE_Recursive_Thread_Mutex::tryacquire_read (void) -{ - return this->tryacquire (); -} - -ACE_INLINE int -ACE_Recursive_Thread_Mutex::tryacquire_write (void) -{ - return this->tryacquire (); -} - -ACE_INLINE int -ACE_Recursive_Thread_Mutex::tryacquire_write_upgrade (void) -{ - return 0; -} - -#endif /* ACE_HAS_THREADS */ - -ACE_INLINE -ACE_Null_Barrier::ACE_Null_Barrier (u_int, - const char *, - void *) -{ -} - -ACE_INLINE -ACE_Null_Barrier::~ACE_Null_Barrier (void) -{ -} - -ACE_INLINE int -ACE_Null_Barrier::wait (void) -{ - return 0; -} - -ACE_INLINE void -ACE_Null_Barrier::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -#endif /* ACE_HAS_DUMP */ -} - -ACE_INLINE -ACE_Null_Mutex::ACE_Null_Mutex (const ACE_TCHAR *) - : lock_ (0) -{ -} - -ACE_INLINE -ACE_Null_Mutex::~ACE_Null_Mutex (void) -{ -} - -ACE_INLINE int -ACE_Null_Mutex::remove (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Mutex::acquire (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Mutex::acquire (ACE_Time_Value &) -{ - errno = ETIME; - return -1; -} - -ACE_INLINE int -ACE_Null_Mutex::acquire (ACE_Time_Value *) -{ - errno = ETIME; - return -1; -} - -ACE_INLINE int -ACE_Null_Mutex::tryacquire (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Mutex::release (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Mutex::acquire_write (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Mutex::tryacquire_write (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Mutex::tryacquire_write_upgrade (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Mutex::acquire_read (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Mutex::tryacquire_read (void) -{ - return 0; -} - -ACE_INLINE void -ACE_Null_Mutex::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -#endif /* ACE_HAS_DUMP */ -} - -ACE_INLINE int -ACE_Noop_Token::queueing_strategy (void) -{ - return -1; -} - -ACE_INLINE void -ACE_Noop_Token::queueing_strategy (int /* queueing_strategy */) -{ -} - -ACE_INLINE int -ACE_Noop_Token::renew (int, ACE_Time_Value *) -{ - return 0; -} - -ACE_INLINE void -ACE_Noop_Token::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -#endif /* ACE_HAS_DUMP */ -} - - -ACE_INLINE -ACE_Null_Condition::ACE_Null_Condition (const ACE_Null_Mutex &m, - const ACE_TCHAR *, - void*) - : mutex_ ((ACE_Null_Mutex &) m) -{ -} - -ACE_INLINE ACE_Null_Condition::~ACE_Null_Condition (void) -{ -} - -ACE_INLINE int ACE_Null_Condition::remove (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Condition::wait (const ACE_Time_Value *) -{ - errno = ETIME; - return -1; -} - -ACE_INLINE int -ACE_Null_Condition::wait (ACE_Null_Mutex &, - const ACE_Time_Value *) -{ - errno = ETIME; - return -1; -} - -ACE_INLINE int -ACE_Null_Condition::signal (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Condition::broadcast (void) -{ - return 0; -} - -ACE_INLINE ACE_Null_Mutex & -ACE_Null_Condition::mutex (void) -{ - return this->mutex_; -} - -ACE_INLINE void -ACE_Null_Condition::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -#endif /* ACE_HAS_DUMP */ -} - -#if defined (ACE_USES_OBSOLETE_GUARD_CLASSES) -ACE_INLINE -ACE_Null_Mutex_Guard::ACE_Null_Mutex_Guard (ACE_Null_Mutex &) -{ -} - -ACE_INLINE -ACE_Null_Mutex_Guard::~ACE_Null_Mutex_Guard (void) -{ -} - -ACE_INLINE int -ACE_Null_Mutex_Guard::remove (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Mutex_Guard::locked (void) -{ - return 1; -} - -ACE_INLINE int -ACE_Null_Mutex_Guard::acquire (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Mutex_Guard::tryacquire (void) -{ - return 0; -} - -ACE_INLINE int -ACE_Null_Mutex_Guard::release (void) -{ - return 0; -} - -ACE_INLINE void -ACE_Null_Mutex_Guard::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -#endif /* ACE_HAS_DUMP */ -} -#endif /* ACE_USES_OBSOLETE_GUARD_CLASSES */ - -ACE_INLINE -ACE_TSS_Adapter::~ACE_TSS_Adapter (void) -{ -} - -ACE_INLINE -ACE_Manual_Event::~ACE_Manual_Event (void) -{ -} - -ACE_INLINE -ACE_Auto_Event::~ACE_Auto_Event (void) -{ -} - -#if defined (ACE_HAS_THREADS) -ACE_INLINE -ACE_RW_Thread_Mutex::~ACE_RW_Thread_Mutex (void) -{ -} - -ACE_INLINE -ACE_Thread_Semaphore::~ACE_Thread_Semaphore (void) -{ -} - -ACE_INLINE -ACE_Sub_Barrier::~ACE_Sub_Barrier (void) -{ -} - -ACE_INLINE -ACE_Barrier::~ACE_Barrier (void) -{ -} - -ACE_INLINE -ACE_Thread_Barrier::~ACE_Thread_Barrier (void) -{ -} -#endif /* ACE_HAS_THREADS */ diff --git a/ace/Synch_T.cpp b/ace/Synch_T.cpp index 8ddd4f0af8f..84cf5e531f1 100644 --- a/ace/Synch_T.cpp +++ b/ace/Synch_T.cpp @@ -18,891 +18,10 @@ ACE_RCSID(ace, Synch_T, "$Id$") #include "ace/Synch_T.i" #endif /* __ACE_INLINE__ */ -// This constructor isn't inlined, because SunPRO C++ 4.2 + patch -// 104631-07 has trouble compiling TAO with it inline. -template <class ACE_LOCKING_MECHANISM> -ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::ACE_Lock_Adapter (void) - : lock_ (0), - delete_lock_ (1) -{ - ACE_NEW (this->lock_, - ACE_LOCKING_MECHANISM); -} - -template <class ACE_LOCKING_MECHANISM> -ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::~ACE_Reverse_Lock (void) -{ -} -// **************************************************************** -// ACE_ALLOC_HOOK_DEFINE(ACE_Guard) - -template <class ACE_LOCK> void -ACE_Guard<ACE_LOCK>::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Guard<ACE_LOCK>::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("mutex_ = %x\n"), this->lock_)); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("owner_ = %d\n"), this->owner_)); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -#endif /* ACE_HAS_DUMP */ -} - -// ACE_ALLOC_HOOK_DEFINE(ACE_Write_Guard) - -template <class ACE_LOCK> void -ACE_Write_Guard<ACE_LOCK>::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Write_Guard<ACE_LOCK>::dump"); - ACE_Guard<ACE_LOCK>::dump (); -#endif /* ACE_HAS_DUMP */ -} - -// ACE_ALLOC_HOOK_DEFINE(ACE_Read_Guard) - -template <class ACE_LOCK> void -ACE_Read_Guard<ACE_LOCK>::dump (void) const -{ -// ACE_TRACE ("ACE_Read_Guard<ACE_LOCK>::dump"); - ACE_Guard<ACE_LOCK>::dump (); -} - -#if defined (ACE_HAS_THREADS) - -ACE_ALLOC_HOOK_DEFINE(ACE_Condition) - -template <class MUTEX> void -ACE_Condition<MUTEX>::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Condition<MUTEX>::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); -#if defined (CHORUS) - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("condname_ = %s\n"), this->condname_)); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("process_cond_ = %x\n"), this->process_cond_)); -#endif /* CHORUS */ - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -#endif /* ACE_HAS_DUMP */ -} - -template <class MUTEX> -ACE_Thread_Condition<MUTEX>::ACE_Thread_Condition (MUTEX &m, - const ACE_TCHAR *name, - void *arg) - : ACE_Condition<MUTEX> (m, USYNC_THREAD, name, arg) -{ -// ACE_TRACE ("ACE_Thread_Condition<MUTEX>::ACE_Thread_Condition"); -} - -template <class MUTEX> void -ACE_Thread_Condition<MUTEX>::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_Thread_Condition<MUTEX>::dump"); - - ACE_Condition<MUTEX>::dump (); -#endif /* ACE_HAS_DUMP */ -} - -template <class MUTEX> -ACE_Condition<MUTEX>::ACE_Condition (MUTEX &m, - int type, - const ACE_TCHAR *name, - void *arg) - : -#if defined (CHORUS) - process_cond_(0), - condname_ (0), -#endif /* CHORUS */ - mutex_ (m) -{ - -#if defined(CHORUS) - if (type == USYNC_PROCESS) - { - // Let's see if the shared memory entity already exists. - ACE_HANDLE fd = ACE_OS::shm_open (name, - O_RDWR | O_CREAT | O_EXCL, - ACE_DEFAULT_FILE_PERMS); - if (fd == ACE_INVALID_HANDLE) - { - if (errno == EEXIST) - fd = ACE_OS::shm_open (name, - O_RDWR | O_CREAT, - ACE_DEFAULT_FILE_PERMS); - else - return; - } - else - { - // We own this shared memory object! Let's set its size. - if (ACE_OS::ftruncate (fd, - sizeof (ACE_mutex_t)) == -1) - { - ACE_OS::close (fd); - return; - } - this->condname_ = ACE_OS::strdup (name); - if (this->condname_ == 0) - { - ACE_OS::close (fd); - return; - } - } - - this->process_cond_ = - (ACE_cond_t *) ACE_OS::mmap (0, - sizeof (ACE_cond_t), - PROT_RDWR, - MAP_SHARED, - fd, - 0); - ACE_OS::close (fd); - if (this->process_cond_ == MAP_FAILED) - return; - - if (this->condname_ - && ACE_OS::cond_init (this->process_cond_, - type, - name, - arg) != 0) - return; - } - // It is ok to fall through into the <cond_init> below if the - // USYNC_PROCESS flag is not enabled. -#endif /* CHORUS */ - - // ACE_TRACE ("ACE_Condition<MUTEX>::ACE_Condition"); - - if (ACE_OS::cond_init (&this->cond_, - (short) type, - name, - arg) != 0) - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("%p\n"), - ACE_LIB_TEXT ("ACE_Condition::ACE_Condition"))); -} - -template <class MUTEX> -ACE_Condition<MUTEX>::~ACE_Condition (void) -{ - // ACE_TRACE ("ACE_Condition<MUTEX>::~ACE_Condition"); - - if (this->remove () == -1) - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("%p\n"), - ACE_LIB_TEXT ("ACE_Condition::~ACE_Condition"))); -} - -template <class MUTEX> int -ACE_Condition<MUTEX>::wait (void) -{ - // ACE_TRACE ("ACE_Condition<MUTEX>::wait"); -#if defined (CHORUS) - if (this->process_cond_ != 0) - return ACE_OS::cond_wait (this->process_cond_, - &this->mutex_.lock_); -#endif /* CHORUS */ - return ACE_OS::cond_wait (&this->cond_, - &this->mutex_.lock_); -} - -template <class MUTEX> int -ACE_Condition<MUTEX>::wait (MUTEX &mutex, - const ACE_Time_Value *abstime) -{ -// ACE_TRACE ("ACE_Condition<MUTEX>::wait"); - if (abstime == 0) - return this->wait (); - else - { -#if defined (CHORUS) - if (this->process_cond_ != 0) - return ACE_OS::cond_timedwait (this->process_cond_, - &mutex_.lock_, - (ACE_Time_Value *) abstime); -#endif /* CHORUS */ - return ACE_OS::cond_timedwait (&this->cond_, - &mutex.lock_, - (ACE_Time_Value *) abstime); - } -} - -// Peform an "alertable" timed wait. If the argument ABSTIME == 0 -// then we do a regular cond_wait(), else we do a timed wait for up to -// ABSTIME using the Solaris cond_timedwait() function. - -template <class MUTEX> int -ACE_Condition<MUTEX>::wait (const ACE_Time_Value *abstime) -{ -// ACE_TRACE ("ACE_Condition<MUTEX>::wait"); - return this->wait (this->mutex_, abstime); -} -#endif /* ACE_HAS_THREADS */ - -ACE_ALLOC_HOOK_DEFINE(ACE_TSS) - -template <class TYPE> -ACE_TSS<TYPE>::~ACE_TSS (void) -{ - // We can't call <ACE_OS::thr_keyfree> until *all* of the threads - // that are using that key have done an <ACE_OS::thr_key_detach>. - // Otherwise, we'll end up with "dangling TSS pointers." - ACE_OS::thr_key_detach (this); -} - -template <class TYPE> TYPE * -ACE_TSS<TYPE>::operator-> () const -{ - return this->ts_get (); -} - -template <class TYPE> -ACE_TSS<TYPE>::operator TYPE *(void) const -{ - return this->ts_get (); -} - -template <class TYPE> TYPE * -ACE_TSS<TYPE>::make_TSS_TYPE (void) const -{ - TYPE *temp = 0; - ACE_NEW_RETURN (temp, - TYPE, - 0); - return temp; -} - -template <class TYPE> void -ACE_TSS<TYPE>::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_TSS<TYPE>::dump"); -#if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - this->keylock_.dump (); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("key_ = %d\n"), this->key_)); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nonce_ = %d"), this->once_)); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -#endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */ -#endif /* ACE_HAS_DUMP */ -} - -#if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) -#if defined (ACE_HAS_THR_C_DEST) -extern "C" void ACE_TSS_C_cleanup(void *); // defined in Synch.cpp -#endif /* ACE_HAS_THR_C_DEST */ - -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> int -ACE_TSS<TYPE>::ts_init (void) const -{ - // Insure that we are serialized! - ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, (ACE_Thread_Mutex &) this->keylock_, 0); - - // Use the Double-Check pattern to make sure we only create the key - // once! - if (this->once_ == 0) - { - if (ACE_Thread::keycreate (ACE_const_cast (ACE_thread_key_t *, &this->key_), -#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 -1; // Major problems, this should *never* happen! - else - { - // This *must* come last to avoid race conditions! Note that - // we need to "cast away const..." - * ACE_const_cast (int*, &this->once_) = 1; - return 0; - } - } - - return -1; -} - -template <class TYPE> -ACE_TSS<TYPE>::ACE_TSS (TYPE *ts_obj) - : once_ (0), - key_ (ACE_OS::NULL_key) -{ - // If caller has passed us a non-NULL TYPE *, then we'll just use - // this to initialize the thread-specific value. Thus, subsequent - // calls to operator->() will return this value. This is useful - // since it enables us to assign objects to thread-specific data - // that have arbitrarily complex constructors! - - if (ts_obj != 0) - { - if (this->ts_init () == -1) - { - // Save/restore errno. - ACE_Errno_Guard error (errno); - // What should we do if this call fails?! -#if defined (ACE_HAS_WINCE) - ::MessageBox (0, - L"ACE_Thread::keycreate() failed!", - L"ACE_TSS::ACE_TSS", - MB_OK); -#else - ACE_OS::fprintf (stderr, - "ACE_Thread::keycreate() failed!"); -#endif /* ACE_HAS_WINCE */ - return; - } - -#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, - ACE_LIB_TEXT ("%p\n"), - ACE_LIB_TEXT ("ACE_Thread::setspecific() failed!"))); - } -#else - if (ACE_Thread::setspecific (this->key_, - (void *) ts_obj) != 0) - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("%p\n"), - ACE_LIB_TEXT ("ACE_Thread::setspecific() failed!"))); -#endif /* ACE_HAS_THR_C_DEST */ - } -} - -template <class TYPE> TYPE * -ACE_TSS<TYPE>::ts_get (void) const -{ - if (this->once_ == 0) - // Create and initialize thread-specific ts_obj. - this->ts_init (); - - 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) - return 0; // This should not happen! - - // 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...). - - ts_obj = this->make_TSS_TYPE (); - - 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) - { - 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 the underlying ts object. - return (TYPE *) tss_adapter->ts_obj_; -#else - return ts_obj; -#endif /* ACE_HAS_THR_C_DEST */ -} - -// Get the thread-specific object for the key associated with this -// object. Returns 0 if the ts_obj has never been initialized, -// otherwise returns a pointer to the ts_obj. - -template <class TYPE> TYPE * -ACE_TSS<TYPE>::ts_object (void) const -{ - // Ensure that we are serialized! - ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, (ACE_Thread_Mutex &) this->keylock_, 0); - - if (this->once_ == 0) // Return 0 if we've never been initialized. - return 0; - - 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! -#endif /* ACE_HAS_THR_C_DEST */ - - return ts_obj; -} - -template <class TYPE> TYPE * -ACE_TSS<TYPE>::ts_object (TYPE *new_ts_obj) -{ - // Note, we shouldn't hold the keylock at this point because - // <ts_init> does it for us and we'll end up with deadlock - // otherwise... - if (this->once_ == 0) - // Create and initialize thread-specific ts_obj. - this->ts_init (); - - // Ensure that we are serialized! - ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->keylock_, 0); - - 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! - if (ACE_Thread::setspecific (this->key_, - (void *) new_ts_obj) == -1) - return ts_obj; // This should not happen! -#endif /* ACE_HAS_THR_C_DEST */ - - return ts_obj; -} - -ACE_ALLOC_HOOK_DEFINE(ACE_TSS_Guard) - -template <class ACE_LOCK> void -ACE_TSS_Guard<ACE_LOCK>::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("key_ = %d"), this->key_)); - ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -#endif /* ACE_HAS_DUMP */ -} - -template <class ACE_LOCK> void -ACE_TSS_Guard<ACE_LOCK>::init_key (void) -{ -// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::init_key"); - - 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<ACE_LOCK>::cleanup, -#endif /* ACE_HAS_THR_C_DEST */ - (void *) this); -} - -template <class ACE_LOCK> -ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard (void) -{ -// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard"); - this->init_key (); -} - -template <class ACE_LOCK> int -ACE_TSS_Guard<ACE_LOCK>::release (void) -{ -// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::release"); - - ACE_Guard<ACE_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<ACE_LOCK> *)tss_adapter->ts_obj_; -#else - ACE_Thread::getspecific (this->key_, - (void **) &guard); -#endif /* ACE_HAS_THR_C_DEST */ - - return guard->release (); -} - -template <class ACE_LOCK> int -ACE_TSS_Guard<ACE_LOCK>::remove (void) -{ -// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::remove"); - - ACE_Guard<ACE_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<ACE_LOCK> *) tss_adapter->ts_obj_; -#else - ACE_Thread::getspecific (this->key_, - (void **) &guard); -#endif /* ACE_HAS_THR_C_DEST */ - - return guard->remove (); -} - -template <class ACE_LOCK> -ACE_TSS_Guard<ACE_LOCK>::~ACE_TSS_Guard (void) -{ -// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::~ACE_TSS_Guard"); - - ACE_Guard<ACE_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<ACE_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_); - // Destructor releases lock. - delete guard; -} - -template <class ACE_LOCK> void -ACE_TSS_Guard<ACE_LOCK>::cleanup (void *ptr) -{ -// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::cleanup"); - - // Destructor releases lock. - delete (ACE_Guard<ACE_LOCK> *) ptr; -} - -template <class ACE_LOCK> -ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard (ACE_LOCK &lock, int block) -{ -// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard"); - - this->init_key (); - ACE_Guard<ACE_LOCK> *guard; - ACE_NEW (guard, - ACE_Guard<ACE_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<ACE_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 ACE_LOCK> int -ACE_TSS_Guard<ACE_LOCK>::acquire (void) -{ -// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::acquire"); - - ACE_Guard<ACE_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<ACE_LOCK> *) tss_adapter->ts_obj_; -#else - ACE_Thread::getspecific (this->key_, - (void **) &guard); -#endif /* ACE_HAS_THR_C_DEST */ - - return guard->acquire (); -} - -template <class ACE_LOCK> int -ACE_TSS_Guard<ACE_LOCK>::tryacquire (void) -{ -// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::tryacquire"); - - ACE_Guard<ACE_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<ACE_LOCK> *) tss_adapter->ts_obj_; -#else - ACE_Thread::getspecific (this->key_, - (void **) &guard); -#endif /* ACE_HAS_THR_C_DEST */ - - return guard->tryacquire (); -} - -template <class ACE_LOCK> -ACE_TSS_Write_Guard<ACE_LOCK>::ACE_TSS_Write_Guard (ACE_LOCK &lock, - int block) -{ -// ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::ACE_TSS_Write_Guard"); - - this->init_key (); - ACE_Guard<ACE_LOCK> *guard; - ACE_NEW (guard, - ACE_Write_Guard<ACE_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<ACE_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 ACE_LOCK> int -ACE_TSS_Write_Guard<ACE_LOCK>::acquire (void) -{ -// ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::acquire"); - - ACE_Write_Guard<ACE_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<ACE_LOCK> *) tss_adapter->ts_obj_; -#else - ACE_Thread::getspecific (this->key_, - (void **) &guard); -#endif /* ACE_HAS_THR_C_DEST */ - - return guard->acquire_write (); -} - -template <class ACE_LOCK> int -ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire (void) -{ -// ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire"); - - ACE_Write_Guard<ACE_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<ACE_LOCK> *) tss_adapter->ts_obj_; -#else - ACE_Thread::getspecific (this->key_, - (void **) &guard); -#endif /* ACE_HAS_THR_C_DEST */ - - return guard->tryacquire_write (); -} - -template <class ACE_LOCK> int -ACE_TSS_Write_Guard<ACE_LOCK>::acquire_write (void) -{ -// ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::acquire_write"); - - return this->acquire (); -} - -template <class ACE_LOCK> int -ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire_write (void) -{ -// ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire_write"); - - return this->tryacquire (); -} - -template <class ACE_LOCK> void -ACE_TSS_Write_Guard<ACE_LOCK>::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::dump"); - ACE_TSS_Guard<ACE_LOCK>::dump (); -#endif /* ACE_HAS_DUMP */ -} - -template <class ACE_LOCK> -ACE_TSS_Read_Guard<ACE_LOCK>::ACE_TSS_Read_Guard (ACE_LOCK &lock, int block) -{ -// ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::ACE_TSS_Read_Guard"); - - this->init_key (); - ACE_Guard<ACE_LOCK> *guard; - ACE_NEW (guard, - ACE_Read_Guard<ACE_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<ACE_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 ACE_LOCK> int -ACE_TSS_Read_Guard<ACE_LOCK>::acquire (void) -{ -// ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::acquire"); - - ACE_Read_Guard<ACE_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<ACE_LOCK> *) tss_adapter->ts_obj_; -#else - ACE_Thread::getspecific (this->key_, - (void **) &guard); -#endif /* ACE_HAS_THR_C_DEST */ - - return guard->acquire_read (); -} - -template <class ACE_LOCK> int -ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire (void) -{ -// ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire"); - - ACE_Read_Guard<ACE_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<ACE_LOCK> *) tss_adapter->ts_obj_; -#else - ACE_Thread::getspecific (this->key_, - (void **) &guard); -#endif /* ACE_HAS_THR_C_DEST */ - - return guard->tryacquire_read (); -} - -template <class ACE_LOCK> int -ACE_TSS_Read_Guard<ACE_LOCK>::acquire_read (void) -{ -// ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::acquire_read"); - - return this->acquire (); -} - -template <class ACE_LOCK> int -ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire_read (void) -{ -// ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire_read"); - - return this->tryacquire (); -} - -template <class ACE_LOCK> void -ACE_TSS_Read_Guard<ACE_LOCK>::dump (void) const -{ -#if defined (ACE_HAS_DUMP) -// ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::dump"); - ACE_TSS_Guard<ACE_LOCK>::dump (); -#endif /* ACE_HAS_DUMP */ -} - - -#endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */ +#include "ace/Lock_Adapter_T.cpp" +#include "ace/Reverse_Lock_T.cpp" +#include "ace/Guard_T.cpp" +#include "ace/TSS_T.cpp" +#include "ace/Condition_T.cpp" #endif /* ACE_SYNCH_T_C */ diff --git a/ace/Synch_T.h b/ace/Synch_T.h index bd8bfe4d3e5..ed4bc493a6e 100644 --- a/ace/Synch_T.h +++ b/ace/Synch_T.h @@ -13,885 +13,29 @@ #ifndef ACE_SYNCH_T_H #define ACE_SYNCH_T_H #include /**/ "ace/pre.h" -#include "ace/Synch.h" + +#include "ace/config-all.h" +//#include "ace/Synch.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -// Forward decl -class ACE_Time_Value; - -/** - * @class ACE_Lock_Adapter - * - * @brief This is an adapter that allows applications to transparently - * combine the <ACE_Lock> abstract base class (which contains - * pure virtual methods) with any of the other concrete ACE - * synchronization classes (e.g., <ACE_Mutex>, <ACE_Semaphore>, - * <ACE_RW_Mutex>, etc.). - * - * This class uses a form of the Adapter pattern. - */ -template <class ACE_LOCKING_MECHANISM> -class ACE_Lock_Adapter : public ACE_Lock -{ -public: - typedef ACE_LOCKING_MECHANISM ACE_LOCK; - - // = Initialization/Finalization methods. - - /// Constructor. All locking requests will be forwarded to <lock>. - ACE_Lock_Adapter (ACE_LOCKING_MECHANISM &lock); - - /// Constructor. Since no lock is provided by the user, one will be - /// created internally. - ACE_Lock_Adapter (void); - - /// Destructor. If <lock_> was not passed in by the user, it will be - /// deleted. - virtual ~ACE_Lock_Adapter (void); - - // = Lock accessors. - /// Block the thread until the lock is acquired. - virtual int acquire (void); - - /// Conditionally acquire the lock (i.e., won't block). - virtual int tryacquire (void); - - /// Release the lock. - virtual int release (void); - - /** - * Block until the thread acquires a read lock. If the locking - * mechanism doesn't support read locks then this just calls - * <acquire>. - */ - virtual int acquire_read (void); - - /** - * Block until the thread acquires a write lock. If the locking - * mechanism doesn't support read locks then this just calls - * <acquire>. - */ - virtual int acquire_write (void); - - /// Conditionally acquire a read lock. If the locking mechanism - /// doesn't support read locks then this just calls <acquire>. - virtual int tryacquire_read (void); - - /// Conditionally acquire a write lock. If the locking mechanism - /// doesn't support read locks then this just calls <acquire>. - virtual int tryacquire_write (void); - - /** - * Conditionally try to upgrade a lock held for read to a write lock. - * If the locking mechanism doesn't support read locks then this just - * calls <acquire>. Returns 0 on success, -1 on failure. - */ - virtual int tryacquire_write_upgrade (void); - - /// Explicitly destroy the lock. - virtual int remove (void); - -private: - /// The concrete locking mechanism that all the methods delegate to. - ACE_LOCKING_MECHANISM *lock_; - - /// This flag keep track of whether we are responsible for deleting - /// the lock - int delete_lock_; -}; - -/** - * @class ACE_Acquire_Method - * - * @brief An enum class. - * - * These enums should have been inside the reverse lock class, but - * some lame compilers cannot handle enums inside template classes. - * - * The METHOD_TYPE is used to indicate which acquire() method will be - * called on the real lock when the release() method is called on the - * reverse lock. REGULAR indicated the acquire() method, READ - * indicates the acquire_read() method, and WRITE indicates the - * acquire_write() method. Note that the try_*() methods are not - * represented here because we have to make sure that the release() - * method on the reverse lock acquires a lock on the real lock. - **/ -class ACE_Acquire_Method -{ -public: - enum METHOD_TYPE - { - ACE_REGULAR, - ACE_READ, - ACE_WRITE - }; -}; - -/** - * @class ACE_Reverse_Lock - * - * @brief A reverse (or anti) lock. - * - * This is an interesting adapter class that changes a lock into - * a reverse lock, i.e., <acquire> on this class calls <release> - * on the lock, and <release> on this class calls <acquire> on - * the lock. - * One motivation for this class is when we temporarily want to - * release a lock (which we have already acquired) but then - * reacquire it soon after. An alternative design would be to - * add a Anti_Guard or Reverse_Guard class which would <release> - * on construction and <acquire> destruction. However, there - * are *many* varieties of the Guard class and this design - * choice would lead to at least 6 new classes. One new - * ACE_Reverse_Lock class seemed more reasonable. - */ -template <class ACE_LOCKING_MECHANISM> -class ACE_Reverse_Lock : public ACE_Lock -{ -public: - - typedef ACE_LOCKING_MECHANISM ACE_LOCK; - - // = Initialization/Finalization methods. - - /// Constructor. All locking requests will be forwarded to <lock>. - ACE_Reverse_Lock (ACE_LOCKING_MECHANISM &lock, - ACE_Acquire_Method::METHOD_TYPE acquire_method = ACE_Acquire_Method::ACE_REGULAR); - - /// Destructor. If <lock_> was not passed in by the user, it will be - /// deleted. - virtual ~ACE_Reverse_Lock (void); - - // = Lock accessors. - /// Release the lock. - virtual int acquire (void); - - /// Release the lock. - virtual int tryacquire (void); - - /// Acquire the lock. - virtual int release (void); - - /// Release the lock. - virtual int acquire_read (void); - - /// Release the lock. - virtual int acquire_write (void); - - /// Release the lock. - virtual int tryacquire_read (void); - - /// Release the lock. - virtual int tryacquire_write (void); - - /// Release the lock. - virtual int tryacquire_write_upgrade (void); - - /// Explicitly destroy the lock. - virtual int remove (void); - -private: - /// The concrete locking mechanism that all the methods delegate to. - ACE_LOCKING_MECHANISM &lock_; - - /// This indicates what kind of acquire method will be called. - ACE_Acquire_Method::METHOD_TYPE acquire_method_; -}; - -/** - * @class ACE_TSS - * - * @brief Allows objects that are "physically" in thread specific - * storage (i.e., private to a thread) to be accessed as though - * they were "logically" global to a program. - * - * This class is a wrapper around the OS thread library - * thread-specific functions. It uses the <C++ operator->> to - * shield applications from the details of accessing - * thread-specific storage. - * - * NOTE: For maximal portability, <TYPE> cannot be a built-in type, - * but instead should be a user-defined class (some compilers will - * allow a built-in type, others won't). See template class - * ACE_TSS_Type_Adapter, below, for adapting built-in types to work - * with ACE_TSS. - */ -template <class TYPE> -class ACE_TSS -{ -public: - // = Initialization and termination methods. - - /** - * If caller has passed us a non-NULL ts_obj *, then we'll just use - * this to initialize the thread-specific value (but only for the - * calling thread). Thus, subsequent calls to <operator->> in this - * thread will return this value. This is useful since it enables - * us to assign objects to thread-specific data that have - * arbitrarily complex constructors. - */ - ACE_TSS (TYPE *ts_obj = 0); - - /// Deregister with thread-key administration. - virtual ~ACE_TSS (void); - - // = Accessors. - - /** - * Get the thread-specific object for the key associated with this - * object. Returns 0 if the data has never been initialized, - * otherwise returns a pointer to the data. - */ - TYPE *ts_object (void) const; - - /// Set the thread-specific object for the key associated with this - /// object. - TYPE *ts_object (TYPE *); - - /// Use a "smart pointer" to get the thread-specific object - /// associated with the <key_>. - TYPE *operator-> () const; - - /// Return or create and return the calling threads TYPE object. - operator TYPE *(void) const; - - /// Hook for construction parameters. - virtual TYPE *make_TSS_TYPE (void) const; - - // = Utility methods. - - /// Dump the state of an object. - void dump (void) const; - - // ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. - -protected: - /// Actually implements the code that retrieves the object from - /// thread-specific storage. - TYPE *ts_get (void) const; - - /// Factors out common code for initializing TSS. This must NOT be - /// called with the lock held... - int ts_init (void) const; - -#if !(defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) - /// This implementation only works for non-threading systems... - TYPE *type_; -#else - /// Avoid race conditions during initialization. - ACE_Thread_Mutex keylock_; - - /// "First time in" flag. - int once_; - - /// Key for the thread-specific error data. - ACE_thread_key_t key_; - - /// "Destructor" that deletes internal TYPE * when thread exits. - static void cleanup (void *ptr); -#endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */ - // = Disallow copying... - ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_TSS<TYPE> &)) - ACE_UNIMPLEMENTED_FUNC (ACE_TSS (const ACE_TSS<TYPE> &)) -}; - -/** - * @class ACE_TSS_Type_Adapter - * - * @brief Adapter that allows built-in types to be used with ACE_TSS. - * - * Wraps a value of a built-in type, providing conversions to - * and from the type. Example use with ACE_TSS: - * ACE_TSS<ACE_TSS_Type_Adapter<int> > i; - * *i = 37; - * ACE_OS::fprintf (stderr, "%d\n", *i); - * Unfortunately, though, some compilers have trouble with the - * implicit type conversions. This seems to work better: - * ACE_TSS<ACE_TSS_Type_Adapter<int> > i; - * i->operator int & () = 37; - * ACE_OS::fprintf (stderr, "%d\n", i->operator int ()); - */ -template <class TYPE> -class ACE_TSS_Type_Adapter -{ -public: - /// Constructor. Inlined here so that it should _always_ be inlined. - ACE_TSS_Type_Adapter (const TYPE value = 0): value_ (value) {} - - /// TYPE conversion. Inlined here so that it should _always_ be - /// inlined. - operator TYPE () const { return value_; }; - - /// TYPE & conversion. Inlined here so that it should _always_ be - /// inlined. - operator TYPE &() { return value_; }; - -private: - /// The wrapped value. - TYPE value_; -}; - -/** - * @class ACE_Guard - * - * @brief This data structure is meant to be used within a method or - * function... It performs automatic aquisition and release of - * a parameterized synchronization object <ACE_LOCK>. - * - * The <ACE_LOCK> class given as an actual parameter must provide at - * the very least the <acquire>, <tryacquire>, <release>, and - * <remove> methods. - */ -template <class ACE_LOCK> -class ACE_Guard -{ -public: - - // = Initialization and termination methods. - ACE_Guard (ACE_LOCK &l); - - /// Implicitly and automatically acquire (or try to acquire) the - /// lock. If <block> is non-0 then <acquire> the <ACE_LOCK>, else - /// <tryacquire> it. - ACE_Guard (ACE_LOCK &l, int block); - - /// Initialise the guard without implicitly acquiring the lock. The - /// <become_owner> parameter indicates whether the guard should release - /// the lock implicitly on destruction. The <block> parameter is - /// ignored and is used here to disambiguate with the preceding - /// constructor. - ACE_Guard (ACE_LOCK &l, int block, int become_owner); - - /// Implicitly release the lock. - ~ACE_Guard (void); - - // = Lock accessors. - - /// Explicitly acquire the lock. - int acquire (void); - - /// Conditionally acquire the lock (i.e., won't block). - int tryacquire (void); - - /// Explicitly release the lock, but only if it is held! - int release (void); - - /// Relinquish ownership of the lock so that it is not released - /// implicitly in the destructor. - void disown (void); - - // = Utility methods. - /// 1 if locked, 0 if couldn't acquire the lock - /// (errno will contain the reason for this). - int locked (void) const; - - /// Explicitly remove the lock. - int remove (void); - - /// Dump the state of an object. - void dump (void) const; - - // ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. - -protected: - - /// Helper, meant for subclass only. - ACE_Guard (ACE_LOCK *lock): lock_ (lock) {} - - /// Pointer to the ACE_LOCK we're guarding. - ACE_LOCK *lock_; - - /// Keeps track of whether we acquired the lock or failed. - int owner_; - -private: - // = Prevent assignment and initialization. - ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Guard<ACE_LOCK> &)) - ACE_UNIMPLEMENTED_FUNC (ACE_Guard (const ACE_Guard<ACE_LOCK> &)) -}; - -/** - * @class ACE_Write_Guard - * - * @brief This class is similar to class <ACE_Guard>, though it - * acquires/releases a write lock automatically (naturally, the - * <ACE_LOCK> it is instantiated with must support the appropriate - * API). - */ -template <class ACE_LOCK> -class ACE_Write_Guard : public ACE_Guard<ACE_LOCK> -{ -public: - // = Initialization method. - - /// Implicitly and automatically acquire a write lock. - ACE_Write_Guard (ACE_LOCK &m); - - /// Implicitly and automatically acquire (or try to acquire) a write - /// lock. - ACE_Write_Guard (ACE_LOCK &m, int block); - - // = Lock accessors. - - /// Explicitly acquire the write lock. - int acquire_write (void); - - /// Explicitly acquire the write lock. - int acquire (void); - - /// Conditionally acquire the write lock (i.e., won't block). - int tryacquire_write (void); - - /// Conditionally acquire the write lock (i.e., won't block). - int tryacquire (void); - - // = Utility methods. - - /// Dump the state of an object. - void dump (void) const; - - // ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. -}; - -/** - * @class ACE_Read_Guard - * - * @brief This class is similar to class <ACE_Guard>, though it - * acquires/releases a read lock automatically (naturally, the - * <ACE_LOCK> it is instantiated with must support the appropriate - * API). - */ -template <class ACE_LOCK> -class ACE_Read_Guard : public ACE_Guard<ACE_LOCK> -{ -public: - // = Initialization methods. - - /// Implicitly and automatically acquire a read lock. - ACE_Read_Guard (ACE_LOCK& m); - - /// Implicitly and automatically acquire (or try to acquire) a read - /// lock. - ACE_Read_Guard (ACE_LOCK &m, int block); - - // = Lock accessors. - - /// Explicitly acquire the read lock. - int acquire_read (void); - - /// Explicitly acquire the read lock. - int acquire (void); - - /// Conditionally acquire the read lock (i.e., won't block). - int tryacquire_read (void); - - /// Conditionally acquire the read lock (i.e., won't block). - int tryacquire (void); - - // = Utility methods. - - /// Dump the state of an object. - void dump (void) const; - - // ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. -}; - -#if !(defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) - -#define ACE_TSS_Guard ACE_Guard -#define ACE_TSS_Write_GUARD ACE_Write_Guard -#define ACE_TSS_Read_GUARD ACE_Read_Guard - -#else - /* ACE platform supports some form of threading and - thread-specific storage. */ - -/** - * @class ACE_TSS_Guard - * - * @brief This data structure is meant to be used within a method or - * function... It performs automatic aquisition and release of - * a synchronization object. Moreover, it ensures that the lock - * is released even if a thread exits via <thr_exit>! - */ -template <class ACE_LOCK> -class ACE_TSS_Guard -{ -public: - // = Initialization and termination methods. - - /// Implicitly and automatically acquire the thread-specific lock. - ACE_TSS_Guard (ACE_LOCK &lock, int block = 1); - - /// Implicitly release the thread-specific lock. - ~ACE_TSS_Guard (void); - - // = Lock accessors. - - /// Explicitly acquire the thread-specific lock. - int acquire (void); - - /// Conditionally acquire the thread-specific lock (i.e., won't - /// block). - int tryacquire (void); - - /// Explicitly release the thread-specific lock. - int release (void); - - // = Utility methods. - /// Explicitly release the thread-specific lock. - int remove (void); - - /// Dump the state of an object. - void dump (void) const; - - // ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. - -protected: - /// Helper, meant for subclass only. - ACE_TSS_Guard (void); - - /// Initialize the key. - void init_key (void); - - /// Called when thread exits to clean up the lock. - static void cleanup (void *ptr); - - /// Thread-specific key... - ACE_thread_key_t key_; - -private: - // = Prevent assignment and initialization. - ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_TSS_Guard<ACE_LOCK> &)) - ACE_UNIMPLEMENTED_FUNC (ACE_TSS_Guard (const ACE_TSS_Guard<ACE_LOCK> &)) -}; - -/** - * @class ACE_TSS_Write_Guard - * - * @brief This class is similar to class ACE_TSS_Guard, though it - * acquires/releases a write-lock automatically (naturally, the - * ACE_LOCK it is instantiated with must support the appropriate - * API). - */ -template <class ACE_LOCK> -class ACE_TSS_Write_Guard : public ACE_TSS_Guard<ACE_LOCK> -{ -public: - // = Initialization method. - - /// Implicitly and automatically acquire the thread-specific write lock. - ACE_TSS_Write_Guard (ACE_LOCK &lock, int block = 1); - - // = Lock accessors. - - /// Explicitly acquire the thread-specific write lock. - int acquire_write (void); - - /// Explicitly acquire the thread-specific write lock. - int acquire (void); - - /// Conditionally acquire the thread-specific write lock (i.e., won't block). - int tryacquire_write (void); - - /// Conditionally acquire the thread-specific write lock (i.e., won't block). - int tryacquire (void); - - // = Utility methods. - - /// Dump the state of an object. - void dump (void) const; - - // ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. -}; - -/** - * @class ACE_TSS_Read_Guard - * - * @brief This class is similar to class <ACE_TSS_Guard>, though it - * acquires/releases a read lock automatically (naturally, the - * <ACE_LOCK> it is instantiated with must support the - * appropriate API). - */ -template <class ACE_LOCK> -class ACE_TSS_Read_Guard : public ACE_TSS_Guard<ACE_LOCK> -{ -public: - // = Initialization method. - /// Implicitly and automatically acquire the thread-specific read lock. - ACE_TSS_Read_Guard (ACE_LOCK &lock, int block = 1); - - // = Lock accessors. - /// Explicitly acquire the thread-specific read lock. - int acquire_read (void); - - /// Explicitly acquire the thread-specific read lock. - int acquire (void); - - /// Conditionally acquire the thread-specific read lock (i.e., won't - /// block). - int tryacquire_read (void); - - /// Conditionally acquire the thread-specific read lock (i.e., won't - /// block). - int tryacquire (void); - - // = Utility methods. - /// Dump the state of an object. - void dump (void) const; - - // ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. -}; -#endif /* !(defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) */ - -#if defined (ACE_HAS_THREADS) /* ACE platform supports some form of threading. */ - -/** - * @class ACE_Condition - * - * @brief ACE_Condition variable wrapper, which allows threads to block - * until shared data changes state. - * - * A condition variable enables threads to atomically block and - * test the condition under the protection of a mutual exclu- - * sion lock (mutex) until the condition is satisfied. That is, - * the mutex must have been held by the thread before calling - * wait or signal on the condition. If the condition is false, - * a thread blocks on a condition variable and atomically - * releases the mutex that is waiting for the condition to - * change. If another thread changes the condition, it may wake - * up waiting threads by signaling the associated condition - * variable. The waiting threads, upon awakening, reacquire the - * mutex and re-evaluate the condition. - * Note, you can only parameterize <ACE_Condition> with - * @a ACE_Thread_Mutex, @a ACE_Recursive_Thread_Mutex, or @a ACE_Null_Mutex. - */ -template <class MUTEX> -class ACE_Condition -{ -public: - // = Initialiation and termination methods. - /// Initialize the condition variable. - ACE_Condition (MUTEX &m, int type = USYNC_THREAD, - const ACE_TCHAR *name = 0, void *arg = 0); - - /// Implicitly destroy the condition variable. - ~ACE_Condition (void); - - // = Lock accessors. - /** - * Block on condition, or until absolute time-of-day has passed. If - * abstime == 0 use "blocking" <wait> semantics. Else, if <abstime> - * != 0 and the call times out before the condition is signaled - * <wait> returns -1 and sets errno to ETIME. - */ - int wait (const ACE_Time_Value *abstime); - - /// Block on condition. - int wait (void); - - /** - * Block on condition or until absolute time-of-day has passed. If - * abstime == 0 use "blocking" wait() semantics on the <mutex> - * passed as a parameter (this is useful if you need to store the - * <Condition> in shared memory). Else, if <abstime> != 0 and the - * call times out before the condition is signaled <wait> returns -1 - * and sets errno to ETIME. - */ - int wait (MUTEX &mutex, const ACE_Time_Value *abstime = 0); - - /// Signal one waiting thread. - int signal (void); - - /// Signal *all* waiting threads. - int broadcast (void); - - // = Utility methods. - /// Explicitly destroy the condition variable. - int remove (void); - - /// Returns a reference to the underlying mutex_; - MUTEX &mutex (void); - - /// Dump the state of an object. - void dump (void) const; - - // ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. - -protected: -#if defined (CHORUS) - /// This condition resides in shared memory. - ACE_cond_t *process_cond_; - - /** - * Remember the name of the condition if we created it so we can - * unlink it when we go away (only the actor that initialized the - * memory can destroy it). - */ - const ACE_TCHAR *condname_; -#endif /* CHORUS */ - - /// Condition variable. - ACE_cond_t cond_; - - /// Reference to mutex lock. - MUTEX &mutex_; - -private: - // = Prevent assignment and initialization. - ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Condition<MUTEX> &)) - ACE_UNIMPLEMENTED_FUNC (ACE_Condition (const ACE_Condition<MUTEX> &)) -}; - -/** - * @class ACE_Thread_Condition - * - * @brief ACE_Condition variable wrapper that works within processes. - * - * A condition variable enables threads to atomically block and - * test the condition under the protection of a mutual exclu- - * sion lock (mutex) until the condition is satisfied. That is, - * the mutex must have been held by the thread before calling - * wait or signal on the condition. If the condition is false, - * a thread blocks on a condition variable and atomically - * releases the mutex that is waiting for the condition to - * change. If another thread changes the condition, it may wake - * up waiting threads by signaling the associated condition - * variable. The waiting threads, upon awakening, reacquire the - * mutex and re-evaluate the condition. - */ -template <class MUTEX> -class ACE_Thread_Condition : public ACE_Condition<MUTEX> -{ -public: - // = Initialization method. - ACE_Thread_Condition (MUTEX &m, const ACE_TCHAR *name = 0, void *arg = 0); - - /// Dump the state of an object. - void dump (void) const; - - // ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. -}; - -#endif /* ACE_HAS_THREADS */ - -#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) - -/** - * @class ACE_NULL_SYNCH - * - * @brief Implement a do nothing Synchronization wrapper that - * typedefs the <ACE_Condition> and <ACE_Mutex> to the Null* versions. - */ -class ACE_Export ACE_NULL_SYNCH -{ -public: - typedef ACE_Null_Mutex MUTEX; - typedef ACE_Null_Mutex NULL_MUTEX; - typedef ACE_Null_Mutex PROCESS_MUTEX; - typedef ACE_Null_Mutex RECURSIVE_MUTEX; - typedef ACE_Null_Mutex RW_MUTEX; - typedef ACE_Null_Condition CONDITION; - typedef ACE_Null_Condition RECURSIVE_CONDITION; - typedef ACE_Null_Semaphore SEMAPHORE; - typedef ACE_Null_Mutex NULL_SEMAPHORE; -}; - -#if defined (ACE_HAS_THREADS) - -class ACE_Process_Mutex; -class ACE_Condition_Recursive_Thread_Mutex; - -/** - * @class ACE_MT_SYNCH - * - * @brief Implement a default thread safe synchronization wrapper that - * typedefs the <ACE_Condition> and <ACE_Mutex> to the - * <ACE_Condition> and <ACE_Mutex> versions. Note that this - * should be a template, but SunC++ 4.0.1 complains about - * this... - */ -class ACE_Export ACE_MT_SYNCH -{ -public: - typedef ACE_Thread_Mutex MUTEX; - typedef ACE_Null_Mutex NULL_MUTEX; - typedef ACE_Process_Mutex PROCESS_MUTEX; - typedef ACE_Recursive_Thread_Mutex RECURSIVE_MUTEX; - typedef ACE_RW_Thread_Mutex RW_MUTEX; - typedef ACE_Condition_Thread_Mutex CONDITION; - typedef ACE_Condition_Recursive_Thread_Mutex RECURSIVE_CONDITION; - typedef ACE_Thread_Semaphore SEMAPHORE; - typedef ACE_Null_Semaphore NULL_SEMAPHORE; -}; - -#endif /* ACE_HAS_THREADS */ - -#define ACE_SYNCH_MUTEX ACE_SYNCH::MUTEX -#define ACE_SYNCH_NULL_MUTEX ACE_SYNCH::NULL_MUTEX -#define ACE_SYNCH_RECURSIVE_MUTEX ACE_SYNCH::RECURSIVE_MUTEX -#define ACE_SYNCH_RW_MUTEX ACE_SYNCH::RW_MUTEX -#define ACE_SYNCH_CONDITION ACE_SYNCH::CONDITION -#define ACE_SYNCH_RECURSIVE_CONDITION ACE_SYNCH::RECURSIVE_CONDITION -#define ACE_SYNCH_NULL_SEMAPHORE ACE_SYNCH::NULL_SEMAPHORE -#define ACE_SYNCH_SEMAPHORE ACE_SYNCH::SEMAPHORE - -#else /* !ACE_HAS_TEMPLATE_TYPEDEFS */ - -#if defined (ACE_HAS_OPTIMIZED_MESSAGE_QUEUE) -#define ACE_NULL_SYNCH ACE_Null_Mutex, ACE_Null_Condition, ACE_Null_Mutex -#define ACE_MT_SYNCH ACE_Thread_Mutex, ACE_Condition_Thread_Mutex, ACE_Thread_Semaphore -#else -#define ACE_NULL_SYNCH ACE_Null_Mutex, ACE_Null_Condition -#define ACE_MT_SYNCH ACE_Thread_Mutex, ACE_Condition_Thread_Mutex -#endif /* ACE_HAS_OPTIMIZED_MESSAGE_QUEUE */ - -#if defined (ACE_HAS_THREADS) - -#define ACE_SYNCH_MUTEX ACE_Thread_Mutex -#define ACE_SYNCH_NULL_MUTEX ACE_Null_Mutex -#define ACE_SYNCH_RECURSIVE_MUTEX ACE_Recursive_Thread_Mutex -#define ACE_SYNCH_RW_MUTEX ACE_RW_Thread_Mutex -#define ACE_SYNCH_CONDITION ACE_Condition_Thread_Mutex -#define ACE_SYNCH_RECURSIVE_CONDITION ACE_Condition_Recursive_Thread_Mutex -#define ACE_SYNCH_SEMAPHORE ACE_Thread_Semaphore -#define ACE_SYNCH_NULL_SEMAPHORE ACE_Null_Semaphore - -#else /* ACE_HAS_THREADS */ - -#define ACE_SYNCH_MUTEX ACE_Null_Mutex -#define ACE_SYNCH_NULL_MUTEX ACE_Null_Mutex -#define ACE_SYNCH_RECURSIVE_MUTEX ACE_Null_Mutex -#define ACE_SYNCH_RW_MUTEX ACE_Null_Mutex -#define ACE_SYNCH_CONDITION ACE_Null_Condition -#define ACE_SYNCH_RECURSIVE_CONDITION ACE_Null_Condition -#define ACE_SYNCH_SEMAPHORE ACE_Null_Semaphore -#define ACE_SYNCH_NULL_SEMAPHORE ACE_Null_Mutex - -#endif /* ACE_HAS_THREADS */ -#endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ - -// These are available on *all* platforms -#define ACE_SYNCH_PROCESS_SEMAPHORE ACE_Process_Semaphore -#define ACE_SYNCH_PROCESS_MUTEX ACE_Process_Mutex - -#if defined (ACE_HAS_THREADS) -#define ACE_SYNCH ACE_MT_SYNCH -#else /* ACE_HAS_THREADS */ -#define ACE_SYNCH ACE_NULL_SYNCH -#endif /* ACE_HAS_THREADS */ +#include "ace/Lock.h" +#include "ace/Thread_Mutex.h" +#include "ace/Thread_Semaphore.h" +#include "ace/Recursive_Thread_Mutex.h" +#include "ace/RW_Thread_Mutex.h" +#include "ace/Null_Mutex.h" +#include "ace/Null_Condition.h" +#include "ace/Null_Semaphore.h" + +#include "ace/Lock_Adapter_T.h" +#include "ace/Reverse_Lock_T.h" +#include "ace/Guard_T.h" +#include "ace/TSS_T.h" +#include "ace/Condition_T.h" +#include "ace/Synch_Traits.h" #if defined (__ACE_INLINE__) #include "ace/Synch_T.i" diff --git a/ace/Synch_T.i b/ace/Synch_T.i index 50cd0a710e9..6318deb79a0 100644 --- a/ace/Synch_T.i +++ b/ace/Synch_T.i @@ -1,452 +1,2 @@ /* -*- C++ -*- */ // $Id$ - -#include "ace/Thread.h" - -template <class ACE_LOCK> ACE_INLINE int -ACE_Guard<ACE_LOCK>::acquire (void) -{ - return this->owner_ = this->lock_->acquire (); -} - -template <class ACE_LOCK> ACE_INLINE int -ACE_Guard<ACE_LOCK>::tryacquire (void) -{ - return this->owner_ = this->lock_->tryacquire (); -} - -template <class ACE_LOCK> ACE_INLINE int -ACE_Guard<ACE_LOCK>::release (void) -{ - if (this->owner_ == -1) - return -1; - else - { - this->owner_ = -1; - return this->lock_->release (); - } -} - -template <class ACE_LOCK> ACE_INLINE -ACE_Guard<ACE_LOCK>::ACE_Guard (ACE_LOCK &l) - : lock_ (&l), - owner_ (0) -{ - this->acquire (); -} - -template <class ACE_LOCK> ACE_INLINE -ACE_Guard<ACE_LOCK>::ACE_Guard (ACE_LOCK &l, int block) - : lock_ (&l), - owner_ (0) -{ - if (block) - this->acquire (); - else - this->tryacquire (); -} - -template <class ACE_LOCK> ACE_INLINE -ACE_Guard<ACE_LOCK>::ACE_Guard (ACE_LOCK &l, int block, int become_owner) - : lock_ (&l), - owner_ (become_owner == 0 ? -1 : 0) -{ - ACE_UNUSED_ARG (block); -} - -// Implicitly and automatically acquire (or try to acquire) the -// lock. - -template <class ACE_LOCK> ACE_INLINE -ACE_Guard<ACE_LOCK>::~ACE_Guard (void) -{ - this->release (); -} - -template <class ACE_LOCK> ACE_INLINE int -ACE_Guard<ACE_LOCK>::locked (void) const -{ - return this->owner_ != -1; -} - -template <class ACE_LOCK> ACE_INLINE int -ACE_Guard<ACE_LOCK>::remove (void) -{ - return this->lock_->remove (); -} - -template <class ACE_LOCK> ACE_INLINE void -ACE_Guard<ACE_LOCK>::disown (void) -{ - this->owner_ = -1; -} - -template <class ACE_LOCK> ACE_INLINE -ACE_Write_Guard<ACE_LOCK>::ACE_Write_Guard (ACE_LOCK &m) - : ACE_Guard<ACE_LOCK> (&m) -{ - this->acquire_write (); -} - -template <class ACE_LOCK> ACE_INLINE int -ACE_Write_Guard<ACE_LOCK>::acquire_write (void) -{ - return this->owner_ = this->lock_->acquire_write (); -} - -template <class ACE_LOCK> ACE_INLINE int -ACE_Write_Guard<ACE_LOCK>::acquire (void) -{ - return this->owner_ = this->lock_->acquire_write (); -} - -template <class ACE_LOCK> ACE_INLINE int -ACE_Write_Guard<ACE_LOCK>::tryacquire_write (void) -{ - return this->owner_ = this->lock_->tryacquire_write (); -} - -template <class ACE_LOCK> ACE_INLINE int -ACE_Write_Guard<ACE_LOCK>::tryacquire (void) -{ - return this->owner_ = this->lock_->tryacquire_write (); -} - -template <class ACE_LOCK> ACE_INLINE -ACE_Write_Guard<ACE_LOCK>::ACE_Write_Guard (ACE_LOCK &m, - int block) - : ACE_Guard<ACE_LOCK> (&m) -{ - if (block) - this->acquire_write (); - else - this->tryacquire_write (); -} - -template <class ACE_LOCK> ACE_INLINE int -ACE_Read_Guard<ACE_LOCK>::acquire_read (void) -{ - return this->owner_ = this->lock_->acquire_read (); -} - -template <class ACE_LOCK> ACE_INLINE int -ACE_Read_Guard<ACE_LOCK>::acquire (void) -{ - return this->owner_ = this->lock_->acquire_read (); -} - -template <class ACE_LOCK> ACE_INLINE int -ACE_Read_Guard<ACE_LOCK>::tryacquire_read (void) -{ - return this->owner_ = this->lock_->tryacquire_read (); -} - -template <class ACE_LOCK> ACE_INLINE int -ACE_Read_Guard<ACE_LOCK>::tryacquire (void) -{ - return this->owner_ = this->lock_->tryacquire_read (); -} - -template <class ACE_LOCK> ACE_INLINE -ACE_Read_Guard<ACE_LOCK>::ACE_Read_Guard (ACE_LOCK &m) - : ACE_Guard<ACE_LOCK> (&m) -{ - this->acquire_read (); -} - -template <class ACE_LOCK> ACE_INLINE -ACE_Read_Guard<ACE_LOCK>::ACE_Read_Guard (ACE_LOCK &m, - int block) - : ACE_Guard<ACE_LOCK> (&m) -{ - if (block) - this->acquire_read (); - else - this->tryacquire_read (); -} - -template <class ACE_LOCKING_MECHANISM> ACE_INLINE -ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::ACE_Lock_Adapter (ACE_LOCKING_MECHANISM &lock) - : lock_ (&lock), - delete_lock_ (0) -{ -} - -template <class ACE_LOCKING_MECHANISM> ACE_INLINE -ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::~ACE_Lock_Adapter (void) -{ - if (this->delete_lock_) - delete this->lock_; -} - -// Explicitly destroy the lock. -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::remove (void) -{ - return this->lock_->remove (); -} - -// Block the thread until the lock is acquired. -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::acquire (void) -{ - return this->lock_->acquire (); -} - -// Conditionally acquire the lock (i.e., won't block). - -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::tryacquire (void) -{ - return this->lock_->tryacquire (); -} - -// Release the lock. - -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::release (void) -{ - return this->lock_->release (); -} - -// Block until the thread acquires a read lock. If the locking -// mechanism doesn't support read locks then this just calls -// <acquire>. - -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::acquire_read (void) -{ - return this->lock_->acquire_read (); -} - -// Block until the thread acquires a write lock. If the locking -// mechanism doesn't support read locks then this just calls -// <acquire>. - -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::acquire_write (void) -{ - return this->lock_->acquire_write (); -} - -// Conditionally acquire a read lock. If the locking mechanism -// doesn't support read locks then this just calls <acquire>. - -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::tryacquire_read (void) -{ - return this->lock_->tryacquire_read (); -} - -// Conditionally acquire a write lock. If the locking mechanism -// doesn't support write locks then this just calls <acquire>. - -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::tryacquire_write (void) -{ - return this->lock_->tryacquire_write (); -} - -// Conditionally try to upgrade a lock held for read to a write lock. -// If the locking mechanism doesn't support read locks then this just -// calls <acquire>. Returns 0 on success, -1 on failure. - -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Lock_Adapter<ACE_LOCKING_MECHANISM>::tryacquire_write_upgrade (void) -{ - return this->lock_->tryacquire_write_upgrade (); -} - -template <class ACE_LOCKING_MECHANISM> ACE_INLINE -ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::ACE_Reverse_Lock (ACE_LOCKING_MECHANISM &lock, - ACE_Acquire_Method::METHOD_TYPE acquire_method) - : lock_ (lock), - acquire_method_ (acquire_method) -{ -} - -// Explicitly destroy the lock. -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::remove (void) -{ - return this->lock_.remove (); -} - -// Release the lock. -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::acquire (void) -{ - return this->lock_.release (); -} - -// Release the lock. -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::tryacquire (void) -{ - ACE_NOTSUP_RETURN (-1); -} - -// Acquire the lock. -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::release (void) -{ - if (this->acquire_method_ == ACE_Acquire_Method::ACE_READ) - return this->lock_.acquire_read (); - else if (this->acquire_method_ == ACE_Acquire_Method::ACE_WRITE) - return this->lock_.acquire_write (); - else - return this->lock_.acquire (); -} - -// Release the lock. -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::acquire_read (void) -{ - ACE_NOTSUP_RETURN (-1); -} - -// Release the lock. -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::acquire_write (void) -{ - ACE_NOTSUP_RETURN (-1); -} - -// Release the lock. -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::tryacquire_read (void) -{ - ACE_NOTSUP_RETURN (-1); -} - -// Release the lock. -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::tryacquire_write (void) -{ - ACE_NOTSUP_RETURN (-1); -} - -// Release the lock. -template <class ACE_LOCKING_MECHANISM> ACE_INLINE int -ACE_Reverse_Lock<ACE_LOCKING_MECHANISM>::tryacquire_write_upgrade (void) -{ - ACE_NOTSUP_RETURN (-1); -} - -#if defined (ACE_HAS_THREADS) - -template<class MUTEX> ACE_INLINE int -ACE_Condition<MUTEX>::remove (void) -{ - // ACE_TRACE ("ACE_Condition<MUTEX>::remove"); - - // cond_destroy() is called in a loop if the condition variable is - // BUSY. This avoids a condition where a condition is signaled and - // because of some timing problem, the thread that is to be signaled - // has called the cond_wait routine after the signal call. Since - // the condition signal is not queued in any way, deadlock occurs. - - int result = 0; - -#if defined (CHORUS) - // Are we the owner? - if (this->process_cond_ && this->condname_) - { - // Only destroy the condition if we're the ones who initialized - // it. - while ((result = ACE_OS::cond_destroy (this->process_cond_)) == -1 - && errno == EBUSY) - { - ACE_OS::cond_broadcast (this->process_cond_); - ACE_OS::thr_yield (); - } - ACE_OS::munmap (this->process_cond_, - sizeof (ACE_cond_t)); - ACE_OS::shm_unlink (this->condname_); - ACE_OS::free (ACE_static_cast (void *, - ACE_const_cast (ACE_TCHAR *, - this->condname_))); - } - else if (this->process_cond_) - { - ACE_OS::munmap (this->process_cond_, - sizeof (ACE_cond_t)); - result = 0; - } - else -#endif /* CHORUS */ - - while ((result = ACE_OS::cond_destroy (&this->cond_)) == -1 - && errno == EBUSY) - { - ACE_OS::cond_broadcast (&this->cond_); - ACE_OS::thr_yield (); - } - - return result; -} - -template<class MUTEX> ACE_INLINE MUTEX & -ACE_Condition<MUTEX>::mutex (void) -{ - // ACE_TRACE ("ACE_Condition<MUTEX>::mutex"); - return this->mutex_; -} - -template <class MUTEX> ACE_INLINE int -ACE_Condition<MUTEX>::signal (void) -{ -// ACE_TRACE ("ACE_Condition<MUTEX>::signal"); -#if defined (CHORUS) - if (this->process_cond_ != 0) - return ACE_OS::cond_signal (this->process_cond_); -#endif /* CHORUS */ - return ACE_OS::cond_signal (&this->cond_); -} - -template <class MUTEX> ACE_INLINE int -ACE_Condition<MUTEX>::broadcast (void) -{ -// ACE_TRACE ("ACE_Condition<MUTEX>::broadcast"); -#if defined (CHORUS) - if (this->process_cond_ != 0) - return ACE_OS::cond_broadcast (this->process_cond_); -#endif /* CHORUS */ - return ACE_OS::cond_broadcast (&this->cond_); -} - -#endif /* ACE_HAS_THREADS */ - -#if !(defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) -template <class TYPE> ACE_INLINE -ACE_TSS<TYPE>::ACE_TSS (TYPE *type) - : type_ (type) -{ -} - -template <class TYPE> ACE_INLINE int -ACE_TSS<TYPE>::ts_init (void) const -{ - return 0; -} - -template <class TYPE> ACE_INLINE TYPE * -ACE_TSS<TYPE>::ts_object (void) const -{ - return this->type_; -} - -template <class TYPE> ACE_INLINE TYPE * -ACE_TSS<TYPE>::ts_object (TYPE *type) -{ - this->type_ = type; - return this->type_; -} - -template <class TYPE> ACE_INLINE TYPE * -ACE_TSS<TYPE>::ts_get (void) const -{ - return this->type_; -} - -#endif /* ! (defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) */ diff --git a/ace/Synch_Traits.h b/ace/Synch_Traits.h new file mode 100644 index 00000000000..092098643c9 --- /dev/null +++ b/ace/Synch_Traits.h @@ -0,0 +1,145 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Synch_Traits.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_SYNCH_TRAITS_H +#define ACE_SYNCH_TRAITS_H +#include /**/ "ace/pre.h" + +#include "ace/Lock.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +// Forward decl +class ACE_Null_Mutex; +class ACE_Null_Condition; +class ACE_Null_Semaphore; +class ACE_Null_Mutex; +class ACE_Thread_Mutex; +class ACE_Process_Mutex; +class ACE_Recursive_Thread_Mutex; +class ACE_RW_Thread_Mutex; +class ACE_Condition_Thread_Mutex; +class ACE_Condition_Recursive_Thread_Mutex; +class ACE_Thread_Semaphore; + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) + +/** + * @class ACE_NULL_SYNCH + * + * @brief Implement a do nothing Synchronization wrapper that + * typedefs the <ACE_Condition> and <ACE_Mutex> to the Null* versions. + */ +class ACE_Export ACE_NULL_SYNCH +{ +public: + typedef ACE_Null_Mutex MUTEX; + typedef ACE_Null_Mutex NULL_MUTEX; + typedef ACE_Null_Mutex PROCESS_MUTEX; + typedef ACE_Null_Mutex RECURSIVE_MUTEX; + typedef ACE_Null_Mutex RW_MUTEX; + typedef ACE_Null_Condition CONDITION; + typedef ACE_Null_Condition RECURSIVE_CONDITION; + typedef ACE_Null_Semaphore SEMAPHORE; + typedef ACE_Null_Mutex NULL_SEMAPHORE; +}; + +#if defined (ACE_HAS_THREADS) + +class ACE_Process_Mutex; +class ACE_Condition_Recursive_Thread_Mutex; + +/** + * @class ACE_MT_SYNCH + * + * @brief Implement a default thread safe synchronization wrapper that + * typedefs the <ACE_Condition> and <ACE_Mutex> to the + * <ACE_Condition> and <ACE_Mutex> versions. Note that this + * should be a template, but SunC++ 4.0.1 complains about + * this... + */ +class ACE_Export ACE_MT_SYNCH +{ +public: + typedef ACE_Thread_Mutex MUTEX; + typedef ACE_Null_Mutex NULL_MUTEX; + typedef ACE_Process_Mutex PROCESS_MUTEX; + typedef ACE_Recursive_Thread_Mutex RECURSIVE_MUTEX; + typedef ACE_RW_Thread_Mutex RW_MUTEX; + typedef ACE_Condition_Thread_Mutex CONDITION; + typedef ACE_Condition_Recursive_Thread_Mutex RECURSIVE_CONDITION; + typedef ACE_Thread_Semaphore SEMAPHORE; + typedef ACE_Null_Semaphore NULL_SEMAPHORE; +}; + +#endif /* ACE_HAS_THREADS */ + +#define ACE_SYNCH_MUTEX ACE_SYNCH::MUTEX +#define ACE_SYNCH_NULL_MUTEX ACE_SYNCH::NULL_MUTEX +#define ACE_SYNCH_RECURSIVE_MUTEX ACE_SYNCH::RECURSIVE_MUTEX +#define ACE_SYNCH_RW_MUTEX ACE_SYNCH::RW_MUTEX +#define ACE_SYNCH_CONDITION ACE_SYNCH::CONDITION +#define ACE_SYNCH_RECURSIVE_CONDITION ACE_SYNCH::RECURSIVE_CONDITION +#define ACE_SYNCH_NULL_SEMAPHORE ACE_SYNCH::NULL_SEMAPHORE +#define ACE_SYNCH_SEMAPHORE ACE_SYNCH::SEMAPHORE + +#else /* !ACE_HAS_TEMPLATE_TYPEDEFS */ + +#if defined (ACE_HAS_OPTIMIZED_MESSAGE_QUEUE) +#define ACE_NULL_SYNCH ACE_Null_Mutex, ACE_Null_Condition, ACE_Null_Mutex +#define ACE_MT_SYNCH ACE_Thread_Mutex, ACE_Condition_Thread_Mutex, ACE_Thread_Semaphore +#else +#define ACE_NULL_SYNCH ACE_Null_Mutex, ACE_Null_Condition +#define ACE_MT_SYNCH ACE_Thread_Mutex, ACE_Condition_Thread_Mutex +#endif /* ACE_HAS_OPTIMIZED_MESSAGE_QUEUE */ + +#if defined (ACE_HAS_THREADS) + +#define ACE_SYNCH_MUTEX ACE_Thread_Mutex +#define ACE_SYNCH_NULL_MUTEX ACE_Null_Mutex +#define ACE_SYNCH_RECURSIVE_MUTEX ACE_Recursive_Thread_Mutex +#define ACE_SYNCH_RW_MUTEX ACE_RW_Thread_Mutex +#define ACE_SYNCH_CONDITION ACE_Condition_Thread_Mutex +#define ACE_SYNCH_RECURSIVE_CONDITION ACE_Condition_Recursive_Thread_Mutex +#define ACE_SYNCH_SEMAPHORE ACE_Thread_Semaphore +#define ACE_SYNCH_NULL_SEMAPHORE ACE_Null_Semaphore + +#else /* ACE_HAS_THREADS */ + +#define ACE_SYNCH_MUTEX ACE_Null_Mutex +#define ACE_SYNCH_NULL_MUTEX ACE_Null_Mutex +#define ACE_SYNCH_RECURSIVE_MUTEX ACE_Null_Mutex +#define ACE_SYNCH_RW_MUTEX ACE_Null_Mutex +#define ACE_SYNCH_CONDITION ACE_Null_Condition +#define ACE_SYNCH_RECURSIVE_CONDITION ACE_Null_Condition +#define ACE_SYNCH_SEMAPHORE ACE_Null_Semaphore +#define ACE_SYNCH_NULL_SEMAPHORE ACE_Null_Mutex + +#endif /* ACE_HAS_THREADS */ +#endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ + +// These are available on *all* platforms +#define ACE_SYNCH_PROCESS_SEMAPHORE ACE_Process_Semaphore +#define ACE_SYNCH_PROCESS_MUTEX ACE_Process_Mutex + +#if defined (ACE_HAS_THREADS) +#define ACE_SYNCH ACE_MT_SYNCH +#else /* ACE_HAS_THREADS */ +#define ACE_SYNCH ACE_NULL_SYNCH +#endif /* ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_SYNCH_TRAITS_H */ diff --git a/ace/System_Time.h b/ace/System_Time.h index f41d7cc02aa..242c944617c 100644 --- a/ace/System_Time.h +++ b/ace/System_Time.h @@ -25,6 +25,7 @@ #include "ace/Memory_Pool.h" #include "ace/Malloc_T.h" +#include "ace/Null_Mutex.h" /** * @class ACE_System_Time diff --git a/ace/TSS_Adapter.cpp b/ace/TSS_Adapter.cpp new file mode 100644 index 00000000000..cbddcd752a6 --- /dev/null +++ b/ace/TSS_Adapter.cpp @@ -0,0 +1,47 @@ +/* -*- C++ -*- */ +/** + * @file TSS_Adapter.cpp + * + * $Id$ + * + * Originally in Synch.cpp + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ + +#include "ace/TSS_Adapter.h" + +#if !defined (__ACE_INLINE__) +#include "ace/TSS_Adapter.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, TSS_Adapter, "$Id$") + +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::cleanup"); + (*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; + } +} + diff --git a/ace/TSS_Adapter.h b/ace/TSS_Adapter.h new file mode 100644 index 00000000000..8fd09f2dd26 --- /dev/null +++ b/ace/TSS_Adapter.h @@ -0,0 +1,64 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file TSS_Adapter.h + * + * $Id$ + * + * Originally in Synch.h + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_TSS_ADAPTER_H +#define ACE_TSS_ADAPTER_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class ACE_TSS_Adapter + * + * @brief 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. + * + * 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_. + */ +class ACE_Export ACE_TSS_Adapter +{ +public: + /// Initialize the adapter. + ACE_TSS_Adapter (void *object, ACE_THR_DEST f); + + /// Default dtor. + ~ACE_TSS_Adapter (void); + + /// Perform the cleanup operation. + void cleanup (void); + +//private: + + /// The real TS object. + void *ts_obj_; + + /// The real cleanup routine for ts_obj; + ACE_THR_DEST func_; +}; + +#if defined (__ACE_INLINE__) +#include "ace/TSS_Adapter.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_TSS_ADAPTER_H */ diff --git a/ace/TSS_Adapter.inl b/ace/TSS_Adapter.inl new file mode 100644 index 00000000000..59651ec36f8 --- /dev/null +++ b/ace/TSS_Adapter.inl @@ -0,0 +1,7 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_TSS_Adapter::~ACE_TSS_Adapter (void) +{ +} diff --git a/ace/TSS_T.cpp b/ace/TSS_T.cpp new file mode 100644 index 00000000000..db2eb5a56aa --- /dev/null +++ b/ace/TSS_T.cpp @@ -0,0 +1,683 @@ +// $Id$ + +#ifndef ACE_TSS_T_C +#define ACE_TSS_T_C + +#include "ace/TSS_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +ACE_RCSID(ace, TSS_T, "$Id$") + +#if defined (__ACE_INLINE__) +#include "ace/TSS_T.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/Thread.h" +#include "ace/Log_Msg.h" +#include "ace/Guard_T.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_TSS) + +template <class TYPE> +ACE_TSS<TYPE>::~ACE_TSS (void) +{ + // We can't call <ACE_OS::thr_keyfree> until *all* of the threads + // that are using that key have done an <ACE_OS::thr_key_detach>. + // Otherwise, we'll end up with "dangling TSS pointers." + ACE_OS::thr_key_detach (this); +} + +template <class TYPE> TYPE * +ACE_TSS<TYPE>::operator-> () const +{ + return this->ts_get (); +} + +template <class TYPE> +ACE_TSS<TYPE>::operator TYPE *(void) const +{ + return this->ts_get (); +} + +template <class TYPE> TYPE * +ACE_TSS<TYPE>::make_TSS_TYPE (void) const +{ + TYPE *temp = 0; + ACE_NEW_RETURN (temp, + TYPE, + 0); + return temp; +} + +template <class TYPE> void +ACE_TSS<TYPE>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_TSS<TYPE>::dump"); +#if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->keylock_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("key_ = %d\n"), this->key_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nonce_ = %d"), this->once_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */ +#endif /* ACE_HAS_DUMP */ +} + +#if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) +#if defined (ACE_HAS_THR_C_DEST) +extern "C" void ACE_TSS_C_cleanup(void *); // defined in Synch.cpp +#endif /* ACE_HAS_THR_C_DEST */ + +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> int +ACE_TSS<TYPE>::ts_init (void) const +{ + // Insure that we are serialized! + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, (ACE_Thread_Mutex &) this->keylock_, 0); + + // Use the Double-Check pattern to make sure we only create the key + // once! + if (this->once_ == 0) + { + if (ACE_Thread::keycreate (ACE_const_cast (ACE_thread_key_t *, &this->key_), +#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 -1; // Major problems, this should *never* happen! + else + { + // This *must* come last to avoid race conditions! Note that + // we need to "cast away const..." + * ACE_const_cast (int*, &this->once_) = 1; + return 0; + } + } + + return -1; +} + +template <class TYPE> +ACE_TSS<TYPE>::ACE_TSS (TYPE *ts_obj) + : once_ (0), + key_ (ACE_OS::NULL_key) +{ + // If caller has passed us a non-NULL TYPE *, then we'll just use + // this to initialize the thread-specific value. Thus, subsequent + // calls to operator->() will return this value. This is useful + // since it enables us to assign objects to thread-specific data + // that have arbitrarily complex constructors! + + if (ts_obj != 0) + { + if (this->ts_init () == -1) + { + // Save/restore errno. + ACE_Errno_Guard error (errno); + // What should we do if this call fails?! +#if defined (ACE_HAS_WINCE) + ::MessageBox (0, + L"ACE_Thread::keycreate() failed!", + L"ACE_TSS::ACE_TSS", + MB_OK); +#else + ACE_OS::fprintf (stderr, + "ACE_Thread::keycreate() failed!"); +#endif /* ACE_HAS_WINCE */ + return; + } + +#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, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("ACE_Thread::setspecific() failed!"))); + } +#else + if (ACE_Thread::setspecific (this->key_, + (void *) ts_obj) != 0) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("ACE_Thread::setspecific() failed!"))); +#endif /* ACE_HAS_THR_C_DEST */ + } +} + +template <class TYPE> TYPE * +ACE_TSS<TYPE>::ts_get (void) const +{ + if (this->once_ == 0) + // Create and initialize thread-specific ts_obj. + this->ts_init (); + + 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) + return 0; // This should not happen! + + // 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...). + + ts_obj = this->make_TSS_TYPE (); + + 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) + { + 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 the underlying ts object. + return (TYPE *) tss_adapter->ts_obj_; +#else + return ts_obj; +#endif /* ACE_HAS_THR_C_DEST */ +} + +// Get the thread-specific object for the key associated with this +// object. Returns 0 if the ts_obj has never been initialized, +// otherwise returns a pointer to the ts_obj. + +template <class TYPE> TYPE * +ACE_TSS<TYPE>::ts_object (void) const +{ + // Ensure that we are serialized! + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, (ACE_Thread_Mutex &) this->keylock_, 0); + + if (this->once_ == 0) // Return 0 if we've never been initialized. + return 0; + + 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! +#endif /* ACE_HAS_THR_C_DEST */ + + return ts_obj; +} + +template <class TYPE> TYPE * +ACE_TSS<TYPE>::ts_object (TYPE *new_ts_obj) +{ + // Note, we shouldn't hold the keylock at this point because + // <ts_init> does it for us and we'll end up with deadlock + // otherwise... + if (this->once_ == 0) + // Create and initialize thread-specific ts_obj. + this->ts_init (); + + // Ensure that we are serialized! + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->keylock_, 0); + + 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! + if (ACE_Thread::setspecific (this->key_, + (void *) new_ts_obj) == -1) + return ts_obj; // This should not happen! +#endif /* ACE_HAS_THR_C_DEST */ + + return ts_obj; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_TSS_Guard) + +template <class ACE_LOCK> void +ACE_TSS_Guard<ACE_LOCK>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("key_ = %d"), this->key_)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +template <class ACE_LOCK> void +ACE_TSS_Guard<ACE_LOCK>::init_key (void) +{ +// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::init_key"); + + 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<ACE_LOCK>::cleanup, +#endif /* ACE_HAS_THR_C_DEST */ + (void *) this); +} + +template <class ACE_LOCK> +ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard (void) +{ +// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard"); + this->init_key (); +} + +template <class ACE_LOCK> int +ACE_TSS_Guard<ACE_LOCK>::release (void) +{ +// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::release"); + + ACE_Guard<ACE_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<ACE_LOCK> *)tss_adapter->ts_obj_; +#else + ACE_Thread::getspecific (this->key_, + (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + + return guard->release (); +} + +template <class ACE_LOCK> int +ACE_TSS_Guard<ACE_LOCK>::remove (void) +{ +// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::remove"); + + ACE_Guard<ACE_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<ACE_LOCK> *) tss_adapter->ts_obj_; +#else + ACE_Thread::getspecific (this->key_, + (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + + return guard->remove (); +} + +template <class ACE_LOCK> +ACE_TSS_Guard<ACE_LOCK>::~ACE_TSS_Guard (void) +{ +// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::~ACE_TSS_Guard"); + + ACE_Guard<ACE_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<ACE_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_); + // Destructor releases lock. + delete guard; +} + +template <class ACE_LOCK> void +ACE_TSS_Guard<ACE_LOCK>::cleanup (void *ptr) +{ +// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::cleanup"); + + // Destructor releases lock. + delete (ACE_Guard<ACE_LOCK> *) ptr; +} + +template <class ACE_LOCK> +ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard (ACE_LOCK &lock, int block) +{ +// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::ACE_TSS_Guard"); + + this->init_key (); + ACE_Guard<ACE_LOCK> *guard; + ACE_NEW (guard, + ACE_Guard<ACE_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<ACE_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 ACE_LOCK> int +ACE_TSS_Guard<ACE_LOCK>::acquire (void) +{ +// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::acquire"); + + ACE_Guard<ACE_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<ACE_LOCK> *) tss_adapter->ts_obj_; +#else + ACE_Thread::getspecific (this->key_, + (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + + return guard->acquire (); +} + +template <class ACE_LOCK> int +ACE_TSS_Guard<ACE_LOCK>::tryacquire (void) +{ +// ACE_TRACE ("ACE_TSS_Guard<ACE_LOCK>::tryacquire"); + + ACE_Guard<ACE_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<ACE_LOCK> *) tss_adapter->ts_obj_; +#else + ACE_Thread::getspecific (this->key_, + (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + + return guard->tryacquire (); +} + +template <class ACE_LOCK> +ACE_TSS_Write_Guard<ACE_LOCK>::ACE_TSS_Write_Guard (ACE_LOCK &lock, + int block) +{ +// ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::ACE_TSS_Write_Guard"); + + this->init_key (); + ACE_Guard<ACE_LOCK> *guard; + ACE_NEW (guard, + ACE_Write_Guard<ACE_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<ACE_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 ACE_LOCK> int +ACE_TSS_Write_Guard<ACE_LOCK>::acquire (void) +{ +// ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::acquire"); + + ACE_Write_Guard<ACE_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<ACE_LOCK> *) tss_adapter->ts_obj_; +#else + ACE_Thread::getspecific (this->key_, + (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + + return guard->acquire_write (); +} + +template <class ACE_LOCK> int +ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire (void) +{ +// ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire"); + + ACE_Write_Guard<ACE_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<ACE_LOCK> *) tss_adapter->ts_obj_; +#else + ACE_Thread::getspecific (this->key_, + (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + + return guard->tryacquire_write (); +} + +template <class ACE_LOCK> int +ACE_TSS_Write_Guard<ACE_LOCK>::acquire_write (void) +{ +// ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::acquire_write"); + + return this->acquire (); +} + +template <class ACE_LOCK> int +ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire_write (void) +{ +// ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::tryacquire_write"); + + return this->tryacquire (); +} + +template <class ACE_LOCK> void +ACE_TSS_Write_Guard<ACE_LOCK>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_TSS_Write_Guard<ACE_LOCK>::dump"); + ACE_TSS_Guard<ACE_LOCK>::dump (); +#endif /* ACE_HAS_DUMP */ +} + +template <class ACE_LOCK> +ACE_TSS_Read_Guard<ACE_LOCK>::ACE_TSS_Read_Guard (ACE_LOCK &lock, int block) +{ +// ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::ACE_TSS_Read_Guard"); + + this->init_key (); + ACE_Guard<ACE_LOCK> *guard; + ACE_NEW (guard, + ACE_Read_Guard<ACE_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<ACE_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 ACE_LOCK> int +ACE_TSS_Read_Guard<ACE_LOCK>::acquire (void) +{ +// ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::acquire"); + + ACE_Read_Guard<ACE_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<ACE_LOCK> *) tss_adapter->ts_obj_; +#else + ACE_Thread::getspecific (this->key_, + (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + + return guard->acquire_read (); +} + +template <class ACE_LOCK> int +ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire (void) +{ +// ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire"); + + ACE_Read_Guard<ACE_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<ACE_LOCK> *) tss_adapter->ts_obj_; +#else + ACE_Thread::getspecific (this->key_, + (void **) &guard); +#endif /* ACE_HAS_THR_C_DEST */ + + return guard->tryacquire_read (); +} + +template <class ACE_LOCK> int +ACE_TSS_Read_Guard<ACE_LOCK>::acquire_read (void) +{ +// ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::acquire_read"); + + return this->acquire (); +} + +template <class ACE_LOCK> int +ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire_read (void) +{ +// ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::tryacquire_read"); + + return this->tryacquire (); +} + +template <class ACE_LOCK> void +ACE_TSS_Read_Guard<ACE_LOCK>::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_TSS_Read_Guard<ACE_LOCK>::dump"); + ACE_TSS_Guard<ACE_LOCK>::dump (); +#endif /* ACE_HAS_DUMP */ +} + + +#endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */ + +#endif /* ACE_TSS_T_C */ diff --git a/ace/TSS_T.h b/ace/TSS_T.h new file mode 100644 index 00000000000..8ed8209c254 --- /dev/null +++ b/ace/TSS_T.h @@ -0,0 +1,187 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file TSS_T.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_TSS_T_H +#define ACE_TSS_T_H +#include /**/ "ace/pre.h" + +#include "ace/Lock.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Thread_Mutex.h" + +// This should probably go somewhere else, but it's only used here and in Thread_Manager. +# if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) +# define ACE_TSS_TYPE(T) ACE_TSS< T > +# if defined (ACE_HAS_BROKEN_CONVERSIONS) +# define ACE_TSS_GET(I, T) (*(I)) +# else +# define ACE_TSS_GET(I, T) ((I)->operator T * ()) +# endif /* ACE_HAS_BROKEN_CONVERSIONS */ +# else +# define ACE_TSS_TYPE(T) T +# define ACE_TSS_GET(I, T) (I) +# endif /* ACE_HAS_THREADS && (ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATIOND) */ + +/** + * @class ACE_TSS + * + * @brief Allows objects that are "physically" in thread specific + * storage (i.e., private to a thread) to be accessed as though + * they were "logically" global to a program. + * + * This class is a wrapper around the OS thread library + * thread-specific functions. It uses the <C++ operator->> to + * shield applications from the details of accessing + * thread-specific storage. + * + * NOTE: For maximal portability, <TYPE> cannot be a built-in type, + * but instead should be a user-defined class (some compilers will + * allow a built-in type, others won't). See template class + * ACE_TSS_Type_Adapter, below, for adapting built-in types to work + * with ACE_TSS. + */ +template <class TYPE> +class ACE_TSS +{ +public: + // = Initialization and termination methods. + + /** + * If caller has passed us a non-NULL ts_obj *, then we'll just use + * this to initialize the thread-specific value (but only for the + * calling thread). Thus, subsequent calls to <operator->> in this + * thread will return this value. This is useful since it enables + * us to assign objects to thread-specific data that have + * arbitrarily complex constructors. + */ + ACE_TSS (TYPE *ts_obj = 0); + + /// Deregister with thread-key administration. + virtual ~ACE_TSS (void); + + // = Accessors. + + /** + * Get the thread-specific object for the key associated with this + * object. Returns 0 if the data has never been initialized, + * otherwise returns a pointer to the data. + */ + TYPE *ts_object (void) const; + + /// Set the thread-specific object for the key associated with this + /// object. + TYPE *ts_object (TYPE *); + + /// Use a "smart pointer" to get the thread-specific object + /// associated with the <key_>. + TYPE *operator-> () const; + + /// Return or create and return the calling threads TYPE object. + operator TYPE *(void) const; + + /// Hook for construction parameters. + virtual TYPE *make_TSS_TYPE (void) const; + + // = Utility methods. + + /// Dump the state of an object. + void dump (void) const; + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + /// Actually implements the code that retrieves the object from + /// thread-specific storage. + TYPE *ts_get (void) const; + + /// Factors out common code for initializing TSS. This must NOT be + /// called with the lock held... + int ts_init (void) const; + +#if !(defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) + /// This implementation only works for non-threading systems... + TYPE *type_; +#else + /// Avoid race conditions during initialization. + ACE_Thread_Mutex keylock_; + + /// "First time in" flag. + int once_; + + /// Key for the thread-specific error data. + ACE_thread_key_t key_; + + /// "Destructor" that deletes internal TYPE * when thread exits. + static void cleanup (void *ptr); +#endif /* defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) */ + // = Disallow copying... + ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_TSS<TYPE> &)) + ACE_UNIMPLEMENTED_FUNC (ACE_TSS (const ACE_TSS<TYPE> &)) +}; + +/** + * @class ACE_TSS_Type_Adapter + * + * @brief Adapter that allows built-in types to be used with ACE_TSS. + * + * Wraps a value of a built-in type, providing conversions to + * and from the type. Example use with ACE_TSS: + * ACE_TSS<ACE_TSS_Type_Adapter<int> > i; + * *i = 37; + * ACE_OS::fprintf (stderr, "%d\n", *i); + * Unfortunately, though, some compilers have trouble with the + * implicit type conversions. This seems to work better: + * ACE_TSS<ACE_TSS_Type_Adapter<int> > i; + * i->operator int & () = 37; + * ACE_OS::fprintf (stderr, "%d\n", i->operator int ()); + */ +template <class TYPE> +class ACE_TSS_Type_Adapter +{ +public: + /// Constructor. Inlined here so that it should _always_ be inlined. + ACE_TSS_Type_Adapter (const TYPE value = 0): value_ (value) {} + + /// TYPE conversion. Inlined here so that it should _always_ be + /// inlined. + operator TYPE () const { return value_; }; + + /// TYPE & conversion. Inlined here so that it should _always_ be + /// inlined. + operator TYPE &() { return value_; }; + +private: + /// The wrapped value. + TYPE value_; +}; + +#if defined (__ACE_INLINE__) +#include "ace/TSS_T.inl" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/TSS_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("TSS_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" +#endif /* ACE_TSS_T_H */ diff --git a/ace/TSS_T.inl b/ace/TSS_T.inl new file mode 100644 index 00000000000..a0bdccba905 --- /dev/null +++ b/ace/TSS_T.inl @@ -0,0 +1,37 @@ +/* -*- C++ -*- */ +// $Id$ + +#if !(defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) + +template <class TYPE> ACE_INLINE +ACE_TSS<TYPE>::ACE_TSS (TYPE *type) + : type_ (type) +{ +} + +template <class TYPE> ACE_INLINE int +ACE_TSS<TYPE>::ts_init (void) const +{ + return 0; +} + +template <class TYPE> ACE_INLINE TYPE * +ACE_TSS<TYPE>::ts_object (void) const +{ + return this->type_; +} + +template <class TYPE> ACE_INLINE TYPE * +ACE_TSS<TYPE>::ts_object (TYPE *type) +{ + this->type_ = type; + return this->type_; +} + +template <class TYPE> ACE_INLINE TYPE * +ACE_TSS<TYPE>::ts_get (void) const +{ + return this->type_; +} + +#endif /* ! (defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))) */ diff --git a/ace/Task_T.cpp b/ace/Task_T.cpp index 25359027fe2..a75ec7d9f61 100644 --- a/ace/Task_T.cpp +++ b/ace/Task_T.cpp @@ -11,7 +11,7 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/Module.h" -//#include "ace/Service_Config.h" +#include "ace/Null_Condition.h" #if !defined (__ACE_INLINE__) #include "ace/Task_T.i" diff --git a/ace/Task_T.h b/ace/Task_T.h index ebd298872e1..ff8d6df04fa 100644 --- a/ace/Task_T.h +++ b/ace/Task_T.h @@ -20,7 +20,7 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/Synch_T.h" +#include "ace/Synch_Traits.h" #include "ace/Task.h" // Forward decls... diff --git a/ace/Test_and_Set.cpp b/ace/Test_and_Set.cpp index 73896eb387a..5a9cbdb0bfe 100644 --- a/ace/Test_and_Set.cpp +++ b/ace/Test_and_Set.cpp @@ -4,7 +4,7 @@ #define ACE_TEST_AND_SET_C #include "ace/Test_and_Set.h" -#include "ace/Synch_T.h" +#include "ace/Guard_T.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/ace/Thread_Exit.cpp b/ace/Thread_Exit.cpp index c3ebe0f577f..713620d9487 100644 --- a/ace/Thread_Exit.cpp +++ b/ace/Thread_Exit.cpp @@ -1,7 +1,6 @@ // $Id$ #include "ace/Thread_Exit.h" -#include "ace/Synch.h" #include "ace/Managed_Object.h" #include "ace/Thread_Manager.h" diff --git a/ace/Thread_Manager.cpp b/ace/Thread_Manager.cpp index d690da52fa9..b24462ec3b9 100644 --- a/ace/Thread_Manager.cpp +++ b/ace/Thread_Manager.cpp @@ -1,6 +1,6 @@ // $Id$ -#include "ace/Synch_T.h" +#include "ace/TSS_T.h" #include "ace/Thread_Manager.h" #include "ace/Dynamic.h" #include "ace/Object_Manager.h" diff --git a/ace/Thread_Manager.h b/ace/Thread_Manager.h index a49ce4e2b79..049f8776181 100644 --- a/ace/Thread_Manager.h +++ b/ace/Thread_Manager.h @@ -22,12 +22,13 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/Synch.h" +#include "ace/Condition_Thread_Mutex.h" #include "ace/Unbounded_Queue.h" #include "ace/Containers.h" #include "ace/Free_List.h" #include "ace/Singleton.h" #include "ace/Log_Msg.h" +#include "ace/Synch_Traits.h" // The following macros control how a Thread Manager manages a pool of // Thread_Descriptor. Currently, the default behavior is not to diff --git a/ace/Thread_Mutex.cpp b/ace/Thread_Mutex.cpp new file mode 100644 index 00000000000..000c7f00bbb --- /dev/null +++ b/ace/Thread_Mutex.cpp @@ -0,0 +1,71 @@ +/* -*- C++ -*- */ +/** + * @file Thread_Mutex.cpp + * + * $Id$ + * + * Originally in Synch.cpp + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ + +#include "ace/Thread_Mutex.h" + +#if defined (ACE_HAS_THREADS) + +#if !defined (__ACE_INLINE__) +#include "ace/Thread_Mutex.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Thread_Mutex, "$Id$") + +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Mutex_Guard) + +#if defined (ACE_USES_OBSOLETE_GUARD_CLASSES) +void +ACE_Thread_Mutex_Guard::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Thread_Mutex_Guard::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} +#endif /* ACE_USES_OBSOLETE_GUARD_CLASSES */ +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Mutex) + +void +ACE_Thread_Mutex::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Thread_Mutex::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n"))); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Thread_Mutex::~ACE_Thread_Mutex (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::~ACE_Thread_Mutex"); + this->remove (); +} + +ACE_Thread_Mutex::ACE_Thread_Mutex (const ACE_TCHAR *name, ACE_mutexattr_t *arg) + : removed_ (0) +{ +// ACE_TRACE ("ACE_Thread_Mutex::ACE_Thread_Mutex"); + + if (ACE_OS::thread_mutex_init (&this->lock_, + USYNC_THREAD, + name, + arg) != 0) + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("%p\n"), + ACE_LIB_TEXT ("ACE_Thread_Mutex::ACE_Thread_Mutex"))); +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ace/Thread_Mutex.h b/ace/Thread_Mutex.h new file mode 100644 index 00000000000..774a1bcb318 --- /dev/null +++ b/ace/Thread_Mutex.h @@ -0,0 +1,235 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Thread_Mutex.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_THREAD_MUTEX_H +#define ACE_THREAD_MUTEX_H +#include /**/ "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_HAS_THREADS) +# include "ace/Null_Thread.h" +#else /* ACE_HAS_THREAD */ +// ACE platform supports some form of threading. + +#include "ace/ACE_export.h" +#include "ace/OS.h" + + /** + * @class ACE_Thread_Mutex + * + * @brief ACE_Thread_Mutex wrapper (only valid for threads in the same + * process). + * + * This implementation is optimized for locking threads that are + * in the same process. It maps to <CRITICAL_SECTION>s on NT + * and <ACE_mutex_t> with <type> set to <USYNC_THREAD> on UNIX. + * ACE_Thread_Mutex is recursive on some platforms (like + * Win32). However, on most platforms (like Solaris) it is not + * recursive. To be totally safe and portable, developers + * should use <ACE_Recursive_Thread_Mutex> when they need a + * recursive mutex. + */ +class ACE_Export ACE_Thread_Mutex +{ + friend class ACE_Condition_Thread_Mutex; +public: + /// Constructor. + ACE_Thread_Mutex (const ACE_TCHAR *name = 0, + ACE_mutexattr_t *attributes = 0); + + /// Implicitly destroy the mutex. + ~ACE_Thread_Mutex (void); + + /** + * Explicitly destroy the mutex. Note that only one thread should + * call this method since it doesn't protect against race + * conditions. + */ + int remove (void); + + /// Acquire lock ownership (wait on queue if necessary). + int acquire (void); + + /** + * Block the thread until we acquire the mutex or until <tv> times + * out, in which case -1 is returned with <errno> == <ETIME>. Note + * that <tv> is assumed to be in "absolute" rather than "relative" + * time. The value of <tv> is updated upon return to show the + * actual (absolute) acquisition time. + */ + int acquire (ACE_Time_Value &tv); + + /** + * If <tv> == 0 the call <acquire()> directly. Otherwise, Block the + * thread until we acquire the mutex or until <tv> times out, in + * which case -1 is returned with <errno> == <ETIME>. Note that + * <*tv> is assumed to be in "absolute" rather than "relative" time. + * The value of <*tv> is updated upon return to show the actual + * (absolute) acquisition time. + */ + int acquire (ACE_Time_Value *tv); + + /** + * Conditionally acquire lock (i.e., don't wait on queue). Returns + * -1 on failure. If we "failed" because someone else already had + * the lock, <errno> is set to <EBUSY>. + */ + int tryacquire (void); + + /// Release lock and unblock a thread at head of queue. + int release (void); + + /** + * Acquire mutex ownership. This calls <acquire> and is only here + * to make the <ACE_Thread_Mutex> interface consistent with the + * other synchronization APIs. + */ + int acquire_read (void); + + /** + * Acquire mutex ownership. This calls <acquire> and is only here + * to make the <ACE_Thread_Mutex> interface consistent with the + * other synchronization APIs. + */ + int acquire_write (void); + + /** + * Conditionally acquire mutex (i.e., won't block). This calls + * <tryacquire> and is only here to make the <ACE_Thread_Mutex> + * interface consistent with the other synchronization APIs. + * Returns -1 on failure. If we "failed" because someone else + * already had the lock, <errno> is set to <EBUSY>. + */ + int tryacquire_read (void); + + /** + * Conditionally acquire mutex (i.e., won't block). This calls + * <tryacquire> and is only here to make the <ACE_Thread_Mutex> + * interface consistent with the other synchronization APIs. + * Returns -1 on failure. If we "failed" because someone else + * already had the lock, <errno> is set to <EBUSY>. + */ + int tryacquire_write (void); + + /** + * This is only here to make the <ACE_Thread_Mutex> + * interface consistent with the other synchronization APIs. + * Assumes the caller has already acquired the mutex using one of + * the above calls, and returns 0 (success) always. + */ + int tryacquire_write_upgrade (void); + + /// Return the underlying mutex. + const ACE_thread_mutex_t &lock (void) const; + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + + // protected: + /// Mutex type that supports single-process locking efficiently. + ACE_thread_mutex_t lock_; + + /// Keeps track of whether <remove> has been called yet to avoid + /// multiple <remove> calls, e.g., explicitly and implicitly in the + /// destructor. This flag isn't protected by a lock, so make sure + /// that you don't have multiple threads simultaneously calling + /// <remove> on the same object, which is a bad idea anyway... + int removed_; + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Thread_Mutex &); + ACE_Thread_Mutex (const ACE_Thread_Mutex &); +}; + +#if defined (ACE_USES_OBSOLETE_GUARD_CLASSES) +/** + * @class ACE_Thread_Mutex_Guard + * + * @brief This data structure is meant to be used within a method or + * function... It performs automatic aquisition and release of + * an <ACE_Thread_Mutex>. + * + * This class is obsolete and should be replaced by + * ACE_Guard<ACE_Thread_Mutex>. + */ +class ACE_Export ACE_Thread_Mutex_Guard +{ +public: + /// Implicitly and automatically acquire the lock. + ACE_Thread_Mutex_Guard (ACE_Thread_Mutex &m, int block = 1); + + /// Implicitly release the lock. + ~ACE_Thread_Mutex_Guard (void); + + /// 1 if locked, 0 if couldn't acquire the lock (errno will contain + /// the reason for this). + int locked (void); + + /** + * Explicitly release the lock. Note that only one thread should + * call this method since it doesn't protect against race + * conditions. + */ + int remove (void); + + /// Explicitly acquire the lock. + int acquire (void); + + /** + * Conditionally acquire the lock (i.e., won't block). Returns -1 + * on failure. If we "failed" because someone else already had the + * lock, <errno> is set to <EBUSY>. + */ + int tryacquire (void); + + /// Explicitly release the lock. + int release (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// Reference to the mutex. + ACE_Thread_Mutex &lock_; + + /// Keeps track of whether we acquired the lock or failed. + int owner_; + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Thread_Mutex_Guard &); + ACE_Thread_Mutex_Guard (const ACE_Thread_Mutex_Guard &); +}; +#endif /* ACE_USES_OBSOLETE_GUARD_CLASSES */ + +#if defined (__ACE_INLINE__) +#include "ace/Thread_Mutex.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* !ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_THREAD_MUTEX_H */ diff --git a/ace/Thread_Mutex.inl b/ace/Thread_Mutex.inl new file mode 100644 index 00000000000..f1031aafa48 --- /dev/null +++ b/ace/Thread_Mutex.inl @@ -0,0 +1,167 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE const ACE_thread_mutex_t & +ACE_Thread_Mutex::lock (void) const +{ +// ACE_TRACE ("ACE_Thread_Mutex::lock"); + return this->lock_; +} + +ACE_INLINE int +ACE_Thread_Mutex::acquire_read (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::acquire_read"); + return ACE_OS::thread_mutex_lock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::acquire_write (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::acquire_write"); + return ACE_OS::thread_mutex_lock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::tryacquire_read (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::tryacquire_read"); + return ACE_OS::thread_mutex_trylock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::tryacquire_write (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::tryacquire_write"); + return ACE_OS::thread_mutex_trylock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::tryacquire_write_upgrade (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::tryacquire_write_upgrade"); + return 0; +} + +ACE_INLINE int +ACE_Thread_Mutex::acquire (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::acquire"); + return ACE_OS::thread_mutex_lock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::acquire (ACE_Time_Value &tv) +{ + // ACE_TRACE ("ACE_Thread_Mutex::acquire"); + return ACE_OS::thread_mutex_lock (&this->lock_, tv); +} + +ACE_INLINE int +ACE_Thread_Mutex::acquire (ACE_Time_Value *tv) +{ + // ACE_TRACE ("ACE_Thread_Mutex::acquire"); + return ACE_OS::thread_mutex_lock (&this->lock_, tv); +} + +ACE_INLINE int +ACE_Thread_Mutex::tryacquire (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::tryacquire"); + return ACE_OS::thread_mutex_trylock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::release (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::release"); + return ACE_OS::thread_mutex_unlock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::remove (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::remove"); + int result = 0; + if (this->removed_ == 0) + { + this->removed_ = 1; + result = ACE_OS::thread_mutex_destroy (&this->lock_); + } + return result; +} + +#if defined (ACE_USES_OBSOLETE_GUARD_CLASSES) +ACE_INLINE int +ACE_Thread_Mutex_Guard::locked (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex_Guard::locked"); + return this->owner_ != -1; +} + +// Explicitly acquire the lock. + +ACE_INLINE int +ACE_Thread_Mutex_Guard::acquire (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex_Guard::acquire"); + return this->owner_ = this->lock_.acquire (); +} + +// Conditionally acquire the lock (i.e., won't block). + +ACE_INLINE int +ACE_Thread_Mutex_Guard::tryacquire (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex_Guard::tryacquire"); + return this->owner_ = this->lock_.tryacquire (); +} + +// Implicitly and automatically acquire the lock. + +ACE_INLINE +ACE_Thread_Mutex_Guard::ACE_Thread_Mutex_Guard (ACE_Thread_Mutex &m, + int block) + : lock_ (m) +{ +// ACE_TRACE ("ACE_Thread_Mutex_Guard::ACE_Thread_Mutex_Guard"); + if (block) + this->acquire (); + else + this->tryacquire (); +} + +// Explicitly release the lock. + +ACE_INLINE int +ACE_Thread_Mutex_Guard::release (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex_Guard::release"); + if (this->owner_ != -1) + { + this->owner_ = -1; + return this->lock_.release (); + } + else + return 0; +} + +// Implicitly release the lock. + +ACE_INLINE +ACE_Thread_Mutex_Guard::~ACE_Thread_Mutex_Guard (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex_Guard::~ACE_Thread_Mutex_Guard"); + this->release (); +} + +// Explicitly release the lock. + +ACE_INLINE int +ACE_Thread_Mutex_Guard::remove (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex_Guard::remove"); + this->owner_ = -1; + return this->release (); +} +#endif /* ACE_USES_OBSOLETE_GUARD_CLASSES */ diff --git a/ace/Thread_Semaphore.cpp b/ace/Thread_Semaphore.cpp new file mode 100644 index 00000000000..954b87e2b8c --- /dev/null +++ b/ace/Thread_Semaphore.cpp @@ -0,0 +1,41 @@ +/* -*- C++ -*- */ +/** + * @file Thread_Semaphore.cpp + * + * $Id$ + * + * Originally in Synch.cpp + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ + +#include "ace/Semaphore.h" + +#if defined (ACE_HAS_THREADS) + +#if !defined (__ACE_INLINE__) +#include "ace/Thread_Semaphore.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(ace, Thread_Semaphore, "$Id$") + + +void +ACE_Thread_Semaphore::dump (void) const +{ +#if defined (ACE_HAS_DUMP) +// ACE_TRACE ("ACE_Thread_Semaphore::dump"); + + ACE_Semaphore::dump (); +#endif /* ACE_HAS_DUMP */ +} + +ACE_Thread_Semaphore::ACE_Thread_Semaphore (u_int count, + const ACE_TCHAR *name, + void *arg, + int max) + : ACE_Semaphore (count, USYNC_THREAD, name, arg, max) +{ +// ACE_TRACE ("ACE_Thread_Semaphore::ACE_Thread_Semaphore"); +} +#endif /* ACE_HAS_THREADS */ diff --git a/ace/Thread_Semaphore.h b/ace/Thread_Semaphore.h new file mode 100644 index 00000000000..e39ec55ad14 --- /dev/null +++ b/ace/Thread_Semaphore.h @@ -0,0 +1,65 @@ +// -*- C++ -*- + +//========================================================================== +/** + * @file Thread_Semaphore.h + * + * $Id$ + * + * Moved from Synch.h. + * + * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> + */ +//========================================================================== + +#ifndef ACE_THREAD_SEMAPHORE_H +#define ACE_THREAD_SEMAPHORE_H +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if !defined (ACE_HAS_THREADS) +# include "ace/Null_Semaphore.h" +#else /* ACE_HAS_THREADS */ +// ACE platform supports some form of threading. + +#include "ace/Semaphore.h" + +/** + * @class ACE_Thread_Semaphore + * + * @brief Wrapper for Dijkstra style general semaphores that work + * only within one process. + */ +class ACE_Export ACE_Thread_Semaphore : public ACE_Semaphore +{ +public: + /// Initialize the semaphore, with an initial value of <count>, + /// maximum value of <max>, and unlocked by default. + ACE_Thread_Semaphore (unsigned int count = 1, // By default make this unlocked. + const ACE_TCHAR *name = 0, + void * = 0, + int max = 0x7FFFFFFF); + + /// Default dtor. + ~ACE_Thread_Semaphore (void); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Thread_Semaphore.inl" +#endif /* __ACE_INLINE__ */ + +#endif /* !ACE_HAS_THREADS */ + +#include /**/ "ace/post.h" +#endif /* ACE_THREAD_SEMAPHORE_H */ diff --git a/ace/Thread_Semaphore.inl b/ace/Thread_Semaphore.inl new file mode 100644 index 00000000000..8d2a9adf785 --- /dev/null +++ b/ace/Thread_Semaphore.inl @@ -0,0 +1,7 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +ACE_Thread_Semaphore::~ACE_Thread_Semaphore (void) +{ +} diff --git a/ace/Timeprobe.h b/ace/Timeprobe.h index 954ef5ddee8..e12636a78de 100644 --- a/ace/Timeprobe.h +++ b/ace/Timeprobe.h @@ -38,6 +38,7 @@ #ifndef ACE_TIMEPROBE_H #define ACE_TIMEPROBE_H #include /**/ "ace/pre.h" + #include "ace/ACE_export.h" #include "ace/OS.h" #include "ace/Malloc_Allocator.h" diff --git a/ace/Timer_Queue.h b/ace/Timer_Queue.h index 1eb4e20a433..96f45771938 100644 --- a/ace/Timer_Queue.h +++ b/ace/Timer_Queue.h @@ -15,7 +15,7 @@ #define ACE_TIMER_QUEUE_H #include /**/ "ace/pre.h" -#include "ace/Synch.h" +#include "ace/Synch_Traits.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/ace/Timer_Queue_T.cpp b/ace/Timer_Queue_T.cpp index 0d5a2b8a5a6..6080fbd1827 100644 --- a/ace/Timer_Queue_T.cpp +++ b/ace/Timer_Queue_T.cpp @@ -3,7 +3,7 @@ #ifndef ACE_TIMER_QUEUE_T_C #define ACE_TIMER_QUEUE_T_C -#include "ace/Synch.h" +#include "ace/config-all.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/ace/Token.cpp b/ace/Token.cpp index 8eec75126a5..72c636be112 100644 --- a/ace/Token.cpp +++ b/ace/Token.cpp @@ -13,7 +13,6 @@ ACE_RCSID(ace, Token, "$Id$") #if defined (ACE_HAS_THREADS) #if !defined (__ACE_INLINE__) -#include "ace/Synch_T.h" #include "ace/Token.i" #endif /* __ACE_INLINE__ */ diff --git a/ace/Token.h b/ace/Token.h index 958708e1a51..786ada3f474 100644 --- a/ace/Token.h +++ b/ace/Token.h @@ -17,7 +17,7 @@ #define ACE_TOKEN_H #include /**/ "ace/pre.h" -#include "ace/Synch.h" +#include "ace/ACE_export.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -25,6 +25,19 @@ #if defined (ACE_HAS_THREADS) +#include "ace/OS.h" +#include "ace/Null_Mutex.h" + +#if defined (ACE_TOKEN_USES_SEMAPHORE) +# include "ace/Semaphore.h" +#else +# include "ace/Condition_Thread_Mutex.h" +#endif /* ACE_TOKEN_USES_SEMAPHORE */ + +class ACE_Thread_Mutex; +class ACE_Time_Value; +//class ACE_Condition_Attributes; + #if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || defined (VXWORKS) || defined (ACE_PSOS) // If platforms support semaphores with timed wait, then we use semaphores instead of c.v. # define ACE_TOKEN_USES_SEMAPHORE @@ -298,10 +311,35 @@ private: int queueing_strategy_; }; +class ACE_Export ACE_Noop_Token : public ACE_Null_Mutex +{ +public: + /// Queueing strategy + enum QUEUEING_STRATEGY + { + FIFO = -1, + LIFO = 0 + }; + + /// Get queueing strategy. + int queueing_strategy (void); + + /// Set queueing strategy. + void queueing_strategy (int queueing_strategy); + + int renew (int = 0, ACE_Time_Value * =0); + + /// Dump the state of an object. + void dump (void) const; + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; +}; + #if defined (__ACE_INLINE__) -#include "ace/Synch_T.h" #include "ace/Token.i" #endif /* __ACE_INLINE__ */ + #else class ACE_Export ACE_Token { diff --git a/ace/Token.i b/ace/Token.i index c7c0f2d9285..e7bdb992b81 100644 --- a/ace/Token.i +++ b/ace/Token.i @@ -1,6 +1,8 @@ /* -*- C++ -*- */ // $Id$ +#include "ace/Guard_T.h" + // Token.i ACE_INLINE int @@ -133,3 +135,27 @@ ACE_Token::ACE_Token_Queue_Entry::signal (void) this->cv_.signal (); #endif /* ACE_TOKEN_USES_SEMAPHORE */ } + +/******************************************************************************/ + +ACE_INLINE int +ACE_Noop_Token::queueing_strategy (void) +{ + return -1; +} + +ACE_INLINE void +ACE_Noop_Token::queueing_strategy (int /* queueing_strategy */) +{ +} + +ACE_INLINE int +ACE_Noop_Token::renew (int, ACE_Time_Value *) +{ + return 0; +} + +ACE_INLINE void +ACE_Noop_Token::dump (void) const +{ +} diff --git a/ace/Token_Invariants.h b/ace/Token_Invariants.h index 887c537d921..dc729c6b395 100644 --- a/ace/Token_Invariants.h +++ b/ace/Token_Invariants.h @@ -20,7 +20,7 @@ #define ACE_TOKEN_INVARIANTS_H #include /**/ "ace/pre.h" -#include "ace/Synch.h" +#include "ace/config-all.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/ace/Token_Manager.h b/ace/Token_Manager.h index 0757a98d4ff..7842db65c1b 100644 --- a/ace/Token_Manager.h +++ b/ace/Token_Manager.h @@ -14,7 +14,7 @@ #define ACE_TOKEN_MANAGER_H #include /**/ "ace/pre.h" -#include "ace/Synch.h" +#include "ace/config-all.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/ace/UPIPE_Acceptor.h b/ace/UPIPE_Acceptor.h index 5dbe1275bef..4ef911218b6 100644 --- a/ace/UPIPE_Acceptor.h +++ b/ace/UPIPE_Acceptor.h @@ -22,7 +22,6 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/Synch.h" #include "ace/SPIPE_Acceptor.h" #include "ace/Thread_Manager.h" diff --git a/ace/UPIPE_Connector.h b/ace/UPIPE_Connector.h index 94bcbd790bb..e2d338f3a56 100644 --- a/ace/UPIPE_Connector.h +++ b/ace/UPIPE_Connector.h @@ -21,7 +21,6 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/Synch.h" #include "ace/SPIPE_Stream.h" #if defined (ACE_HAS_THREADS) diff --git a/ace/UPIPE_Stream.h b/ace/UPIPE_Stream.h index 51bf542c1ca..646efe3df90 100644 --- a/ace/UPIPE_Stream.h +++ b/ace/UPIPE_Stream.h @@ -22,7 +22,6 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/Synch.h" #include "ace/SPIPE.h" #include "ace/Message_Queue.h" #include "ace/UPIPE_Addr.h" diff --git a/ace/UUID.h b/ace/UUID.h index ce69d6c7a81..428cc734372 100644 --- a/ace/UUID.h +++ b/ace/UUID.h @@ -22,7 +22,7 @@ #include "ace/SString.h" #include "ace/Singleton.h" -#include "ace/Synch.h" +#include "ace/Synch_Traits.h" namespace ACE_Utils { diff --git a/ace/Unbounded_Queue.cpp b/ace/Unbounded_Queue.cpp index c827ff6738b..d265d9b9fd2 100644 --- a/ace/Unbounded_Queue.cpp +++ b/ace/Unbounded_Queue.cpp @@ -4,8 +4,6 @@ #define ACE_UNBOUNDED_QUEUE_C #include "ace/Unbounded_Queue.h" -#include "ace/Malloc_Base.h" -#include "ace/Log_Msg.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -15,6 +13,10 @@ #include "ace/Unbounded_Queue.inl" #endif /* __ACE_INLINE__ */ +#include "ace/Malloc_Base.h" +#include "ace/Log_Msg.h" +#include "ace/os_include/os_errno.h" + ACE_RCSID(ace, Unbounded_Queue, "$Id$") ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Queue) diff --git a/apps/drwho/BS_Client.cpp b/apps/drwho/BS_Client.cpp index 33b341aa3d5..ec6ae351632 100644 --- a/apps/drwho/BS_Client.cpp +++ b/apps/drwho/BS_Client.cpp @@ -4,6 +4,7 @@ #include "File_Manager.h" #include "BS_Client.h" #include "ace/Log_Msg.h" +#include "ace/Null_Mutex.h" BS_Client::BS_Client (void) { diff --git a/etc/ace.doxygen b/etc/ace.doxygen index 719ac9bbe95..8c92fc258a6 100644 --- a/etc/ace.doxygen +++ b/etc/ace.doxygen @@ -126,7 +126,7 @@ MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = YES SEARCH_INCLUDES = YES INCLUDE_PATH = . -PREDEFINED = +PREDEFINED = __ACE_INLINE__ ACE_TEMPLATES_REQUIRE_SOURCE EXPAND_AS_DEFINED = ACE_RCSID \ ACE_UNIMPLEMENTED_FUNC \ ACE_CACHE_MAP_MANAGER \ diff --git a/examples/ASX/Event_Server/Event_Server/Consumer_Router.h b/examples/ASX/Event_Server/Event_Server/Consumer_Router.h index 82682dfa2c0..556dd640230 100644 --- a/examples/ASX/Event_Server/Event_Server/Consumer_Router.h +++ b/examples/ASX/Event_Server/Event_Server/Consumer_Router.h @@ -12,6 +12,7 @@ #include "ace/UPIPE_Acceptor.h" #include "ace/Svc_Handler.h" +#include "ace/RW_Thread_Mutex.h" #include "Peer_Router.h" class Consumer_Router : public Peer_Router diff --git a/examples/ASX/Event_Server/Event_Server/Peer_Router.h b/examples/ASX/Event_Server/Event_Server/Peer_Router.h index 0740d0e546b..044ef07ea07 100644 --- a/examples/ASX/Event_Server/Event_Server/Peer_Router.h +++ b/examples/ASX/Event_Server/Event_Server/Peer_Router.h @@ -13,6 +13,7 @@ #include "ace/SOCK_Acceptor.h" #include "ace/Svc_Handler.h" #include "ace/Map_Manager.h" +#include "ace/RW_Thread_Mutex.h" // Type of search key for CONSUMER_MAP typedef ACE_HANDLE ROUTING_KEY; diff --git a/examples/ASX/UPIPE_Event_Server/Peer_Router.h b/examples/ASX/UPIPE_Event_Server/Peer_Router.h index 5b7b33e9227..0dab5d3caac 100644 --- a/examples/ASX/UPIPE_Event_Server/Peer_Router.h +++ b/examples/ASX/UPIPE_Event_Server/Peer_Router.h @@ -20,6 +20,7 @@ #include "ace/Map_Manager.h" #if defined (ACE_HAS_THREADS) +#include "ace/RW_Mutex.h" // Forward declaration. template <class PEER_HANDLER, class KEY> diff --git a/examples/C++NPv2/Logging_Event_Handler_Ex.h b/examples/C++NPv2/Logging_Event_Handler_Ex.h index 020766c2630..d6639cf78d2 100644 --- a/examples/C++NPv2/Logging_Event_Handler_Ex.h +++ b/examples/C++NPv2/Logging_Event_Handler_Ex.h @@ -9,6 +9,7 @@ #include "ace/Reactor.h" #include "ace/Time_Value.h" +#include "ace/Recursive_Thread_Mutex.h" #include "Logging_Event_Handler.h" diff --git a/examples/Logger/simple-server/Reactor_Singleton.h b/examples/Logger/simple-server/Reactor_Singleton.h index 567029bf5c9..ec0653125a9 100644 --- a/examples/Logger/simple-server/Reactor_Singleton.h +++ b/examples/Logger/simple-server/Reactor_Singleton.h @@ -19,6 +19,7 @@ #define _REACTOR_SINGLETON_H #include "ace/Singleton.h" +#include "ace/Null_Mutex.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/examples/Misc/test_get_opt.cpp b/examples/Misc/test_get_opt.cpp index 0b5cc0e0d97..9fd3e66d929 100644 --- a/examples/Misc/test_get_opt.cpp +++ b/examples/Misc/test_get_opt.cpp @@ -2,6 +2,7 @@ // Test the ACE_Get_Opt class. +#include "ace/OS.h" #include "ace/Get_Opt.h" #include "ace/Log_Msg.h" diff --git a/examples/Misc/test_set.cpp b/examples/Misc/test_set.cpp index 919116b76c5..5ed71dbeaf0 100644 --- a/examples/Misc/test_set.cpp +++ b/examples/Misc/test_set.cpp @@ -1,5 +1,6 @@ // $Id$ +#include "ace/OS.h" #include "ace/Containers.h" #include "ace/Log_Msg.h" diff --git a/examples/Misc/test_trace.cpp b/examples/Misc/test_trace.cpp index 4a1d80dad67..23aaf25251a 100644 --- a/examples/Misc/test_trace.cpp +++ b/examples/Misc/test_trace.cpp @@ -21,6 +21,7 @@ // Enable tracing #define ACE_NTRACE 0 +#include "ace/OS.h" #include "ace/Signal.h" #include "ace/Task.h" diff --git a/examples/Reactor/Misc/test_timer_queue.cpp b/examples/Reactor/Misc/test_timer_queue.cpp index 37bc7636a64..81dd3b28511 100644 --- a/examples/Reactor/Misc/test_timer_queue.cpp +++ b/examples/Reactor/Misc/test_timer_queue.cpp @@ -4,6 +4,8 @@ #include "ace/Timer_List.h" #include "ace/Timer_Queue.h" #include "ace/Log_Msg.h" +#include "ace/Recursive_Thread_Mutex.h" +#include "ace/Null_Mutex.h" ACE_RCSID(Misc, test_timer_queue, "$Id$") diff --git a/examples/Shared_Malloc/test_persistence.cpp b/examples/Shared_Malloc/test_persistence.cpp index 6e8b0da82c1..3d7a41563d7 100644 --- a/examples/Shared_Malloc/test_persistence.cpp +++ b/examples/Shared_Malloc/test_persistence.cpp @@ -8,6 +8,7 @@ #include "ace/Malloc.h" #include "ace/streams.h" +#include "ace/Null_Mutex.h" ACE_RCSID(Shared_Malloc, test_persistence, "$Id$") diff --git a/examples/Threads/TSS_Data.h b/examples/Threads/TSS_Data.h index 03fd6c8ff50..3c9dfcfe28c 100644 --- a/examples/Threads/TSS_Data.h +++ b/examples/Threads/TSS_Data.h @@ -19,6 +19,8 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ +#include "ace/Synch_Traits.h" + class TSS_Data // = TITLE // Data that is stored in thread-specific storage. diff --git a/examples/Threads/barrier2.cpp b/examples/Threads/barrier2.cpp index cdbe6ff95f3..13d152da7fe 100644 --- a/examples/Threads/barrier2.cpp +++ b/examples/Threads/barrier2.cpp @@ -17,6 +17,7 @@ ACE_RCSID(Threads, barrier2, "$Id$") #if defined (ACE_HAS_THREADS) +#include "ace/Null_Barrier.h" #define BARRIER_TYPE ACE_Null_Barrier template <class BARRIER> diff --git a/examples/Threads/task_one.cpp b/examples/Threads/task_one.cpp index e5e0b5e7234..734c0863712 100644 --- a/examples/Threads/task_one.cpp +++ b/examples/Threads/task_one.cpp @@ -13,6 +13,7 @@ ACE_RCSID(Threads, task_one, "$Id$") #if defined (ACE_HAS_THREADS) #include "ace/Task.h" +#include "ace/Barrier.h" class Barrier_Task : public ACE_Task<ACE_MT_SYNCH> { diff --git a/examples/Timer_Queue/Thread_Timer_Queue_Test.h b/examples/Timer_Queue/Thread_Timer_Queue_Test.h index c9098123df0..06ec8538bfc 100644 --- a/examples/Timer_Queue/Thread_Timer_Queue_Test.h +++ b/examples/Timer_Queue/Thread_Timer_Queue_Test.h @@ -32,6 +32,7 @@ #include "ace/Timer_Heap_T.h" #include "ace/Timer_Queue_Adapters.h" #include "ace/svc_export.h" +#include "ace/Condition_Recursive_Thread_Mutex.h" #include "Driver.h" // These typedefs ensure that we use the minimal amount of locking diff --git a/performance-tests/SCTP/Options_Manager.cpp b/performance-tests/SCTP/Options_Manager.cpp index 4e5db1aa628..9ea6e9770de 100644 --- a/performance-tests/SCTP/Options_Manager.cpp +++ b/performance-tests/SCTP/Options_Manager.cpp @@ -3,17 +3,18 @@ // $Id$ extern "C" { -#include <sys/types.h> +#include "ace/os_include/sys/os_types.h" }; #include "ace/Get_Opt.h" +#include "ace/os_include/netinet/os_in.h" +#include "ace/OS.h" // make sure that the code compiles cleanly even if SCTP is not // available. If SCTP is not installed, program will exit early in // main() with an error message. #ifdef ACE_HAS_SCTP extern "C" { -#include <netinet/in.h> #include <netinet/sctp.h> }; #else diff --git a/performance-tests/Server_Concurrency/Leader_Follower/RT_CORBA_Leader_Follower.h b/performance-tests/Server_Concurrency/Leader_Follower/RT_CORBA_Leader_Follower.h index 96ce58545fc..5813d4fb972 100644 --- a/performance-tests/Server_Concurrency/Leader_Follower/RT_CORBA_Leader_Follower.h +++ b/performance-tests/Server_Concurrency/Leader_Follower/RT_CORBA_Leader_Follower.h @@ -25,6 +25,7 @@ #if defined (ACE_HAS_THREADS) #include "ace/Synch_T.h" +#include "ace/Manual_Event.h" enum DEBUGGING_RANGE { diff --git a/performance-tests/Server_Concurrency/Queue_Based_Workers/RT_CORBA_Workers.cpp b/performance-tests/Server_Concurrency/Queue_Based_Workers/RT_CORBA_Workers.cpp index 4ae34a00cfb..0bce791a652 100644 --- a/performance-tests/Server_Concurrency/Queue_Based_Workers/RT_CORBA_Workers.cpp +++ b/performance-tests/Server_Concurrency/Queue_Based_Workers/RT_CORBA_Workers.cpp @@ -7,7 +7,7 @@ #include "ace/Get_Opt.h" #include "ace/High_Res_Timer.h" #include "ace/Sched_Params.h" - +#include "ace/Lock_Adapter_T.h" // The number of messages that is being processed static size_t number_of_messages = 100; diff --git a/performance-tests/Server_Concurrency/Queue_Based_Workers/RT_CORBA_Workers.h b/performance-tests/Server_Concurrency/Queue_Based_Workers/RT_CORBA_Workers.h index 2cbad364dfc..46d78e8624c 100644 --- a/performance-tests/Server_Concurrency/Queue_Based_Workers/RT_CORBA_Workers.h +++ b/performance-tests/Server_Concurrency/Queue_Based_Workers/RT_CORBA_Workers.h @@ -17,7 +17,7 @@ #include /**/ "ace/pre.h" #include "ace/Task_T.h" - +#include "ace/Manual_Event.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once diff --git a/performance-tests/Server_Concurrency/Queue_Based_Workers/workers.cpp b/performance-tests/Server_Concurrency/Queue_Based_Workers/workers.cpp index a59ee2f10aa..bc08f453245 100644 --- a/performance-tests/Server_Concurrency/Queue_Based_Workers/workers.cpp +++ b/performance-tests/Server_Concurrency/Queue_Based_Workers/workers.cpp @@ -6,6 +6,7 @@ #include "ace/High_Res_Timer.h" #include "ace/Sched_Params.h" #include "ace/Profile_Timer.h" +#include "ace/Lock_Adapter_T.h" #include "../Latency_Stats.h" static size_t number_of_messages = 100; diff --git a/tests/Aio_Platform_Test.cpp b/tests/Aio_Platform_Test.cpp index f95ea4c08bb..e2ec2209aa1 100644 --- a/tests/Aio_Platform_Test.cpp +++ b/tests/Aio_Platform_Test.cpp @@ -19,6 +19,7 @@ // ===================================================================== #include "test_config.h" +#include "ace/OS.h" ACE_RCSID(tests, Aio_Platform_Test, "$Id$") diff --git a/tests/Basic_Types_Test.cpp b/tests/Basic_Types_Test.cpp index 2b901f3acaf..95e1cd848cf 100644 --- a/tests/Basic_Types_Test.cpp +++ b/tests/Basic_Types_Test.cpp @@ -35,6 +35,9 @@ # include "test_config.h" #endif /* ! ACE_HAS_MINIMAL_ACE_OS */ +#include "ace/Basic_Types.h" +#include "ace/OS.h" + ACE_RCSID(tests, Basic_Types_Test, "$Id$") typedef void* (*a_function_pointer) (void*); diff --git a/tests/Cached_Allocator_Test.cpp b/tests/Cached_Allocator_Test.cpp index e6836fc7ccf..dabbf289cd0 100644 --- a/tests/Cached_Allocator_Test.cpp +++ b/tests/Cached_Allocator_Test.cpp @@ -22,6 +22,9 @@ ACE_RCSID(tests, Cached_Allocator_Test, "$Id$") +#include "ace/Synch_Traits.h" +#include "ace/Null_Mutex.h" + typedef ACE_Dynamic_Cached_Allocator<ACE_SYNCH_NULL_MUTEX> DYNAMIC_ALLOCATOR; static int diff --git a/tests/MT_Reference_Counted_Event_Handler_Test.cpp b/tests/MT_Reference_Counted_Event_Handler_Test.cpp index a87acf7f856..d7f9f73e3fb 100644 --- a/tests/MT_Reference_Counted_Event_Handler_Test.cpp +++ b/tests/MT_Reference_Counted_Event_Handler_Test.cpp @@ -35,6 +35,7 @@ #include "ace/Task.h" #include "ace/SOCK_Acceptor.h" #include "ace/SOCK_Connector.h" +#include "ace/Auto_Event.h" ACE_RCSID(tests, MT_Reference_Counted_Event_Handler_Test, "$Id$") diff --git a/tests/Malloc_Test.cpp b/tests/Malloc_Test.cpp index 9d0280c627e..0185937b3e9 100644 --- a/tests/Malloc_Test.cpp +++ b/tests/Malloc_Test.cpp @@ -24,6 +24,7 @@ #include "ace/Process_Mutex.h" #include "ace/PI_Malloc.h" #include "Malloc_Test.h" +#include "ace/RW_Thread_Mutex.h" ACE_RCSID(tests, Malloc_Test, "Malloc_Test.cpp,v 4.22 1999/12/13 22:24:42 nanbor Exp") diff --git a/tests/Message_Block_Test.cpp b/tests/Message_Block_Test.cpp index 53601e327d4..56a25a3d878 100644 --- a/tests/Message_Block_Test.cpp +++ b/tests/Message_Block_Test.cpp @@ -37,6 +37,9 @@ static const size_t ACE_ALLOC_AMOUNT = 48; #if defined (ACE_HAS_THREADS) +#include "ace/Lock_Adapter_T.h" +#include "ace/Synch_Traits.h" + // Number of iterations to run the test. static size_t n_iterations = ACE_MAX_ITERATIONS; diff --git a/tests/Message_Queue_Notifications_Test.cpp b/tests/Message_Queue_Notifications_Test.cpp index ec86ba4647c..567df50cf00 100644 --- a/tests/Message_Queue_Notifications_Test.cpp +++ b/tests/Message_Queue_Notifications_Test.cpp @@ -39,6 +39,7 @@ #include "ace/Task.h" #include "ace/Reactor_Notification_Strategy.h" #include "ace/Atomic_Op.h" +#include "ace/Barrier.h" ACE_RCSID(tests, Message_Queue_Notifications_Test, "$Id$") diff --git a/tests/Reactor_Timer_Test.cpp b/tests/Reactor_Timer_Test.cpp index f5017c0b70d..6057d8c20b2 100644 --- a/tests/Reactor_Timer_Test.cpp +++ b/tests/Reactor_Timer_Test.cpp @@ -25,6 +25,7 @@ #include "ace/Reactor.h" #include "ace/High_Res_Timer.h" #include "ace/Trace.h" +#include "ace/Recursive_Thread_Mutex.h" ACE_RCSID(tests, Reactor_Timer_Test, "$Id$") diff --git a/tests/Recursive_Condition_Bug_Test.cpp b/tests/Recursive_Condition_Bug_Test.cpp index a865431353f..25563e00d32 100644 --- a/tests/Recursive_Condition_Bug_Test.cpp +++ b/tests/Recursive_Condition_Bug_Test.cpp @@ -27,6 +27,7 @@ #include "ace/Activation_Queue.h" #include "ace/Timer_Heap.h" #include "ace/Timer_Queue_Adapters.h" +#include "ace/Condition_Recursive_Thread_Mutex.h" ACE_RCSID (tests, Recursive_Condition_Bug_Test, diff --git a/tests/Task_Test.cpp b/tests/Task_Test.cpp index 9b6a3e3555a..ff6849bb95e 100644 --- a/tests/Task_Test.cpp +++ b/tests/Task_Test.cpp @@ -27,6 +27,7 @@ ACE_RCSID(tests, Task_Test, "$Id$") #if defined (ACE_HAS_THREADS) +#include "ace/Barrier.h" class My_Thread_Hook : public ACE_Thread_Hook { diff --git a/tests/Thread_Manager_Test.cpp b/tests/Thread_Manager_Test.cpp index 0df3fd5cf2e..7bb10bfe411 100644 --- a/tests/Thread_Manager_Test.cpp +++ b/tests/Thread_Manager_Test.cpp @@ -28,6 +28,7 @@ ACE_RCSID(tests, Thread_Manager_Test, "$Id$") #if defined (ACE_HAS_THREADS) +#include "ace/Barrier.h" // Each thread keeps track of whether it has been signalled by using a // global array. It must be dynamically allocated to allow sizing at diff --git a/tests/Thread_Pool_Test.cpp b/tests/Thread_Pool_Test.cpp index a34b240dd1d..d26bce9915c 100644 --- a/tests/Thread_Pool_Test.cpp +++ b/tests/Thread_Pool_Test.cpp @@ -30,6 +30,7 @@ ACE_RCSID(tests, Thread_Pool_Test, "$Id$") #if defined (ACE_HAS_THREADS) +#include "ace/Lock_Adapter_T.h" // Number of iterations to run the test. static size_t n_iterations = 100; diff --git a/tests/Timeprobe_Test.cpp b/tests/Timeprobe_Test.cpp index 814ede89c56..83bb71aa4e6 100644 --- a/tests/Timeprobe_Test.cpp +++ b/tests/Timeprobe_Test.cpp @@ -23,6 +23,8 @@ #include "tests/test_config.h" #include "ace/Timeprobe.h" #include "ace/Singleton.h" +#include "ace/Synch_Traits.h" +#include "ace/Recursive_Thread_Mutex.h" ACE_RCSID(tests, Timeprobe_Test, "$Id$") diff --git a/tests/Timer_Queue_Reference_Counting_Test.cpp b/tests/Timer_Queue_Reference_Counting_Test.cpp index bafaef95d0a..9b4b9cf70e5 100644 --- a/tests/Timer_Queue_Reference_Counting_Test.cpp +++ b/tests/Timer_Queue_Reference_Counting_Test.cpp @@ -25,6 +25,8 @@ #include "ace/Timer_Hash.h" #include "ace/Timer_Wheel.h" #include "ace/Reactor.h" +#include "ace/Recursive_Thread_Mutex.h" +#include "ace/Null_Mutex.h" ACE_RCSID(tests, Timer_Queue_Reference_Counting_Test, "$Id$") diff --git a/tests/Timer_Queue_Test.cpp b/tests/Timer_Queue_Test.cpp index 81865b002be..6ca67a9aafd 100644 --- a/tests/Timer_Queue_Test.cpp +++ b/tests/Timer_Queue_Test.cpp @@ -31,6 +31,8 @@ #include "ace/Timer_Wheel.h" #include "ace/Timer_Hash.h" #include "ace/Timer_Queue.h" +#include "ace/Recursive_Thread_Mutex.h" +#include "ace/Null_Mutex.h" ACE_RCSID(tests, Timer_Queue_Test, "$Id$") diff --git a/tests/Token_Strategy_Test.cpp b/tests/Token_Strategy_Test.cpp index 4332afd2c3f..adb78fdf9e8 100644 --- a/tests/Token_Strategy_Test.cpp +++ b/tests/Token_Strategy_Test.cpp @@ -24,6 +24,7 @@ #include "ace/Stats.h" #include "tests/test_config.h" #include "ace/ACE.h" +#include "ace/Barrier.h" ACE_RCSID(tests, Token_Strategy_Test, "$Id$") |