The Guard Classes
The guard classes are a family of helper classes commonly used to manipulate synchronization objects.
As explained in
“Using Guards”, the guard classes use the “resource acquisition is initialization” idiom. The
RWTLockGuard template class uses this idiom for automatic acquisition and release of synchronization resources. The lock guard constructor calls an
acquire() member provided by the synchronization resource. The lock guard destructor calls the
release() member of an acquired resource.
Using a Lock Guard
To use a lock guard, declare a named instance of the guard class and initialize it with a reference to the synchronization mechanism, as shown in
Example 39.
Example 39 – Using a lock guard
RWMutexLock mutex;
{
RWTLockGuard<RWMutexLock> lock(mutex); // 1
// Mutex is acquired!
} // 2
// Mutex is released!
Releasing and Reacquiring a Guarded Lock
To release and reacquire a guarded lock, you should use the
release() and
acquire() members of the guard object. as shown in
Example 40. These member functions update the internal state of the guard so that the destructor does not attempt to release a lock that is no longer held.
Example 40 – Releasing and reacquiring a guarded lock
{
RWTLockGuard<RWMutexLock> lock(mutex);
// Mutex is acquired!
lock.release();
// Mutex is released!
lock.acquire();
// Mutex is acquired!
}
// Mutex is released!
Using the Unlock Guard Class
The same result can be achieved by using an
RWTUnlockGuard to temporarily release then reacquire a synchronization resource, as shown in
Example 41. The unlock guard class works in the same way as the lock guard class, except that it releases the resource in the constructor, and reacquires it in the destructor.
Example 41 – Using an unlock guard
{
RWTLockGuard<RWMutexLock> lock(mutex);
// Mutex is acquired!
{
RWTUnlockGuard<RWMutexLock> unlock(mutex);
// Mutex is released!
}
// Mutex is acquired!
}
// Mutex is released!
Using the RWTTryLockGuard Template Class
The
RWTTryLockGuard template class defines a constructor that uses the resource member function
tryAcquire(), to conditionally acquire a resource. The
tryAcquire() function only acquires the resource when it is immediately available. It returns
true if the resource was successfully acquired and
false if the resource is currently owned by another thread. The destructor for this class releases the resource, but only if it was and is still acquired. The try-lock guard method
isAcquired() can be used to test whether or not the acquisition was successful.
Example 42 – Using a try-lock guard for conditional acquisition and release
{
RWTTryLockGuard<RWMutexLock> lock(mutex);
if (lock.isAcquired()) {
// Mutex is acquired!
}
else {
// Mutex was not acquired!
}
}
// Mutex is released (if acquired)!
Using Classes with Read-Write Synchronization Resources
The remaining guard classes are used with read-write synchronization resources such as
RWReadersWriterLock. They are:
These guards behave in a manner identical to the simple guard classes, but rely on an acquisition interface that has been divided into read and write access:
Read Interface | Write Interface |
acquireRead() | acquireWrite() |
tryAcquireRead() | tryAcquireWrite() |