Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bsls_bsllock
[Package bsls]

Provide a platform-independent mutex for use below bslmt. More...

Namespaces

namespace  bsls

Detailed Description

Outline
Purpose:
Provide a platform-independent mutex for use below bslmt.
Classes:
bsls::BslLock platform-independent mutex
bsls::BslLockGuard RAII mechanism for locking/unlocking a BslLock
See also:
Component bslmt_mutex
Description:
This component provides a mutually exclusive lock primitive ("mutex") by wrapping a suitable platform-specific mechanism. The bsls::BslLock class provides lock and unlock operations. Note that bsls::BslLock is not intended for direct client use; see bslmt_mutex instead. Also note that bsls::BslLock is not recursive.
This component also provides the bsls::BslLockGuard class, a mechanism that follows the RAII idiom for automatically acquiring and releasing the lock on an associated bsls::BslLock object. To ensure exception safety, client code should make use of a bsls::BslLockGuard object wherever appropriate rather than calling the methods on the associated bsls::BslLock object directly.
Usage:
In this section we show intended use of this component.
Example 1: Using bsls::BslLock to Make a class Thread-Safe:
In this example we illustrate the use of bsls::BslLock and bsls::BslLockGuard to write a thread-safe class.
First, we provide an elided definition of the my_Account class. Note the d_lock data member of type bsls::BslLock:
  class my_Account {
      // This 'class' implements a very simplistic bank account.  It is meant
      // for illustrative purposes only.

      // DATA
      double                d_money;  // amount of money in the account
      mutable bsls::BslLock d_lock;   // ensure exclusive access to 'd_money'

    // ...

    public:

      // ...

      // MANIPULATORS
      void deposit(double amount);
          // Atomically deposit the specified 'amount' of money into this
          // account.  The behavior is undefined unless 'amount >= 0.0'.

      int withdraw(double amount);
          // Atomically withdraw the specified 'amount' of money from this
          // account.  Return 0 on success, and a non-zero value otherwise.
          // The behavior is undefined unless 'amount >= 0.0'.

      // ...
  };
Next, we show the implementation of the two my_Account manipulators show-casing the use of bsls::BslLock and bsls::BslLockGuard:
  // MANIPULATORS
  void my_Account::deposit(double amount)
  {
Here, we use the interface of bsls::BslLock directly. However, wherever appropriate, a bsls::BslLockGuard object should be used instead to ensure that an acquired lock is always properly released, even if an exception is thrown:
      d_lock.lock();  // consider using 'bsls::BslLockGuard' (see 'withdraw')
      d_money += amount;
      d_lock.unlock();
  }
In contrast, withdraw uses a bsls::BslLockGuard to automatically acquire and release the lock. The lock is acquired as a side-effect of the construction of guard, and released when guard is destroyed upon returning from the function:
  int my_Account::withdraw(double amount)
  {
      bsls::BslLockGuard guard(&d_lock);  // a very good practice

      if (amount <= d_money) {
          d_money -= amount;
          return 0;
      }
      else {
          return -1;
      }
  }