--- linuxsampler/trunk/src/common/Mutex.h 2004/07/01 04:25:55 165 +++ linuxsampler/trunk/src/common/Mutex.h 2014/01/10 13:53:19 2501 @@ -3,6 +3,7 @@ * LinuxSampler - modular, streaming capable sampler * * * * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * + * Copyright (C) 2005 - 2014 Christian Schoenebeck * * * * 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 * @@ -23,18 +24,110 @@ #ifndef __MUTEX_H__ #define __MUTEX_H__ +#if defined(WIN32) +#include +#else #include +#endif +namespace LinuxSampler { + +/** @brief Mutual exclusive objects + * + * This class provides the classical thread / process synchronisation + * technique called Mutex. It is used to protect critical sections, that is + * resources (typically data structures) from being used at the same time by + * different threads or processes which otherwise might turn into undefined + * and of course undesired behavior. + * + * Note: as this technique might block the calling thread and also implies + * a system call, this should not be used directly in realtime sensitive + * threads! + */ class Mutex { public: + /** + * Constructor + */ Mutex(); - ~Mutex(); + + /** + * Destructor + */ + virtual ~Mutex(); + + /** @brief Lock this Mutex. + * + * If this Mutex object is currently be locked by another thread, + * then the calling thread will be blocked until the other thread + * unlocks this Mutex object. The calling thread though can safely + * call this method several times without danger to be blocked + * himself. + * + * The calling thread should call Unlock() as soon as the critical + * section was left. + */ void Lock(); + + /** @brief Try to lock this Mutex. + * + * Same as Lock() except that this method won't block the calling + * thread in case this Mutex object is currently locked by another + * thread. So this call will always immediately return and the + * return value has to be checked if the locking request was + * successful or not. + * + * @returns true if the Mutex object could be locked, false if the + * Mutex is currently locked by another thread + */ bool Trylock(); + + /** @brief Unlock this Mutex. + * + * If other threads are currently blocked and waiting due to a + * Lock() call, one of them will be awaken. + */ void Unlock(); + protected: + #if defined(WIN32) + HANDLE hMutex; + #else pthread_mutex_t __posix_mutex; pthread_mutexattr_t __posix_mutexattr; + #endif }; +// Lock guard for exception safe locking +class LockGuard { +public: + LockGuard(Mutex& m) : pm(&m) { + m.Lock(); + } + + /** + * Empty LockGuard. This constructor can be used to implement conditional + * mutex protection like: + * @code + * Mutex m; + * LockGuard g; + * if (requiresMutexProtection()) g = LockGuard(m); + * @endcode + */ + LockGuard() : pm(NULL) { + } + + LockGuard(const LockGuard& g) : pm(g.pm) { + if (pm) pm->Lock(); + } + + ~LockGuard() { + if (pm) pm->Unlock(); + } +private: + Mutex* pm; +}; + +} // namespace LinuxSampler + #endif // __MUTEX_H__