+++ /dev/null
-#ifndef MUTEX_CLASS
-#define MUTEX_CLASS
-
-/*****************************************************************************\
-* *
-* Name : mutex *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1996-$now By Author. This program is free software; you can *
-* redistribute it and/or modify it under the terms of the GNU General Public *
-* License as published by the Free Software Foundation; either version 2 of *
-* the License or (at your option) any later version. This is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-#include "contracts.h"
-
-//! A simple primitive class that encapsulates OS support for mutual exclusion.
-/*!
- The word "mutex" is an abbreviation for "mutual exclusion". The mutex
- provides a simple synchronization object that supports the programming of
- critical sections. It is guaranteed to be safe for threads, but it is only
- useful within one application rather than between multiple applications.
- The mutex_base is hardly ever used directly; instead the mutex class should
- be used.
-*/
-
-namespace basis {
-
-class mutex : public virtual base_synchronizer
-{
-public:
- mutex(); //!< Constructs a new mutex.
-
- virtual ~mutex();
- //!< Destroys the mutex. It should not be locked upon destruction.
-
- //! Constructor for use with malloc/free instead of new/delete.
- void construct();
-
- //! Destructor for use with malloc/free instead of new/delete.
- void destruct();
-
- void lock();
- //!< Clamps down on the mutex, if possible.
- /*!< Otherwise the current thread is blocked until the mutex is unlocked. */
-
- void unlock();
- //!< Gives up the possession of the mutex.
-
- virtual void establish_lock();
- //!< Satisfies base class requirements for locking.
- virtual void repeal_lock();
- //!< Satisfies base class requirements for unlocking.
-
-private:
- void *c_os_mutex; //!< OS version of the mutex.
-
- void defang();
- //!< Removes the underlying OS synchronization primitive.
- /*!< This method renders this mutex object inoperable. This is useful
- when the reason for the lock has vanished, but the mutex object cannot be
- deleted yet. Sometimes it may still be referred to, but there is no
- longer any critical section to be protected. */
-
- mutex(const mutex &); //!< not allowed.
- mutex &operator =(const mutex &); //!< not allowed.
-};
-
-//////////////
-
-//! auto_synchronizer simplifies concurrent code by automatically unlocking.
-/*!
- This relies on the base_synchronizer for the form of the objects that
- will provide synchronization. The synchronization object is locked when the
- auto_synchronizer is created and it is unlocked when the auto_synchronizer
- is destroyed. This is most useful when the auto_synchronizer is an automatic
- object; the synchronization lock is grabbed at the point of creation (even
- in the middle of a function) and it is released when the function or block
- scope exits, thus freeing us of the responsibility of always unlocking the
- object before exiting from the critical section.
-
- More Detail:
- The auto_synchronizer provides an easy way to provide nearly idiot-proof
- synchronization of functions that share the same locking object. By giving
- the synchronizer a working object that's derived from synchronization_base,
- its mere construction establishes the lock and its destruction releases the
- lock. Thus you can protect a critical section in a function by creating
- the auto_synchronizer at the top of the function as an automatic object, or
- wherever in the function body is appropriate. When the function exits, the
- auto_synchronizer will be destroyed as part of the cleanup and the lock will
- be released. If there are multiple synchronization objects in a function,
- then be very careful. One must order them appropriately to avoid a deadlock.
-
- for example: @code
- mutex my_lock; // the real synchronization primitive.
- ... // lots of program in between.
- int calculate_average() {
- // our function that must control thread concurrency.
- auto_synchronizer syncho(my_lock); // establishes the lock.
- ... // lots of stuff done in the function in safety from other threads.
- } // end of the function. @endcode
-
- Note that there was no unlock of the mutex above. Remembering to unlock
- synchronization primitives is one of the most troublesome requirements of
- programming with multiple threads; the auto_synchronizer can be used in
- many situations to automate the release of the lock.
-*/
-
-class auto_synchronizer
-{
-public:
- auto_synchronizer(base_synchronizer &locker) : _locker(locker)
- { _locker.establish_lock(); }
- //!< Construction locks the "locker" object for the current program scope.
- /*!< This automatically locks a synchronization object until the current
- scope (such as a function or even just a block) is exited, which implements
- synchronization without needing multiple unlock calls before every return
- statement. */
-
- ~auto_synchronizer() { _locker.repeal_lock(); }
- //!< Releases the lock as this object goes out of scope.
-
-private:
- base_synchronizer &_locker; //!< the locking object.
-
- // disallowed.
- auto_synchronizer(const auto_synchronizer &locker);
- auto_synchronizer &operator =(const auto_synchronizer &locker);
-};
-
-} //namespace.
-
-#endif
-