RWMutexLock RWSynchObject
LockGuard ReadLockGuard ReadUnlockGuard |
RWMutexLockRep TryLockGuard TryReadLockGuard |
TryWriteLockGuard UnlockGuard WriteLockGuard |
WriteUnlockGuard |
acquire() acquireRead() acquireWrite() |
getMutexLockRep() isAcquired() release() |
tryAcquire() tryAcquireRead() tryAcquireWrite() |
#include <rw/sync/RWTMutexLock.h>
RWMutexLock implements a mutex or mutual exclusion lock. It can be used to permit only one thread at a time to access a section of code that is to be treated as a single atomic operation. Mutexes are typically used to protect sections of code that access shared resources or data. The sensitive area of code, or critical section, is bracketed by calls to acquire and release on the mutex.
All operations on the mutex, except initialization, are themselves guaranteed to be atomic in order to prevent race conditions from destroying the integrity of the lock. However, there is no reliable mechanism to guarantee that a race condition will not occur during initialization of a mutex lock. Generally, the user can ensure this by creating and initializing all mutexes in a primary thread of execution, before other threads are spawned. However, in the common case, when a mutex is used to protect static global data, there is no portable way to atomically initialize the mutex because C++ defines the order of initialization of static variables to be implementation-specific.
RWMutexLock provides some protection against race conditions during initialization of static global mutexes by providing a special constructor that does no initialization. When this constructor is used, initialization is postponed until the first attempt to acquire the lock. In order to prevent race conditions during mutex initialization by using this constructor, the user must still make sure the first acquire operation on such a mutex is not attempted concurrently by two or more threads.
This class is primarily a portable object wrapper for platform-specific mutex implementations. For example, RWMutexLock uses an instance of pthread_mutex_t for POSIX conforming environments, mutex_t on Solaris platforms, a mutex semaphore represented by an HMTX handle under OS2, and a mutex represented by a HANDLE under Win32.
#include <rw/sync/RWMutexLock.h> // for RWMutexLock #include <rw/sync/RWTLockGuard.h> // for RWTLockGuard<T> class SavingsAccount { public: SavingsAccount(int initialBalance); void deposit(int amount); void withdraw(int amount); int balance(void); static void decreaseInterestRate(double decrement); static double getInterestRate(void); private: int balance_; static double interestRate_; RWMutexLock objectMutex_; // mutex to protect // instance data }; void SavingsAccount::deposit(int amount) { // Acquire mutex so that only one thread can access the // state. Normally you should use a LockGuard to acquire a // mutex that is to be released at the end of a scope. We // show the explicit form here for completeness. The // preferred form is shown below. objectMutex_.acquire(); balance_ += amount; objectMutex_.release(); } void SavingsAccount::withdraw(int amount) { // An RWTLockGuard acquires a synch. object // in its constructor and releases it in its destructor. // Preferred over explicit calls to acquire and release // on the mutex. This is because: // 1) you will never forget to do the release and // 2) if an exception is thrown from somewhere in your // function, the lock will always be released because all // objects on the stack will have their destructors called // as the stack is unwound // calls objectMutex_.acquire(): RWTLockGuard<RWMutexLock> lock(objectMutex_); balance_ -= amount; // objectMutex released in lock destructor. } int SavingsAccount::balance(void) { // RWMutexLock::LockGuard is a typedef of // RWTLockGuard<RWMutexLock>. It has the same effect // as above. This is the form that we prefer // for purely aesthetic reasons: RWMutexLock::LockGuard lock(objectMutex_); return balance_; // objectMutex released in lock destructor. }
typedef HMTX RWMutexLockRep; // OS/2 typedef pthread_mutex_t RWMutexLockRep; // POSIX typedef mutex_t RWMutexLockRep; // Solaris typedef HANDLE RWMutexLockRep; // Win32
RWMutexLockRep is the internal representation for the mutex.
typedef RWTLockGuard<RWMutexLock> LockGuard; typedef RWTReadLockGuard<RWMutexLock> ReadLockGuard; typedef RWTWriteLockGuard<RWMutexLock> WriteLockGuard; typedef RWTTryLockGuard<RWMutexLock> TryLockGuard; typedef RWTTryReadLockGuard<RWMutexLock> TryReadLockGuard; typedef RWTTryWriteLockGuard<RWMutexLock> TryWriteLockGuard; typedef RWTUnlockGuard<RWMutexLock> UnlockGuard; typedef RWTReadUnlockGuard<RWMutexLock> ReadUnlockGuard; typedef RWTWriteUnlockGuard<RWMutexLock> WriteUnlockGuard;
Predefined types for compatible guards.
RWMutexLock(RWStaticCtor);
Creates an RWMutexLock but does no direct initialization. The mutex will be initialized upon first use.
RWMutexLock(RWCancellationState
state=RW_CANCELLATION_DISABLED);
Creates and initializes an RWMutexLock. The thread cancellation state of the object is initialized to state. Possible exceptions include RWTHRResourceLimit and RWTHRInternalError.
~RWMutexLock(void);
Recovers the system resource used to implement the RWMutexLock. Possible exceptions include RWTHRInternalError.
void acquire(void);
Causes the current thread to block until the mutex is released, at which time the thread acquires the mutex and continues. In the debug version of the library, this function will produce an assertion and abort if a thread attempts to recursively acquire the same mutex. Possible exceptions include RWCancellation, RWTHRResourceLimit, and RWTHRInternalError.
This function will throw an RWCancellation object if the mutex has cancellation detection enabled and a runnable containing the calling thread has been canceled.
RWWaitStatus acquire(unsigned long milliseconds);
Blocks at least for the specified number of milliseconds, or until the mutex is released-whichever comes first. If the mutex is released within the specified time, acquires it, and continues. If the mutex is not released, returns RW_THR_TIMEOUT. In the debug version of the library, this function will produce an assertion and abort if a thread attempts to recursively acquire the same mutex.
Note that true timed-acquisition is not supported on all platforms. OS/2 and Win32 support it, but Solaris and POSIX do not. On those platforms that do not support true timed-acquisition, if the mutex cannot be acquired immediately, the function simply returns RW_THR_TIMEOUT. Timed mutex acquisition is available if the macro, RW_THR_HAS_TIMED_MUTEX_ACQUIRE is defined.
This function will throw an RWCancellation object if the mutex has cancellation detection enabled and a runnable containing the calling thread has been canceled. Other possible exceptions include RWTHRResourceLimit and RWTHRInternalError.
void acquireRead(void);
Calls acquire(). Provided for compatibility with Read/Write locks. Possible exceptions include RWCancellation, RWTHRResourceLimit, and RWTHRInternalError.
RWWaitStatus acquireRead(unsigned long milliseconds);
Calls acquire(milliseconds). Provided for compatibility with Read/Write locks. Possible exceptions include RWCancellation, RWTHRResourceLimit, and RWTHRInternalError.
void acquireWrite(void);
Calls acquire(). Provided for compatibility with Read/Write locks. Possible exceptions include RWCancellation, RWTHRResourceLimit, and RWTHRInternalError.
RWWaitStatus acquireWrite(unsigned long milliseconds);
Calls acquire(milliseconds). Provided for compatibility with Read/Write locks. Possible exceptions include RWCancellation, RWTHRResourceLimit, and RWTHRInternalError.
RWMutexLockRep* getMutexLockRep(void) const;
Provides access to the underlying mechanism.
RWBoolean isAcquired(void) const;
Determines whether the calling thread currently owns the mutex.
NOTE: Only available from the debug version of the library.
void release(void);
Releases the mutex, making it available. Possible exceptions include RWTHRInternalError.
RWBoolean tryAcquire(void);
Tries to acquire mutex without blocking. Returns TRUE if the mutex is acquired, and FALSE if the mutex is not acquired. Possible exceptions include RWCancellation, RWTHRResourceLimit, and RWTHRInternalError.
RWBoolean tryAcquireRead(void);
Calls tryAcquire(). Provided for compatibility with Read/Write locks. Possible exceptions include RWCancellation, RWTHRResourceLimit, and RWTHRInternalError.
RWBoolean tryAcquireWrite(void);
Calls tryAcquire(). Provided for compatibility with Read/Write locks. Possible exceptions include RWCancellation, RWTHRResourceLimit, and RWTHRInternalError.
RWNullMutexLock, RWTLockGuard<Resource>, RWTUnlockGuard<Resource>, RWTTryLockGuard<Resource>
©Copyright 2000, Rogue Wave Software, Inc.
Contact Rogue Wave about documentation or support issues.