#ifndef COMMON_H
#define COMMON_H
#include <mutex>
#include "error.h"
#include "handle.h"
class RecursiveMutex {
public:
class CondWrapper {
private:
int cnt;
bool locked;
inline void lockCnt(int cnt) { for(int i = 0; i < cnt; ++i) mutex.lock(); }
inline void unlockCnt(int cnt) { for(int i = 0; i < cnt; ++i) mutex.unlock(); }
public:
RecursiveMutex &mutex;
inline CondWrapper(RecursiveMutex &mutex):
cnt(mutex.count()), locked(true), mutex(mutex) { }
inline ~CondWrapper()
{ if (!locked) lock(); }
inline void lock() {
if (!locked) lockCnt(cnt);
locked = true;
}
inline void unlock() {
if (locked) unlockCnt(cnt);
locked = false;
}
inline bool try_lock() {
if (locked || cnt <= 0) return true;
if (!mutex.try_lock()) return false;
lockCnt(cnt-1);
locked = true;
return true;
}
};
private:
int cnt;
public:
std::recursive_mutex mutex;
inline RecursiveMutex(): cnt() { }
inline ~RecursiveMutex() { assert(!cnt); }
inline int count() const { return cnt; }
inline void lock() { mutex.lock(); ++cnt; }
inline bool try_lock() { if (mutex.try_lock()) { ++cnt; return true; } else return false; }
inline void unlock() { mutex.unlock(); --cnt; }
};
#endif