BLocker

The BLocker class provides a locking mechanism that can be used to protect a section of critical code. The code that you want to protect should be placed between BLocker's Lock() and Unlock() calls:

BLocker *aLock = new BLocker();
. . .
aLock->Lock();
/* Protected code goes here. */
aLock->Unlock();

This guarantees that only one thread at a time will pass through the lock. After a thread has locked the BLocker object, subsequent attempts to lock by other threads are blocked until the first thread calls Unlock().

BLocker keeps track of the locking thread—the thread that's currently between Lock() and Unlock() calls. It lets the thread make nested calls to Lock() without blocking. Because of this, you can wrap a BLocker's lock around a series of functions that might, themselves, lock the same BLocker object.

For example, let's say you have a class called BadDog that's declared thus:

class BadDog : public BArchivable
{
public:
   void DoThis();
   void DoThat();
   void DoThisAndThat();

private:
   BLocker lock;
};

Let's implement the member functions as follows:

void BadDog::DoThis()
{
   lock.Lock();
   /* Do this here. */
   lock.Unlock();
}

void BadDog::DoThat()
{
   lock.Lock();
   /* Do that here. */
   lock.Unlock();
}

void BadDog::DoThisAndThat()
{
   lock.Lock();
   DoThis();
   DoThat();
   lock.Unlock();
}

Notice that DoThisAndThat() wraps the lock around its calls to DoThis() and DoThat(), both of which contain locks as well. A thread that gets past the Lock() call in DoThisAndThat() won't block when it calls the nested Lock() calls that it runs into in DoThis() and DoThat().

Keep in mind that nested Lock() calls must be balanced by an equal number of Unlock() calls.

See also: the BAutolock class

Creative Commons License
Legal Notice
This work is licensed under a Creative Commons Attribution-Non commercial-No Derivative Works 3.0 License.