|
BDE 4.14.0 Production release
|
Macros | |
| #define | BSLMT_READERWRITERLOCKASSERT_IS_LOCKED(rwLock_p) ((void) 0) |
| #define | BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_SAFE(rwLock_p) ((void) 0) |
| #define | BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_OPT(rwLock_p) ((void) 0) |
| #define | BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_READ(rwLock_p) ((void) 0) |
| #define | BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_READ_SAFE(rwLock_p) ((void) 0) |
| #define | BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_READ_OPT(rwLock_p) ((void) 0) |
| #define | BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_WRITE(rwLock_p) ((void) 0) |
| #define | BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_WRITE_SAFE(rwLock_p) ((void) 0) |
| #define | BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_WRITE_OPT(rwLock_p) ((void) 0) |
Provide an assert macro for verifying reader-writer lock status.
This component provides macros for asserting that a reader-writer lock is locked. It does not distinguish between locks held by the current thread or other threads. If the macro is active in the current build mode, when the macro is called, if the supplied lock is unlocked, the assert handler installed for BSLS_ASSERT will be called. The assert handler installed by default will report an error and abort the task. Note that the type of lock (pointer) passed to each of these macros is determined at compile-time. See {Requirements on the Lock Type} below.
The nine macros defined by the component are analogous to the macros defined by BSLS_ASSERT:
In build modes where any one of these macros is not active, the presence of the macros has no effect.
If any of these asserts are in effect and fail (because the reader-writer lock in question was unlocked), the behavior parallels the behavior of the assertion macros defined in bsls_assert.h – bsls::Assert::invokeHandler is called, with a source code expression, the name of the source file, and the line number in the source file where the macro was called. If the default handler is installed, this will result in an error message and an abort.
Preconditions on locks typically require that the lock exist and is held by the calling thread. Unfortunately, lock ownership is not recorded in the lock and cannot be confirmed. The absence of any lock when the calling thread should hold one is certainly a problem; however, the existence of a lock does not guarantee that the complete precondition is met.
This system of macros accept pointers to reader-write lock objects that provide the methods:
isLocked,isLockedRead, andisLockedWriteTwo compatible classes are:
Although the required methods are typically const-qualified (i.e., "accessor" methods), that is not a requriement. Some client lock classes may implement these methods in terms of tryLock/unlock methods that require non-const access to the lock.
This section illustrates intended use of this component.
This example is an generalization of {bslmt_mutexassert |Example 1: Checking Consistency Within a Private Method}. In that example, a mutex was used to control access. Here, the (simple) mutex is replaced with a bslmt::ReaderWriterLock that is allows multiple concurrent access to the queue when conditions allow.
Sometimes multithreaded code is written such that the author of a function requires that a caller has already acquired a lock. The BSLMT_READERWRITERLOCKASSERT_IS_LOCKED* family of assertions allows the programmers to detect, using defensive programming techniques, if the required lock has not been acquired.
Suppose we have a fully thread-safe queue that contains int values, and is guarded by an internal bslmt::ReaderWriterLock object.
First, we define the container class:
Notice that this version of the MyThreadSafeQueue class has two public accessors, numElements and mean, and an additional manipulator, purgeAll.
Then, we implement most of the manipulators:
Notice that these implementations are identical to those shown in {bslmt_mutexassert |Example 1} except that the lock calls to the bslmt::Mutex there have been changed here to lockWrite calls on a bslmt::ReaderWriterLock. Both operations provide exclusive access to the container.
Also notice that, having learned the lesson of {bslmt_mutexassert |Example 1}, we were careful to acquire a write lock for the duration of each of these operation and to check the precondition of the private popImp method by using the BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_WRITE macro.
Finally notice that we use the "normal" flavor of the macro (rather than the *_SAFE version) because this test is not particularly expensive.
Next, we implement the accessor methods of the container:
Notice that each of these methods acquire a read lock for the duration of the operation. These locks allow shared access provided that the container is not changed, a reasonable assumption for these const-qualified methods.
Also notice that the bulk of the work of mean is done by the private method getStats. One's might except the private method to confirm that a lock was acquired by using the BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_READ macro; however, the reason for creating that private method is so that it can be reused by the purgeAll method, a non-const method that requires a write lock. Thus, getStats is an occassion to use the BSLMT_READERWRITERLOCKASSERT_IS_LOCKED check (for either a read lock or a write lock).
Next, we implement the purgeAll method:
Finally, we confirm that our accessors work as expected:
| #define BSLMT_READERWRITERLOCKASSERT_IS_LOCKED | ( | rwLock_p | ) | ((void) 0) |
| #define BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_OPT | ( | rwLock_p | ) | ((void) 0) |
| #define BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_READ | ( | rwLock_p | ) | ((void) 0) |
| #define BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_READ_OPT | ( | rwLock_p | ) | ((void) 0) |
| #define BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_READ_SAFE | ( | rwLock_p | ) | ((void) 0) |
| #define BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_SAFE | ( | rwLock_p | ) | ((void) 0) |
| #define BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_WRITE | ( | rwLock_p | ) | ((void) 0) |
| #define BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_WRITE_OPT | ( | rwLock_p | ) | ((void) 0) |
| #define BSLMT_READERWRITERLOCKASSERT_IS_LOCKED_WRITE_SAFE | ( | rwLock_p | ) | ((void) 0) |