Lumiera  0.pre.03
»edit your freedom«
sync.hpp File Reference

Go to the source code of this file.

Description

Object Monitor based synchronisation.

The actual locking, signalling and waiting is implemented by delegating to the a mutex and for waiting also to a condition variable as provided by the C++ standard library. The purpose of the Sync baseclass is to provide a clear and simple „everyday“ concurrency coordination based on the Object Monitor Pattern. This pattern describes a way of dealing with synchronisation known to play well with scoping, encapsulation and responsibility for a single purpose. For performance critical code, other solutions (e.g. Atomics) might be preferable.

Usage

A class becomes lockable by inheriting from lib::Sync with the appropriate parametrisation. This causes any instance to inherit a monitor member (object), maintaining a dedicated a mutex and (optionally) a condition variable for waiting. The actual synchronisation is achieved by placing a guard object as local (stack) variable into a given scope (typically a member function body). This guard object of class lib::Sync::Lock accesses the enclosing object's monitor and automatically manages the locking and unlocking; optionally it may also be used to perform a wait-on-condition — the call to Lock::wait(predicate) will first check the predicate, and if it does not yield true, the thread will be put to sleep. It must be awakened from another thread by invoking notify_one|all and will then re-check the condition predicate. The wait_for variant allows to set a timeout to limit the sleep state, which implies however that the call may possibly return false in case the condition predicate is not (yet) fulfilled.

Note
  • It is important to select a suitable parametrisation of the monitor. This is done by specifying one of the defined policy classes.
  • Be sure to pick the recursive mutex implementation when recursive calls of synchronised functions can't be avoided. (performance penalty)
  • You can't use the Lock::wait and Lock::notify functions unless you pick a parametrisation including a condition variable.
  • The "this" pointer is fed to the ctor of the Lock guard object. Thus you may use any object's monitor as appropriate, especially in cases when adding the monitor to a given class may cause size problems.
  • There is a special variant of the Lock guard called ClassLock, which can be used to lock based on a type, not an instance.
See also
mutex.h
sync-locking-test.cpp
sync-waiting-test.cpp
usage example: receiving session coomands
usage example: subsystem start/shutdown

Definition in file sync.hpp.

#include "lib/error.hpp"
#include "lib/nocopy.hpp"
#include "lib/util.hpp"
#include <mutex>
#include <condition_variable>
#include <chrono>

Classes

struct  Condition< MTX >
 
class  Sync< CONF >::Lock
 scoped guard to control the actual locking. More...
 
class  Monitor< IMPL >
 Object Monitor for synchronisation and waiting. More...
 
struct  NoLocking
 
class  Sync< CONF >
 Facility for monitor object based locking. More...
 

Typedefs

using NonrecursiveLock_NoWait = std::mutex
 
using NonrecursiveLock_Waitable = Condition< std::mutex >
 
using RecursiveLock_NoWait = std::recursive_mutex
 
using RecursiveLock_Waitable = Condition< std::recursive_mutex >
 

Namespaces

 lib
 Implementation namespace for support and library code.
 
 lib::sync
 Helpers and building blocks for Monitor based synchronisation.