1
0
Fork 0

added isLocked() flag for ConditionLocker

This commit is contained in:
jsteemann 2017-04-27 13:01:30 +02:00
parent c99d64b5cc
commit 8b7fe79ebb
4 changed files with 32 additions and 117 deletions

View File

@ -31,18 +31,16 @@
using namespace arangodb::basics; using namespace arangodb::basics;
////////////////////////////////////////////////////////////////////////////////
/// @brief locks the condition variable /// @brief locks the condition variable
/// ///
/// The constructors locks the condition variable, the destructors unlocks /// The constructors locks the condition variable, the destructors unlocks
/// the condition variable /// the condition variable
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_SHOW_LOCK_TIME #ifdef TRI_SHOW_LOCK_TIME
ConditionLocker::ConditionLocker(ConditionVariable* conditionVariable, ConditionLocker::ConditionLocker(ConditionVariable* conditionVariable,
char const* file, int line) char const* file, int line)
: _conditionVariable(conditionVariable), : _conditionVariable(conditionVariable),
_isLocked(true),
_file(file), _file(file),
_line(line), _line(line),
_time(0.0) { _time(0.0) {
@ -54,18 +52,17 @@ ConditionLocker::ConditionLocker(ConditionVariable* conditionVariable,
#else #else
ConditionLocker::ConditionLocker(ConditionVariable* conditionVariable) ConditionLocker::ConditionLocker(ConditionVariable* conditionVariable)
: _conditionVariable(conditionVariable) { : _conditionVariable(conditionVariable), _isLocked(true) {
_conditionVariable->lock(); _conditionVariable->lock();
} }
#endif #endif
////////////////////////////////////////////////////////////////////////////////
/// @brief unlocks the condition variable /// @brief unlocks the condition variable
////////////////////////////////////////////////////////////////////////////////
ConditionLocker::~ConditionLocker() { ConditionLocker::~ConditionLocker() {
_conditionVariable->unlock(); if (_isLocked) {
unlock();
}
#ifdef TRI_SHOW_LOCK_TIME #ifdef TRI_SHOW_LOCK_TIME
if (_time > TRI_SHOW_LOCK_THRESHOLD) { if (_time > TRI_SHOW_LOCK_THRESHOLD) {
@ -74,41 +71,33 @@ ConditionLocker::~ConditionLocker() {
#endif #endif
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief waits for an event to occur /// @brief waits for an event to occur
////////////////////////////////////////////////////////////////////////////////
void ConditionLocker::wait() { _conditionVariable->wait(); } void ConditionLocker::wait() { _conditionVariable->wait(); }
////////////////////////////////////////////////////////////////////////////////
/// @brief waits for an event to occur, with a timeout in microseconds /// @brief waits for an event to occur, with a timeout in microseconds
/// returns true when the condition was signaled, false on timeout /// returns true when the condition was signaled, false on timeout
////////////////////////////////////////////////////////////////////////////////
bool ConditionLocker::wait(uint64_t delay) { bool ConditionLocker::wait(uint64_t delay) {
return _conditionVariable->wait(delay); return _conditionVariable->wait(delay);
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief broadcasts an event /// @brief broadcasts an event
////////////////////////////////////////////////////////////////////////////////
void ConditionLocker::broadcast() { _conditionVariable->broadcast(); } void ConditionLocker::broadcast() { _conditionVariable->broadcast(); }
////////////////////////////////////////////////////////////////////////////////
/// @brief signals an event /// @brief signals an event
////////////////////////////////////////////////////////////////////////////////
void ConditionLocker::signal() { _conditionVariable->signal(); } void ConditionLocker::signal() { _conditionVariable->signal(); }
////////////////////////////////////////////////////////////////////////////////
/// @brief unlocks the variable (handle with care, no exception allowed) /// @brief unlocks the variable (handle with care, no exception allowed)
//////////////////////////////////////////////////////////////////////////////// void ConditionLocker::unlock() {
if (_isLocked) {
_conditionVariable->unlock();
_isLocked = false;
}
}
void ConditionLocker::unlock() { _conditionVariable->unlock(); }
////////////////////////////////////////////////////////////////////////////////
/// @brief relock the variable after unlock /// @brief relock the variable after unlock
//////////////////////////////////////////////////////////////////////////////// void ConditionLocker::lock() {
TRI_ASSERT(!_isLocked);
_conditionVariable->lock();
_isLocked = true;
}
void ConditionLocker::lock() { _conditionVariable->lock(); }

View File

@ -27,10 +27,7 @@
#include "Basics/Common.h" #include "Basics/Common.h"
////////////////////////////////////////////////////////////////////////////////
/// @brief construct locker with file and line information /// @brief construct locker with file and line information
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_SHOW_LOCK_TIME #ifdef TRI_SHOW_LOCK_TIME
#define CONDITION_LOCKER(a, b) \ #define CONDITION_LOCKER(a, b) \
@ -46,26 +43,20 @@ namespace arangodb {
namespace basics { namespace basics {
class ConditionVariable; class ConditionVariable;
////////////////////////////////////////////////////////////////////////////////
/// @brief condition locker /// @brief condition locker
/// ///
/// A ConditionLocker locks a condition when constructed and releases the lock /// A ConditionLocker locks a condition when constructed and releases the lock
/// when destroyed. It is possible the wait for an event in which case the lock /// when destroyed. It is possible the wait for an event in which case the lock
/// is released or to broadcast an event. /// is released or to broadcast an event.
////////////////////////////////////////////////////////////////////////////////
class ConditionLocker { class ConditionLocker {
ConditionLocker(ConditionLocker const&); ConditionLocker(ConditionLocker const&);
ConditionLocker& operator=(ConditionLocker const&); ConditionLocker& operator=(ConditionLocker const&);
public: public:
////////////////////////////////////////////////////////////////////////////////
/// @brief locks the condition variable /// @brief locks the condition variable
/// ///
/// The constructor locks the condition variable, the destructor unlocks /// The constructor locks the condition variable, the destructor unlocks
/// the condition variable /// the condition variable
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_SHOW_LOCK_TIME #ifdef TRI_SHOW_LOCK_TIME
ConditionLocker(ConditionVariable* conditionVariable, char const* file, ConditionLocker(ConditionVariable* conditionVariable, char const* file,
@ -77,75 +68,49 @@ class ConditionLocker {
#endif #endif
//////////////////////////////////////////////////////////////////////////////
/// @brief unlocks the condition variable /// @brief unlocks the condition variable
//////////////////////////////////////////////////////////////////////////////
~ConditionLocker(); ~ConditionLocker();
public: public:
//////////////////////////////////////////////////////////////////////////////
/// @brief waits for an event to occur /// @brief whether or not the condition is locked
////////////////////////////////////////////////////////////////////////////// bool isLocked() const { return _isLocked; }
/// @brief waits for an event to occur
void wait(); void wait();
//////////////////////////////////////////////////////////////////////////////
/// @brief waits for an event to occur, using a timeout in micro seconds /// @brief waits for an event to occur, using a timeout in micro seconds
/// returns true when the condition was signaled, false on timeout /// returns true when the condition was signaled, false on timeout
//////////////////////////////////////////////////////////////////////////////
bool wait(uint64_t); bool wait(uint64_t);
//////////////////////////////////////////////////////////////////////////////
/// @brief broadcasts an event /// @brief broadcasts an event
//////////////////////////////////////////////////////////////////////////////
void broadcast(); void broadcast();
//////////////////////////////////////////////////////////////////////////////
/// @brief signals an event /// @brief signals an event
//////////////////////////////////////////////////////////////////////////////
void signal(); void signal();
//////////////////////////////////////////////////////////////////////////////
/// @brief unlocks the variable (handle with care, no exception allowed) /// @brief unlocks the variable (handle with care, no exception allowed)
//////////////////////////////////////////////////////////////////////////////
void unlock(); void unlock();
//////////////////////////////////////////////////////////////////////////////
/// @brief relock the variable after unlock /// @brief relock the variable after unlock
//////////////////////////////////////////////////////////////////////////////
void lock(); void lock();
private: private:
//////////////////////////////////////////////////////////////////////////////
/// @brief the condition /// @brief the condition
//////////////////////////////////////////////////////////////////////////////
ConditionVariable* _conditionVariable; ConditionVariable* _conditionVariable;
/// @brief lock state
bool _isLocked;
#ifdef TRI_SHOW_LOCK_TIME #ifdef TRI_SHOW_LOCK_TIME
//////////////////////////////////////////////////////////////////////////////
/// @brief file /// @brief file
//////////////////////////////////////////////////////////////////////////////
char const* _file; char const* _file;
//////////////////////////////////////////////////////////////////////////////
/// @brief line number /// @brief line number
//////////////////////////////////////////////////////////////////////////////
int _line; int _line;
//////////////////////////////////////////////////////////////////////////////
/// @brief lock time /// @brief lock time
//////////////////////////////////////////////////////////////////////////////
double _time; double _time;
#endif #endif

View File

@ -31,12 +31,9 @@
using namespace arangodb; using namespace arangodb;
using namespace arangodb::basics; using namespace arangodb::basics;
////////////////////////////////////////////////////////////////////////////////
/// @brief aquires a lock /// @brief aquires a lock
/// ///
/// The constructor aquires a lock, the destructors releases the lock. /// The constructor aquires a lock, the destructors releases the lock.
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_SHOW_LOCK_TIME #ifdef TRI_SHOW_LOCK_TIME
MutexLocker::MutexLocker(Mutex* mutex, char const* file, int line) MutexLocker::MutexLocker(Mutex* mutex, char const* file, int line)
@ -54,10 +51,7 @@ MutexLocker::MutexLocker(Mutex* mutex) : _mutex(mutex), _isLocked(true) {
#endif #endif
////////////////////////////////////////////////////////////////////////////////
/// @brief releases the lock /// @brief releases the lock
////////////////////////////////////////////////////////////////////////////////
MutexLocker::~MutexLocker() { MutexLocker::~MutexLocker() {
if (_isLocked) { if (_isLocked) {
_mutex->unlock(); _mutex->unlock();
@ -70,6 +64,12 @@ MutexLocker::~MutexLocker() {
#endif #endif
} }
void MutexLocker::lock() {
TRI_ASSERT(!_isLocked);
_mutex->lock();
_isLocked = true;
}
void MutexLocker::unlock() { void MutexLocker::unlock() {
if (_isLocked) { if (_isLocked) {
_mutex->unlock(); _mutex->unlock();
@ -81,10 +81,7 @@ TryMutexLocker::TryMutexLocker(Mutex* mutex) : _mutex(mutex), _isLocked(true) {
_isLocked = _mutex->tryLock(); _isLocked = _mutex->tryLock();
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief releases the lock /// @brief releases the lock
////////////////////////////////////////////////////////////////////////////////
TryMutexLocker::~TryMutexLocker() { TryMutexLocker::~TryMutexLocker() {
if (_isLocked) { if (_isLocked) {
_mutex->unlock(); _mutex->unlock();

View File

@ -28,13 +28,10 @@
#include "Basics/Common.h" #include "Basics/Common.h"
#include "Basics/Mutex.h" #include "Basics/Mutex.h"
////////////////////////////////////////////////////////////////////////////////
/// @brief construct locker with file and line information /// @brief construct locker with file and line information
/// ///
/// Ones needs to use macros twice to get a unique variable based on the line /// Ones needs to use macros twice to get a unique variable based on the line
/// number. /// number.
////////////////////////////////////////////////////////////////////////////////
#define MUTEX_LOCKER_VAR_B(a) MUTEX_LOCKER_VAR_A(a) #define MUTEX_LOCKER_VAR_B(a) MUTEX_LOCKER_VAR_A(a)
#ifdef TRI_SHOW_LOCK_TIME #ifdef TRI_SHOW_LOCK_TIME
@ -53,24 +50,18 @@
namespace arangodb { namespace arangodb {
namespace basics { namespace basics {
////////////////////////////////////////////////////////////////////////////////
/// @brief mutex locker /// @brief mutex locker
/// ///
/// A MutexLocker locks a mutex during its lifetime und unlocks the mutex /// A MutexLocker locks a mutex during its lifetime und unlocks the mutex
/// when it is destroyed. /// when it is destroyed.
////////////////////////////////////////////////////////////////////////////////
class MutexLocker { class MutexLocker {
MutexLocker(MutexLocker const&) = delete; MutexLocker(MutexLocker const&) = delete;
MutexLocker& operator=(MutexLocker const&) = delete; MutexLocker& operator=(MutexLocker const&) = delete;
public: public:
////////////////////////////////////////////////////////////////////////////////
/// @brief aquires a lock /// @brief aquires a lock
/// ///
/// The constructor aquires a lock, the destructor releases the lock. /// The constructor aquires a lock, the destructor releases the lock.
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_SHOW_LOCK_TIME #ifdef TRI_SHOW_LOCK_TIME
MutexLocker(Mutex* mutex, char const* file, int line); MutexLocker(Mutex* mutex, char const* file, int line);
@ -86,43 +77,28 @@ class MutexLocker {
bool isLocked() const { return _isLocked; } bool isLocked() const { return _isLocked; }
////////////////////////////////////////////////////////////////////////////// /// @brief locks the mutex
/// @brief releases the lock void lock();
//////////////////////////////////////////////////////////////////////////////
/// @brief releases the mutex
void unlock(); void unlock();
private: private:
//////////////////////////////////////////////////////////////////////////////
/// @brief the mutex /// @brief the mutex
//////////////////////////////////////////////////////////////////////////////
Mutex* _mutex; Mutex* _mutex;
//////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the mutex is locked /// @brief whether or not the mutex is locked
//////////////////////////////////////////////////////////////////////////////
bool _isLocked; bool _isLocked;
#ifdef TRI_SHOW_LOCK_TIME #ifdef TRI_SHOW_LOCK_TIME
//////////////////////////////////////////////////////////////////////////////
/// @brief file /// @brief file
//////////////////////////////////////////////////////////////////////////////
char const* _file; char const* _file;
//////////////////////////////////////////////////////////////////////////////
/// @brief line number /// @brief line number
//////////////////////////////////////////////////////////////////////////////
int _line; int _line;
//////////////////////////////////////////////////////////////////////////////
/// @brief lock time /// @brief lock time
//////////////////////////////////////////////////////////////////////////////
double _time; double _time;
#endif #endif
@ -134,35 +110,23 @@ class TryMutexLocker {
TryMutexLocker& operator=(MutexLocker const&) = delete; TryMutexLocker& operator=(MutexLocker const&) = delete;
public: public:
////////////////////////////////////////////////////////////////////////////////
/// @brief tries to aquire a lock /// @brief tries to aquire a lock
/// ///
/// The constructor aquires a lock, the destructor releases the lock. /// The constructor aquires a lock, the destructor releases the lock.
////////////////////////////////////////////////////////////////////////////////
explicit TryMutexLocker(Mutex* mutex); explicit TryMutexLocker(Mutex* mutex);
~TryMutexLocker(); ~TryMutexLocker();
bool isLocked() const { return _isLocked; } bool isLocked() const { return _isLocked; }
//////////////////////////////////////////////////////////////////////////////
/// @brief releases the lock /// @brief releases the lock
//////////////////////////////////////////////////////////////////////////////
void unlock(); void unlock();
private: private:
//////////////////////////////////////////////////////////////////////////////
/// @brief the mutex /// @brief the mutex
//////////////////////////////////////////////////////////////////////////////
Mutex* _mutex; Mutex* _mutex;
//////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the mutex is locked /// @brief whether or not the mutex is locked
//////////////////////////////////////////////////////////////////////////////
bool _isLocked; bool _isLocked;
}; };
} }