BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslmt_recursivemutex.h
Go to the documentation of this file.
1/// @file bslmt_recursivemutex.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmt_recursivemutex.h -*-C++-*-
8#ifndef INCLUDED_BSLMT_RECURSIVEMUTEX
9#define INCLUDED_BSLMT_RECURSIVEMUTEX
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmt_recursivemutex bslmt_recursivemutex
15/// @brief Provide a platform-independent recursive mutex.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmt
19/// @{
20/// @addtogroup bslmt_recursivemutex
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmt_recursivemutex-purpose"> Purpose</a>
25/// * <a href="#bslmt_recursivemutex-classes"> Classes </a>
26/// * <a href="#bslmt_recursivemutex-description"> Description </a>
27/// * <a href="#bslmt_recursivemutex-usage"> Usage </a>
28/// * <a href="#bslmt_recursivemutex-example-1-basic-usage"> Example 1: Basic Usage </a>
29///
30/// # Purpose {#bslmt_recursivemutex-purpose}
31/// Provide a platform-independent recursive mutex.
32///
33/// # Classes {#bslmt_recursivemutex-classes}
34///
35/// - bslmt::RecursiveMutex: platform-independent recursive mutex
36///
37/// @see bslmt_mutex
38///
39/// # Description {#bslmt_recursivemutex-description}
40/// This component provides a mutually exclusive lock primitive
41/// ("mutex") that is "recursive" - a given thread can lock a recursive mutex
42/// multiple times, and then release it by unlocking it the same number of
43/// times. The `bslmt::RecursiveMutex` class provides the following operations:
44/// `lock`, `tryLock`, and `unlock`.
45///
46/// The non-recursive mutex `bslmt::Mutex` has substantially lower overhead than
47/// `bslmt::RecursiveMutex`, and should be used instead if at all possible. In
48/// particular, it is rare to need a recursive mutex.
49///
50/// The behavior is undefined if `unlock` is invoked on a
51/// `bslmt::RecursiveMutex` object from a thread that does not currently own the
52/// lock.
53///
54/// ## Usage {#bslmt_recursivemutex-usage}
55///
56///
57/// This section illustrates intended use of this component.
58///
59/// ### Example 1: Basic Usage {#bslmt_recursivemutex-example-1-basic-usage}
60///
61///
62/// As the name implies, `bslmt::RecursiveMutex` supports multiple calls to
63/// `lock`, which *must* be balanced by a corresponding number of calls to
64/// `unlock`. Suppose that we are using a `bslmt::RecursiveMutex` object to
65/// guarantee exclusive access to some object. The following sketches the
66/// "recursive" nature of `bslmt::RecursiveMutex`:
67/// @code
68/// bslmt::RecursiveMutex recMutex;
69/// @endcode
70/// Assume that we do not have exclusive access to the object.
71/// @code
72/// recMutex.lock(); // first level of locking
73/// @endcode
74/// We have exclusive access here.
75/// @code
76/// recMutex.lock(); // second level of locking
77/// @endcode
78/// We still have exclusive access.
79/// @code
80/// recMutex.unlock(); // release second level lock -- mutex stays locked
81/// @endcode
82/// We *still* have exclusive access.
83/// @code
84/// recMutex.unlock(); // release first level lock -- mutex is unlocked
85/// @endcode
86/// The two calls to `unlock` have balanced the two earlier calls to `lock`.
87/// Consequently, we no longer have exclusive access.
88///
89/// Note that `bslmt::RecursiveMutex` has substantially more overhead than does
90/// `bslmt::Mutex`. Consequently, the latter should be used unless recursive
91/// locking is truly warranted.
92/// @}
93/** @} */
94/** @} */
95
96/** @addtogroup bsl
97 * @{
98 */
99/** @addtogroup bslmt
100 * @{
101 */
102/** @addtogroup bslmt_recursivemutex
103 * @{
104 */
105
106#include <bslscm_version.h>
107
110#include <bslmt_platform.h>
111
112
113namespace bslmt {
114
115template <class THREAD_POLICY>
117
118 // ====================
119 // class RecursiveMutex
120 // ====================
121
122/// This `class` implements a recursive mutex (i.e., a mutex that can be
123/// locked any number of times by a thread, and then released by unlocking
124/// the mutex the same number of times). If there is an efficient native
125/// recursive mutex, this class wraps it. Otherwise, a reasonably efficient proprietary implementation is used.
126///
127/// \note Note that `Mutex` should be
128/// preferred if at all possible.
129///
130/// See @ref bslmt_recursivemutex
132
133 // DATA
134 RecursiveMutexImpl<Platform::ThreadPolicy> d_imp; // platform-specific
135 // implementation
136
137 private:
138 // NOT IMPLEMENTED
140 RecursiveMutex& operator=(const RecursiveMutex&);
141
142 public:
143 // CREATORS
144
145 /// Create a recursive mutex object in the unlocked state. This method
146 /// does not return normally unless there are sufficient system
147 /// resources to construct the object.
149
150 /// Destroy this recursive mutex object.
152
153 // MANIPULATORS
154
155 /// Acquire a lock on this object. If this object is currently locked,
156 /// then suspend execution of the current thread until a lock can be
157 /// acquired. Succeed immediately if this thread already holds the
158 /// lock.
159 void lock();
160
161 /// Attempt to acquire a lock on this object. Return 0 on success, and
162 /// a non-zero value if this object is already locked by another thread,
163 /// or if an error occurs. Succeed immediately if this thread already
164 /// holds the lock.
165 int tryLock();
166
167 /// Release a lock on this object that was previously acquired through a
168 /// call to `lock`, or a successful call to `tryLock`. To fully release
169 /// the lock, a thread must invoke `unlock` the same number of times it invoked `lock` and `tryLock`.
170 ///
171 /// \pre The behavior is undefined unless the
172 /// calling thread currently owns the lock on this recursive mutex.
173 void unlock();
174};
175
176// ============================================================================
177// INLINE DEFINITIONS
178// ============================================================================
179
180 // --------------------
181 // class RecursiveMutex
182 // --------------------
183
184// CREATORS
185inline
189
190inline
194
195// MANIPULATORS
196inline
198{
199 d_imp.lock();
200}
201
202inline
204{
205 return d_imp.tryLock();
206}
207
208inline
210{
211 d_imp.unlock();
212}
213
214} // close package namespace
215
216
217#endif
218
219// ----------------------------------------------------------------------------
220// Copyright 2015 Bloomberg Finance L.P.
221//
222// Licensed under the Apache License, Version 2.0 (the "License");
223// you may not use this file except in compliance with the License.
224// You may obtain a copy of the License at
225//
226// http://www.apache.org/licenses/LICENSE-2.0
227//
228// Unless required by applicable law or agreed to in writing, software
229// distributed under the License is distributed on an "AS IS" BASIS,
230// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
231// See the License for the specific language governing permissions and
232// limitations under the License.
233// ----------------------------- END-OF-FILE ----------------------------------
234
235/** @} */
236/** @} */
237/** @} */
Definition bslmt_recursivemutex.h:131
void unlock()
Definition bslmt_recursivemutex.h:209
int tryLock()
Definition bslmt_recursivemutex.h:203
~RecursiveMutex()
Destroy this recursive mutex object.
Definition bslmt_recursivemutex.h:191
RecursiveMutex()
Definition bslmt_recursivemutex.h:186
void lock()
Definition bslmt_recursivemutex.h:197
Definition bslmt_recursivemutex.h:116
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bslmt_barrier.h:344