25 #include <condition_variable> 28 #pragma GCC diagnostic push 29 #pragma GCC diagnostic ignored "-Wunused-parameter" 30 #include <boost/thread.hpp> 32 #pragma GCC diagnostic pop 41 using Guard = std::lock_guard<std::mutex>;
44 using ReadGuard = boost::shared_lock<boost::shared_mutex>;
46 using UpgradeGuard = boost::upgrade_to_unique_lock<boost::shared_mutex>;
47 using WriteGuard = boost::unique_lock<boost::shared_mutex>;
49 template <
class GuardType,
class MutexType>
55 template <
class MutexType>
63 template <
class MutexType>
77 void lock() {
while (m_lock.test_and_set(std::memory_order_acquire)) {} }
78 void unlock() { m_lock.clear(std::memory_order_release); }
93 operator N()
const {
UniqueGuard l(m_mutex);
return m_value; }
95 void wait()
const { N old; {
UniqueGuard l(m_mutex); old = m_value; } waitNot(old); }
96 void wait(N
const& _v)
const {
UniqueGuard l(m_mutex); m_cv.wait(l, [&](){
return m_value == _v;}); }
97 void waitNot(N
const& _v)
const {
UniqueGuard l(m_mutex); m_cv.wait(l, [&](){
return m_value != _v;}); }
98 template <
class F>
void wait(
F const& _f)
const {
UniqueGuard l(m_mutex); m_cv.wait(l, _f); }
100 template <
class R,
class P>
void wait(std::chrono::duration<R, P> _d)
const { N old; {
UniqueGuard l(m_mutex); old = m_value; } waitNot(_d, old); }
101 template <
class R,
class P>
void wait(std::chrono::duration<R, P> _d, N
const& _v)
const {
UniqueGuard l(m_mutex); m_cv.wait_for(l, _d, [&](){
return m_value == _v;}); }
102 template <
class R,
class P>
void waitNot(std::chrono::duration<R, P> _d, N
const& _v)
const {
UniqueGuard l(m_mutex); m_cv.wait_for(l, _d, [&](){
return m_value != _v;}); }
103 template <
class R,
class P,
class F>
void wait(std::chrono::duration<R, P> _d,
F const& _f)
const {
UniqueGuard l(m_mutex); m_cv.wait_for(l, _d, _f); }
107 mutable std::condition_variable
m_cv;
144 #define DEV_GUARDED(MUTEX) \ 145 for (GenericGuardBool<Guard, Mutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false) 146 #define DEV_READ_GUARDED(MUTEX) \ 147 for (GenericGuardBool<ReadGuard, SharedMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false) 148 #define DEV_WRITE_GUARDED(MUTEX) \ 149 for (GenericGuardBool<WriteGuard, SharedMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false) 150 #define DEV_RECURSIVE_GUARDED(MUTEX) \ 151 for (GenericGuardBool<RecursiveGuard, RecursiveMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false) 152 #define DEV_UNGUARDED(MUTEX) \ 153 for (GenericUnguardBool<Mutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false) 154 #define DEV_READ_UNGUARDED(MUTEX) \ 155 for (GenericUnguardSharedBool<SharedMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false) 156 #define DEV_WRITE_UNGUARDED(MUTEX) \ 157 for (GenericUnguardBool<SharedMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false) GenericUnguardBool(MutexType &_m)
GenericUnguardSharedBool(MutexType &_m)
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
boost::upgrade_to_unique_lock< boost::shared_mutex > UpgradeGuard
Simple lock that waits for release without making context switch.
boost::upgrade_lock< boost::shared_mutex > UpgradableGuard
GenericGuardBool(MutexType &_m)
std::unique_lock< std::mutex > UniqueGuard
std::recursive_mutex RecursiveMutex
void wait(F const &_f) const
void wait(std::chrono::duration< R, P > _d, N const &_v) const
std::lock_guard< std::mutex > Guard
void wait(std::chrono::duration< R, P > _d) const
Notified & operator=(N const &_v)
std::lock_guard< SpinLock > SpinGuard
void waitNot(N const &_v) const
boost::shared_lock< boost::shared_mutex > ReadGuard
boost::unique_lock< boost::shared_mutex > WriteGuard
std::condition_variable m_cv
boost::shared_mutex SharedMutex
~GenericUnguardSharedBool()
std::lock_guard< std::recursive_mutex > RecursiveGuard
void wait(std::chrono::duration< R, P > _d, F const &_f) const
void wait(N const &_v) const
void waitNot(std::chrono::duration< R, P > _d, N const &_v) const