00001 // -*- C++ -*- 00002 00003 //========================================================================== 00004 /** 00005 * @file Thread_Mutex.h 00006 * 00007 * $Id: Thread_Mutex.h 78460 2007-05-23 13:33:56Z johnnyw $ 00008 * 00009 * Moved from Synch.h. 00010 * 00011 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> 00012 */ 00013 //========================================================================== 00014 00015 #ifndef ACE_THREAD_MUTEX_H 00016 #define ACE_THREAD_MUTEX_H 00017 #include /**/ "ace/pre.h" 00018 00019 #include /**/ "ace/config-all.h" 00020 00021 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00022 # pragma once 00023 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00024 00025 #if !defined (ACE_HAS_THREADS) 00026 # include "ace/Null_Mutex.h" 00027 #else /* ACE_HAS_THREADS */ 00028 // ACE platform supports some form of threading. 00029 00030 #include /**/ "ace/ACE_export.h" 00031 #include "ace/OS_NS_Thread.h" 00032 00033 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00034 00035 /** 00036 * @class ACE_Thread_Mutex 00037 * 00038 * @brief ACE_Thread_Mutex wrapper (only valid for threads in the same 00039 * process). 00040 * 00041 * This implementation is optimized for locking threads that are 00042 * in the same process. It maps to <CRITICAL_SECTION>s on NT 00043 * and <ACE_mutex_t> with <type> set to <USYNC_THREAD> on UNIX. 00044 * ACE_Thread_Mutex is recursive on some platforms (like 00045 * Win32). However, on most platforms (like Solaris) it is not 00046 * recursive. To be totally safe and portable, developers 00047 * should use ACE_Recursive_Thread_Mutex when they need a 00048 * recursive mutex. 00049 */ 00050 class ACE_Export ACE_Thread_Mutex 00051 { 00052 friend class ACE_Condition_Thread_Mutex; 00053 public: 00054 /// Constructor. 00055 ACE_Thread_Mutex (const ACE_TCHAR *name = 0, 00056 ACE_mutexattr_t *attributes = 0); 00057 00058 /// Implicitly destroy the mutex. 00059 ~ACE_Thread_Mutex (void); 00060 00061 /** 00062 * Explicitly destroy the mutex. Note that only one thread should 00063 * call this method since it doesn't protect against race 00064 * conditions. 00065 */ 00066 int remove (void); 00067 00068 /// Acquire lock ownership (wait on queue if necessary). 00069 int acquire (void); 00070 00071 /** 00072 * Block the thread until we acquire the mutex or until @a tv times 00073 * out, in which case -1 is returned with @c errno == @c ETIME. Note 00074 * that @a tv is assumed to be in "absolute" rather than "relative" 00075 * time. The value of @a tv is updated upon return to show the 00076 * actual (absolute) acquisition time. 00077 */ 00078 int acquire (ACE_Time_Value &tv); 00079 00080 /** 00081 * If @a tv == 0 the call <acquire()> directly. Otherwise, Block the 00082 * thread until we acquire the mutex or until @a tv times out, in 00083 * which case -1 is returned with @c errno == @c ETIME. Note that 00084 * <*tv> is assumed to be in "absolute" rather than "relative" time. 00085 * The value of <*tv> is updated upon return to show the actual 00086 * (absolute) acquisition time. 00087 */ 00088 int acquire (ACE_Time_Value *tv); 00089 00090 /** 00091 * Conditionally acquire lock (i.e., don't wait on queue). Returns 00092 * -1 on failure. If we "failed" because someone else already had 00093 * the lock, @c errno is set to @c EBUSY. 00094 */ 00095 int tryacquire (void); 00096 00097 /// Release lock and unblock a thread at head of queue. 00098 int release (void); 00099 00100 /** 00101 * Acquire mutex ownership. This calls <acquire> and is only here 00102 * to make the ACE_Thread_Mutex interface consistent with the 00103 * other synchronization APIs. 00104 */ 00105 int acquire_read (void); 00106 00107 /** 00108 * Acquire mutex ownership. This calls <acquire> and is only here 00109 * to make the ACE_Thread_Mutex interface consistent with the 00110 * other synchronization APIs. 00111 */ 00112 int acquire_write (void); 00113 00114 /** 00115 * Conditionally acquire mutex (i.e., won't block). This calls 00116 * <tryacquire> and is only here to make the ACE_Thread_Mutex 00117 * interface consistent with the other synchronization APIs. 00118 * Returns -1 on failure. If we "failed" because someone else 00119 * already had the lock, @c errno is set to @c EBUSY. 00120 */ 00121 int tryacquire_read (void); 00122 00123 /** 00124 * Conditionally acquire mutex (i.e., won't block). This calls 00125 * <tryacquire> and is only here to make the ACE_Thread_Mutex 00126 * interface consistent with the other synchronization APIs. 00127 * Returns -1 on failure. If we "failed" because someone else 00128 * already had the lock, @c errno is set to @c EBUSY. 00129 */ 00130 int tryacquire_write (void); 00131 00132 /** 00133 * This is only here to make the ACE_Thread_Mutex 00134 * interface consistent with the other synchronization APIs. 00135 * Assumes the caller has already acquired the mutex using one of 00136 * the above calls, and returns 0 (success) always. 00137 */ 00138 int tryacquire_write_upgrade (void); 00139 00140 /// Return the underlying mutex. 00141 const ACE_thread_mutex_t &lock (void) const; 00142 00143 /// Dump the state of an object. 00144 void dump (void) const; 00145 00146 /// Declare the dynamic allocation hooks. 00147 ACE_ALLOC_HOOK_DECLARE; 00148 00149 // protected: 00150 /// Mutex type that supports single-process locking efficiently. 00151 ACE_thread_mutex_t lock_; 00152 00153 /// Keeps track of whether <remove> has been called yet to avoid 00154 /// multiple <remove> calls, e.g., explicitly and implicitly in the 00155 /// destructor. This flag isn't protected by a lock, so make sure 00156 /// that you don't have multiple threads simultaneously calling 00157 /// <remove> on the same object, which is a bad idea anyway... 00158 bool removed_; 00159 00160 private: 00161 // = Prevent assignment and initialization. 00162 void operator= (const ACE_Thread_Mutex &); 00163 ACE_Thread_Mutex (const ACE_Thread_Mutex &); 00164 }; 00165 00166 ACE_END_VERSIONED_NAMESPACE_DECL 00167 00168 #if defined (__ACE_INLINE__) 00169 #include "ace/Thread_Mutex.inl" 00170 #endif /* __ACE_INLINE__ */ 00171 00172 #endif /* !ACE_HAS_THREADS */ 00173 00174 #include /**/ "ace/post.h" 00175 #endif /* ACE_THREAD_MUTEX_H */