3 //==========================================================================
5 * @file Recursive_Thread_Mutex.h
7 * @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu> and
8 * Abdullah Sowayan <abdullah.sowayan@lmco.com>
10 //==========================================================================
12 #ifndef ACE_RECURSIVE_THREAD_MUTEX_H
13 #define ACE_RECURSIVE_THREAD_MUTEX_H
14 #include /**/ "ace/pre.h"
16 #include /**/ "ace/ACE_export.h"
18 #if !defined (ACE_LACKS_PRAGMA_ONCE)
20 #endif /* ACE_LACKS_PRAGMA_ONCE */
22 #if !defined (ACE_HAS_THREADS)
23 # include "ace/Null_Mutex.h"
24 #else /* ACE_HAS_THREADS */
25 // ACE platform supports some form of threading.
27 #include "ace/OS_NS_Thread.h"
29 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
32 * @class ACE_Recursive_Thread_Mutex
34 * @brief Implement a C++ wrapper that allows nested acquisition and
35 * release of a mutex that occurs in the same thread.
37 class ACE_Export ACE_Recursive_Thread_Mutex
40 /// Initialize a recursive mutex.
41 ACE_Recursive_Thread_Mutex (const ACE_TCHAR
*name
= 0,
42 ACE_mutexattr_t
*arg
= 0);
44 /// Implicitly release a recursive mutex.
45 ~ACE_Recursive_Thread_Mutex ();
48 * Implicitly release a recursive mutex. Note that only one thread
49 * should call this method since it doesn't protect against race
55 * Acquire a recursive mutex (will increment the nesting level and
56 * not deadmutex if the owner of the mutex calls this method more
62 * Block the thread until we acquire the mutex or until @a tv times
63 * out, in which case -1 is returned with @c errno == @c ETIME. Note
64 * that @a tv is assumed to be in "absolute" rather than "relative"
65 * time. The value of @a tv is updated upon return to show the
66 * actual (absolute) acquisition time.
68 int acquire (ACE_Time_Value
&tv
);
71 * If @a tv == 0 the call acquire() directly. Otherwise, Block the
72 * thread until we acquire the mutex or until @a tv times out, in
73 * which case -1 is returned with @c errno == @c ETIME. Note that
74 * <*tv> is assumed to be in "absolute" rather than "relative" time.
75 * The value of <*tv> is updated upon return to show the actual
76 * (absolute) acquisition time.
78 int acquire (ACE_Time_Value
*tv
);
81 * Conditionally acquire a recursive mutex (i.e., won't block).
82 * Returns -1 on failure. If we "failed" because someone else
83 * already had the lock, @c errno is set to @c EBUSY.
88 * Acquire mutex ownership. This calls acquire() and is only
89 * here to make the ACE_Recusive_Thread_Mutex interface consistent
90 * with the other synchronization APIs.
95 * Acquire mutex ownership. This calls acquire() and is only
96 * here to make the ACE_Recusive_Thread_Mutex interface consistent
97 * with the other synchronization APIs.
102 * Conditionally acquire mutex (i.e., won't block). This calls
103 * tryacquire() and is only here to make the
104 * ACE_Recusive_Thread_Mutex interface consistent with the other
105 * synchronization APIs. Returns -1 on failure. If we "failed"
106 * because someone else already had the lock, @c errno is set to
109 int tryacquire_read ();
112 * Conditionally acquire mutex (i.e., won't block). This calls
113 * tryacquire() and is only here to make the
114 * ACE_Recusive_Thread_Mutex interface consistent with the other
115 * synchronization APIs. Returns -1 on failure. If we "failed"
116 * because someone else already had the lock, @c errno is set to
119 int tryacquire_write ();
122 * This is only here to make the ACE_Recursive_Thread_Mutex
123 * interface consistent with the other synchronization APIs.
124 * Assumes the caller has already acquired the mutex using one of
125 * the above calls, and returns 0 (success) always.
127 int tryacquire_write_upgrade ();
130 * Releases a recursive mutex (will not release mutex until all the
131 * nesting level drops to 0, which means the mutex is no longer
136 /// Return the id of the thread that currently owns the mutex.
137 ACE_thread_t
get_thread_id ();
140 * Return the nesting level of the recursion. When a thread has
141 * acquired the mutex for the first time, the nesting level == 1.
142 * The nesting level is incremented every time the thread acquires
143 * the mutex recursively. Note that if the ACE_HAS_RECURSIVE_MUTEXES
144 * macro is enabled then this method may return -1 on platforms that
145 * do not expose the internal count.
147 int get_nesting_level ();
149 /// Returns a reference to the recursive mutex;
150 ACE_recursive_thread_mutex_t
&lock ();
152 /// Returns a reference to the recursive mutex's internal mutex;
153 ACE_thread_mutex_t
&get_nesting_mutex ();
155 /// Dump the state of an object.
158 /// Declare the dynamic allocation hooks.
159 ACE_ALLOC_HOOK_DECLARE
;
162 // = This method should *not* be public (they hold no locks...)
163 void set_thread_id (ACE_thread_t t
);
166 ACE_recursive_thread_mutex_t lock_
;
168 /// Keeps track of whether remove() has been called yet to avoid
169 /// multiple remove() calls, e.g., explicitly and implicitly in the
170 /// destructor. This flag isn't protected by a lock, so make sure
171 /// that you don't have multiple threads simultaneously calling
172 /// remove() on the same object, which is a bad idea anyway...
176 void operator= (const ACE_Recursive_Thread_Mutex
&) = delete;
177 ACE_Recursive_Thread_Mutex (const ACE_Recursive_Thread_Mutex
&) = delete;
180 ACE_END_VERSIONED_NAMESPACE_DECL
182 #if defined (__ACE_INLINE__)
183 #include "ace/Recursive_Thread_Mutex.inl"
184 #endif /* __ACE_INLINE__ */
186 #endif /* !ACE_HAS_THREADS */
188 #include /**/ "ace/post.h"
189 #endif /* ACE_RECURSIVE_THREAD_MUTEX_H */