The ACE Guard Classes





The ACE Guard Classes

Motivation

The uniformity of ACE's synchronization wrapper facade interfaces makes it easy to use them correctly, which helps to overcome several accidental complexities of cross-platform network programming. A separate issue that often occurs is related to lock scoping. Improper lock acquisition and release can result in system deadlock or inadvertent race conditions. When acquiring and releasing locks explicitly, it can be hard to ensure that all paths through the code release the lock, especially when C++ exceptions are thrown. ACE provides the ACE_Guard class and its associated subclasses to help assure that locks are acquired and released properly.

Class Capabilities

The ACE_Guard, ACE_Read_Guard, and ACE_Write_Guard classes implement the Scoped Locking idiom [SSRB00], which leverages the semantics of C++ class constructors and destructors to ensure a lock is acquired and released automatically upon entry to and exit from a block of C++ code, respectively. Figure shows the interface of these classes and their relationships to each other.

Figure. The ACE_Guard Family Class Diagrams

graphics/10fig02.gif

The following C++ source code segment from the ACE_Guard class shows how it implements the Scoped Locking idiom:

template <class LOCK>
class ACE_Guard
{
public:
  // Implicitly and automatically acquire the lock.
  ACE_Guard (LOCK &lock): lock_ (&lock) { acquire (); }
  // Implicitly release the lock.
  ~ACE_Guard () { release (); }

  // Explicitly acquire the lock.
  int acquire (); {
    return owner_ = lock_->acquire ();
  }

  // Explicitly release the lock.
  int release () {
    if (owner_ = -1)
      return -1;
    else {
      owner_ = -1
      return lock_->release ();
    }
  }

  int locked () const { return owner_ != -1; }
  // ... Other methods omitted

protected:
  // Used by subclasses to store pointer.
  ACE_Guard (LOCK *lock): lock_ (lock) {}

  // Pointer to the LOCK we're guarding.
  LOCK *lock_;

  // Keeps track of whether we acquired the lock or failed.
  int owner_;
};

An instance of ACE_Guard defines a scope of code over which a lock is acquired and then released automatically when the guard object is created and destroyed. ACE_Guard is a class template that works for any LOCK class whose public methods match the signatures contained in the ACE_LOCK* pseudo-class shown in Figure on page 209. As illustrated later, this includes most of the ACE synchronization wrapper facades presented in this chapter.

The ACE_Read_Guard and ACE_Write_Guard template classes have the same interface as the ACE_Guard class. However, their acquire() methods acquire read locks and write locks, respectively, via the acquire_read() and acquire_write() methods defined on the LOCK template parameter, as shown below:

template <class LOCK>
class ACE_Write_Guard : public ACE_Guard<LOCK>
{
public:
  // Automatically acquire the lock for writing.
  ACE_Write_Guard (LOCK &lock): ACE_Guard (&lock)
  { owner_ = lock_.acquire_write (); }

  // ... Same operations as <ACE_Guard>.
};

template <class LOCK>
class ACE_Read_Guard : public ACE_Guard<LOCK>
{
public:
  // Automatically acquire the lock for reading.
  ACE_Read_Guard (LOCK &lock): ACE_Guard (&lock)
  { owner_ = lock_.acquire_read (); }

  // ... Same operations as <ACE Guard>.
};

The Atomic_Op implementation on page 220 illustrates the use of the ACE_Write_Guard and ACE_Read_Guard classes.


     Python   SQL   Java   php   Perl 
     game development   web development   internet   *nix   graphics   hardware 
     telecommunications   C++ 
     Flash   Active Directory   Windows