BDE 4.14.0 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
126/// proprietary implementation is used. Note that `Mutex` should be
127/// preferred if at all possible.
128///
129/// See @ref bslmt_recursivemutex
131
132 // DATA
133 RecursiveMutexImpl<Platform::ThreadPolicy> d_imp; // platform-specific
134 // implementation
135
136 // NOT IMPLEMENTED
138 RecursiveMutex& operator=(const RecursiveMutex&);
139
140 public:
141 // CREATORS
142
143 /// Create a recursive mutex object in the unlocked state. This method
144 /// does not return normally unless there are sufficient system
145 /// resources to construct the object.
147
148 /// Destroy this recursive mutex object.
150
151 // MANIPULATORS
152
153 /// Acquire a lock on this object. If this object is currently locked,
154 /// then suspend execution of the current thread until a lock can be
155 /// acquired. Succeed immediately if this thread already holds the
156 /// lock.
157 void lock();
158
159 /// Attempt to acquire a lock on this object. Return 0 on success, and
160 /// a non-zero value if this object is already locked by another thread,
161 /// or if an error occurs. Succeed immediately if this thread already
162 /// holds the lock.
163 int tryLock();
164
165 /// Release a lock on this object that was previously acquired through a
166 /// call to `lock`, or a successful call to `tryLock`. To fully release
167 /// the lock, a thread must invoke `unlock` the same number of times it
168 /// invoked `lock` and `tryLock`. The behavior is undefined unless the
169 /// calling thread currently owns the lock on this recursive mutex.
170 void unlock();
171};
172
173// ============================================================================
174// INLINE DEFINITIONS
175// ============================================================================
176
177 // --------------------
178 // class RecursiveMutex
179 // --------------------
180
181// CREATORS
182inline
186
187inline
191
192// MANIPULATORS
193inline
195{
196 d_imp.lock();
197}
198
199inline
201{
202 return d_imp.tryLock();
203}
204
205inline
207{
208 d_imp.unlock();
209}
210
211} // close package namespace
212
213
214#endif
215
216// ----------------------------------------------------------------------------
217// Copyright 2015 Bloomberg Finance L.P.
218//
219// Licensed under the Apache License, Version 2.0 (the "License");
220// you may not use this file except in compliance with the License.
221// You may obtain a copy of the License at
222//
223// http://www.apache.org/licenses/LICENSE-2.0
224//
225// Unless required by applicable law or agreed to in writing, software
226// distributed under the License is distributed on an "AS IS" BASIS,
227// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
228// See the License for the specific language governing permissions and
229// limitations under the License.
230// ----------------------------- END-OF-FILE ----------------------------------
231
232/** @} */
233/** @} */
234/** @} */
Definition bslmt_recursivemutex.h:130
void unlock()
Definition bslmt_recursivemutex.h:206
int tryLock()
Definition bslmt_recursivemutex.h:200
~RecursiveMutex()
Destroy this recursive mutex object.
Definition bslmt_recursivemutex.h:188
RecursiveMutex()
Definition bslmt_recursivemutex.h:183
void lock()
Definition bslmt_recursivemutex.h:194
Definition bslmt_recursivemutex.h:116
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bslmt_barrier.h:344