BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmt_rwmutex.h
Go to the documentation of this file.
1/// @file bslmt_rwmutex.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmt_rwmutex.h -*-C++-*-
8#ifndef INCLUDED_BSLMT_RWMUTEX
9#define INCLUDED_BSLMT_RWMUTEX
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmt_rwmutex bslmt_rwmutex
15/// @brief Provide a platform-independent RW mutex class.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmt
19/// @{
20/// @addtogroup bslmt_rwmutex
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmt_rwmutex-purpose"> Purpose</a>
25/// * <a href="#bslmt_rwmutex-classes"> Classes </a>
26/// * <a href="#bslmt_rwmutex-description"> Description </a>
27/// * <a href="#bslmt_rwmutex-usage"> Usage </a>
28/// * <a href="#bslmt_rwmutex-example-1-basic-usage"> Example 1: Basic Usage </a>
29///
30/// # Purpose {#bslmt_rwmutex-purpose}
31/// Provide a platform-independent RW mutex class.
32///
33/// @deprecated Use @ref bslmt_readerwritermutex instead.
34///
35/// # Classes {#bslmt_rwmutex-classes}
36///
37/// - bslmt::RWMutex: platform-independent wrapper of an RW mutex
38///
39/// @see bslmt_readerwritermutex, bslmt_readerwriterlock,
40/// bslmt_readlockguard, bslmt_writelockguard
41///
42/// # Description {#bslmt_rwmutex-description}
43/// This component provides a class, `bslmt::RWMutex`, that defines
44/// a platform-independent RW mutex. An RW mutex provides for a shared "read"
45/// lock that may be held simultaneously by any number of threads, and a "write"
46/// lock that is exclusive (i.e., it may be held by only one thread at a time).
47/// The "write" lock is also exclusive with the "read" lock, so that no threads
48/// may hold a "read" lock while the "write" lock is held, and vice versa.
49///
50/// ## Usage {#bslmt_rwmutex-usage}
51///
52///
53/// This section illustrates intended use of this component.
54///
55/// ### Example 1: Basic Usage {#bslmt_rwmutex-example-1-basic-usage}
56///
57///
58/// TBD
59/// @}
60/** @} */
61/** @} */
62
63/** @addtogroup bsl
64 * @{
65 */
66/** @addtogroup bslmt
67 * @{
68 */
69/** @addtogroup bslmt_rwmutex
70 * @{
71 */
72
73#include <bslscm_version.h>
74
75#include <bslmt_platform.h>
76
77#include <bsls_assert.h>
78#include <bsls_platform.h>
79
80#if defined(BSLMT_PLATFORM_WIN32_THREADS) || defined(BSLS_PLATFORM_OS_AIX)
82#endif
83
84#ifdef BSLMT_PLATFORM_POSIX_THREADS
85#include <pthread.h>
86#endif
87#include <bsl_cstddef.h>
88
89
90namespace bslmt {
91
92template <class THREAD_POLICY>
94
95} // close package namespace
96
97#ifdef BSLMT_PLATFORM_POSIX_THREADS
98
99namespace bslmt {
100
101 // ================================
102 // struct RWMutexImpl<PosixThreads>
103 // ================================
104
105/// This is a platform-specific implementation detail that is not intended
106/// for use outside of this component. Use the `RWMutex` class instead.
107/// This structure is a wrapper around a POSIX RW lock on Sun (on AIX the
108/// POSIX RW lock has poor performance and no writer guarantees).
109template <>
110struct RWMutexImpl<Platform::PosixThreads> {
111
112 private:
113 // DATA
114 pthread_rwlock_t d_lock;
115
116 public:
117 // CREATORS
118 RWMutexImpl();
119 ~RWMutexImpl();
120
121 // MANIPULATORS
122 void lockRead();
123 void lockWrite();
124 int tryLockRead();
125 int tryLockWrite();
126 void unlock();
127};
128
129} // close package namespace
130
131#endif // BSLMT_PLATFORM_POSIX_THREADS
132
133namespace bslmt {
134
135 // =============
136 // class RWMutex
137 // =============
138
139/// This class is a platform-independent interface to a reader-writer lock
140/// ("RW mutex"). Multiple readers can safely hold the lock simultaneously,
141/// whereas only one writer is allowed to hold the lock at a time. This
142/// class uses the most efficient RW mutex implementation available for the
143/// current platform. Note that the implementation may allow readers to
144/// starve writers.
145///
146/// See @ref bslmt_rwmutex
147class RWMutex {
148
149 // DATA
150#if defined(BSLS_PLATFORM_OS_AIX) || defined(BSLMT_PLATFORM_WIN32_THREADS)
151 ReaderWriterLock d_impl;
152#else
154#endif
155
156 // NOT IMPLEMENTED
157 RWMutex(const RWMutex&);
158 RWMutex& operator=(const RWMutex&);
159
160 public:
161 // CREATORS
162
163 /// Create an RW mutex initialized to an unlocked state.
164 RWMutex();
165
166 /// Destroy this RW mutex. The behavior is undefined if the mutex
167 /// is in a locked state.
168 ~RWMutex();
169
170 // MANIPULATORS
171
172 /// Lock this reader-writer mutex for reading. If there are no active
173 /// or pending write locks, lock this mutex for reading and return
174 /// immediately. Otherwise, block until the read lock on this mutex is
175 /// acquired. Use `unlock` to release the lock on this mutex. The
176 /// behavior is undefined if this method is called from a thread that
177 /// already has a lock on this mutex.
178 void lockRead();
179
180 /// Lock this reader-writer mutex for writing. If there are no active
181 /// or pending locks on this mutex, lock this mutex for writing and
182 /// return immediately. Otherwise, block until the write lock on this
183 /// mutex is acquired. Use `unlock` to release the lock on this mutex.
184 /// The behavior is undefined if this method is called from a thread
185 /// that already has a lock on this mutex.
186 void lockWrite();
187
188 /// Attempt to lock this reader-writer mutex for reading. Immediately
189 /// return 0 on success, and a non-zero value if there are active or
190 /// pending writers. If successful, `unlock` must be used to release
191 /// the lock on this mutex. The behavior is undefined if this method is
192 /// called from a thread that already has a lock on this mutex.
193 int tryLockRead();
194
195 /// Attempt to lock this reader-writer mutex for writing. Immediately
196 /// return 0 on success, and a non-zero value if there are active or
197 /// pending locks on this mutex. If successful, `unlock` must be used
198 /// to release the lock on this mutex. The behavior is undefined if
199 /// this method is called from a thread that already has a lock on this
200 /// mutex.
201 int tryLockWrite();
202
203 /// Release the lock that the calling thread holds on this reader-writer
204 /// mutex. The behavior is undefined unless the calling thread
205 /// currently has a lock on this mutex.
206 void unlock();
207};
208
209
210// ============================================================================
211// INLINE DEFINITIONS
212// ============================================================================
213
214#ifdef BSLMT_PLATFORM_POSIX_THREADS
215
216 // ------------------
217 // struct RWMutexImpl
218 // ------------------
219
220// CREATORS
221inline
223{
224 const int rc = pthread_rwlock_init(&d_lock, NULL);
225
226 // pthread_rwlock_init should not return a failure code.
227
228 if (rc) {
229 BSLS_ASSERT_INVOKE_NORETURN("'pthread_rwlock_init' failed");
230 }
231}
232
233inline
234RWMutexImpl<bslmt::Platform::PosixThreads>::~RWMutexImpl()
235{
236 const int rc = pthread_rwlock_destroy(&d_lock);
237
238 // pthread_rwlock_destroy should not return a failure code.
239
240 BSLS_ASSERT_SAFE(0 == rc);
241 (void) rc; // suppress 'unused variable' warnings
242}
243
244// MANIPULATORS
245inline
246void
247RWMutexImpl<bslmt::Platform::PosixThreads>::lockRead()
248{
249 const int rc = pthread_rwlock_rdlock(&d_lock);
250
251 // pthread_rwlock_rdlock should not return a failure code.
252
253 BSLS_ASSERT_SAFE(0 == rc);
254 (void) rc; // suppress 'unused variable' warnings
255}
256
257inline
258void
259RWMutexImpl<bslmt::Platform::PosixThreads>::lockWrite()
260{
261 const int rc = pthread_rwlock_wrlock(&d_lock);
262
263 // pthread_rwlock_wrlock should not return a failure code.
264
265 BSLS_ASSERT_SAFE(0 == rc);
266 (void) rc; // suppress 'unused variable' warnings
267}
268
269inline
270int
271RWMutexImpl<bslmt::Platform::PosixThreads>::tryLockRead()
272{
273 return pthread_rwlock_tryrdlock(&d_lock) ? 1 : 0;
274}
275
276inline
277int
278RWMutexImpl<bslmt::Platform::PosixThreads>::tryLockWrite()
279{
280 return pthread_rwlock_trywrlock(&d_lock) ? 1 : 0;
281}
282
283inline
284void
285RWMutexImpl<bslmt::Platform::PosixThreads>::unlock()
286{
287 pthread_rwlock_unlock(&d_lock);
288}
289
290#endif // BSLMT_PLATFORM_POSIX_THREADS
291
292 // -------------
293 // class RWMutex
294 // -------------
295
296// CREATORS
297inline
301
302inline
306
307// MANIPULATORS
308inline
310{
311 d_impl.lockRead();
312}
313
314inline
316{
317 d_impl.lockWrite();
318}
319
320inline
322{
323 return d_impl.tryLockRead();
324}
325
326inline
328{
329 return d_impl.tryLockWrite();
330}
331
332inline
334{
335 d_impl.unlock();
336}
337
338} // close package namespace
339
340
341#endif
342
343// ----------------------------------------------------------------------------
344// Copyright 2023 Bloomberg Finance L.P.
345//
346// Licensed under the Apache License, Version 2.0 (the "License");
347// you may not use this file except in compliance with the License.
348// You may obtain a copy of the License at
349//
350// http://www.apache.org/licenses/LICENSE-2.0
351//
352// Unless required by applicable law or agreed to in writing, software
353// distributed under the License is distributed on an "AS IS" BASIS,
354// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
355// See the License for the specific language governing permissions and
356// limitations under the License.
357// ----------------------------- END-OF-FILE ----------------------------------
358
359/** @} */
360/** @} */
361/** @} */
Definition bslmt_rwmutex.h:147
int tryLockWrite()
Definition bslmt_rwmutex.h:327
int tryLockRead()
Definition bslmt_rwmutex.h:321
RWMutex()
Create an RW mutex initialized to an unlocked state.
Definition bslmt_rwmutex.h:298
~RWMutex()
Definition bslmt_rwmutex.h:303
void lockRead()
Definition bslmt_rwmutex.h:309
void unlock()
Definition bslmt_rwmutex.h:333
void lockWrite()
Definition bslmt_rwmutex.h:315
Definition bslmt_readerwriterlock.h:294
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_ASSERT_INVOKE_NORETURN(X)
Definition bsls_assert.h:1895
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bslmt_barrier.h:344
This struct provides a namespace for concurrency trait definitions.
Definition bslmt_platform.h:81
Definition bslmt_rwmutex.h:93