Recursive_Thread_Mutex.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //==========================================================================
00004 /**
00005  *  @file    Recursive_Thread_Mutex.h
00006  *
00007  *  Recursive_Thread_Mutex.h,v 4.5 2006/05/29 18:47:16 schmidt Exp
00008  *
00009  *   Moved from Synch.h.
00010  *
00011  *  @author Douglas C. Schmidt <schmidt@cs.wustl.edu> and
00012  *          Abdullah Sowayan <abdullah.sowayan@lmco.com>
00013  */
00014 //==========================================================================
00015 
00016 #ifndef ACE_RECURSIVE_THREAD_MUTEX_H
00017 #define ACE_RECURSIVE_THREAD_MUTEX_H
00018 #include /**/ "ace/pre.h"
00019 
00020 #include "ace/ACE_export.h"
00021 
00022 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00023 # pragma once
00024 #endif /* ACE_LACKS_PRAGMA_ONCE */
00025 
00026 #if !defined (ACE_HAS_THREADS)
00027 #  include "ace/Null_Mutex.h"
00028 #else /* ACE_HAS_THREADS */
00029 // ACE platform supports some form of threading.
00030 
00031 #include "ace/OS_NS_Thread.h"
00032 
00033 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00034 
00035 /**
00036  * @class ACE_Recursive_Thread_Mutex
00037  *
00038  * @brief Implement a C++ wrapper that allows nested acquisition and
00039  * release of a mutex that occurs in the same thread.
00040  */
00041 class ACE_Export ACE_Recursive_Thread_Mutex
00042 {
00043 public:
00044   /// Initialize a recursive mutex.
00045   ACE_Recursive_Thread_Mutex (const ACE_TCHAR *name = 0,
00046                               ACE_mutexattr_t *arg = 0);
00047 
00048   /// Implicitly release a recursive mutex.
00049   ~ACE_Recursive_Thread_Mutex (void);
00050 
00051   /**
00052    * Implicitly release a recursive mutex.  Note that only one thread
00053    * should call this method since it doesn't protect against race
00054    * conditions.
00055    */
00056   int remove (void);
00057 
00058   /**
00059    * Acquire a recursive mutex (will increment the nesting level and
00060    * not deadmutex if the owner of the mutex calls this method more
00061    * than once).
00062    */
00063   int acquire (void);
00064 
00065   /**
00066    * Block the thread until we acquire the mutex or until @a tv times
00067    * out, in which case -1 is returned with <errno> == <ETIME>.  Note
00068    * that @a tv is assumed to be in "absolute" rather than "relative"
00069    * time.  The value of @a tv is updated upon return to show the
00070    * actual (absolute) acquisition time.
00071    */
00072   int acquire (ACE_Time_Value &tv);
00073 
00074   /**
00075    * If <tv> == 0 the call <acquire()> directly.  Otherwise, Block the
00076    * thread until we acquire the mutex or until <tv> times out, in
00077    * which case -1 is returned with <errno> == <ETIME>.  Note that
00078    * <*tv> is assumed to be in "absolute" rather than "relative" time.
00079    * The value of <*tv> is updated upon return to show the actual
00080    * (absolute) acquisition time.
00081    */
00082   int acquire (ACE_Time_Value *tv);
00083 
00084   /**
00085    * Conditionally acquire a recursive mutex (i.e., won't block).
00086    * Returns -1 on failure.  If we "failed" because someone else
00087    * already had the lock, <errno> is set to <EBUSY>.
00088    */
00089   int tryacquire (void);
00090 
00091   /**
00092    * Acquire mutex ownership.  This calls <acquire> and is only
00093    * here to make the <ACE_Recusive_Thread_Mutex> interface consistent
00094    * with the other synchronization APIs.
00095    */
00096   int acquire_read (void);
00097 
00098   /**
00099    * Acquire mutex ownership.  This calls <acquire> and is only
00100    * here to make the <ACE_Recusive_Thread_Mutex> interface consistent
00101    * with the other synchronization APIs.
00102    */
00103   int acquire_write (void);
00104 
00105   /**
00106    * Conditionally acquire mutex (i.e., won't block).  This calls
00107    * <tryacquire> and is only here to make the
00108    * <ACE_Recusive_Thread_Mutex> interface consistent with the other
00109    * synchronization APIs.  Returns -1 on failure.  If we "failed"
00110    * because someone else already had the lock, <errno> is set to
00111    * <EBUSY>.
00112    */
00113   int tryacquire_read (void);
00114 
00115   /**
00116    * Conditionally acquire mutex (i.e., won't block).  This calls
00117    * <tryacquire> and is only here to make the
00118    * <ACE_Recusive_Thread_Mutex> interface consistent with the other
00119    * synchronization APIs.  Returns -1 on failure.  If we "failed"
00120    * because someone else already had the lock, <errno> is set to
00121    * <EBUSY>.
00122    */
00123   int tryacquire_write (void);
00124 
00125   /**
00126    * This is only here to make the ACE_Recursive_Thread_Mutex
00127    * interface consistent with the other synchronization APIs.
00128    * Assumes the caller has already acquired the mutex using one of
00129    * the above calls, and returns 0 (success) always.
00130    */
00131   int tryacquire_write_upgrade (void);
00132 
00133   /**
00134    * Releases a recursive mutex (will not release mutex until all the
00135    * nesting level drops to 0, which means the mutex is no longer
00136    * held).
00137    */
00138   int release (void);
00139 
00140   /// Return the id of the thread that currently owns the mutex.
00141   ACE_thread_t get_thread_id (void);
00142 
00143   /**
00144    * Return the nesting level of the recursion.  When a thread has
00145    * acquired the mutex for the first time, the nesting level == 1.
00146    * The nesting level is incremented every time the thread acquires
00147    * the mutex recursively.  Note that if the ACE_HAS_RECURSIVE_MUTEXES
00148    * macro is enabled then this method may return -1 on platforms that
00149    * do not expose the internal count.
00150    */
00151   int get_nesting_level (void);
00152 
00153   /// Returns a reference to the recursive mutex;
00154   ACE_recursive_thread_mutex_t &mutex (void);
00155 
00156   /// Returns a reference to the recursive mutex's internal mutex;
00157   ACE_thread_mutex_t &get_nesting_mutex (void);
00158 
00159   /// Dump the state of an object.
00160   void dump (void) const;
00161 
00162   /// Declare the dynamic allocation hooks.
00163   ACE_ALLOC_HOOK_DECLARE;
00164 
00165 protected:
00166   // = This method should *not* be public (they hold no locks...)
00167   void set_thread_id (ACE_thread_t t);
00168 
00169   /// Recursive mutex.
00170   ACE_recursive_thread_mutex_t lock_;
00171 
00172   /// Keeps track of whether <remove> has been called yet to avoid
00173   /// multiple <remove> calls, e.g., explicitly and implicitly in the
00174   /// destructor.  This flag isn't protected by a lock, so make sure
00175   /// that you don't have multiple threads simultaneously calling
00176   /// <remove> on the same object, which is a bad idea anyway...
00177   int removed_;
00178 
00179 private:
00180   // = Prevent assignment and initialization.
00181   void operator= (const ACE_Recursive_Thread_Mutex &);
00182   ACE_Recursive_Thread_Mutex (const ACE_Recursive_Thread_Mutex &);
00183 };
00184 
00185 ACE_END_VERSIONED_NAMESPACE_DECL
00186 
00187 #if defined (__ACE_INLINE__)
00188 #include "ace/Recursive_Thread_Mutex.inl"
00189 #endif /* __ACE_INLINE__ */
00190 
00191 #endif /* !ACE_HAS_THREADS */
00192 
00193 #include /**/ "ace/post.h"
00194 #endif /* ACE_RECURSIVE_THREAD_MUTEX_H */

Generated on Thu Nov 9 09:42:01 2006 for ACE by doxygen 1.3.6