Ethereum  PoC-8
The C++ Implementation of Ethereum
Guards.h
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
22 #pragma once
23 
24 #include <mutex>
25 #include <condition_variable>
26 #include <atomic>
27 #pragma warning(push)
28 #pragma GCC diagnostic push
29 #pragma GCC diagnostic ignored "-Wunused-parameter"
30 #include <boost/thread.hpp>
31 #pragma warning(pop)
32 #pragma GCC diagnostic pop
33 
34 namespace dev
35 {
36 
37 using Mutex = std::mutex;
38 using RecursiveMutex = std::recursive_mutex;
39 using SharedMutex = boost::shared_mutex;
40 
41 using Guard = std::lock_guard<std::mutex>;
42 using UniqueGuard = std::unique_lock<std::mutex>;
43 using RecursiveGuard = std::lock_guard<std::recursive_mutex>;
44 using ReadGuard = boost::shared_lock<boost::shared_mutex>;
45 using UpgradableGuard = boost::upgrade_lock<boost::shared_mutex>;
46 using UpgradeGuard = boost::upgrade_to_unique_lock<boost::shared_mutex>;
47 using WriteGuard = boost::unique_lock<boost::shared_mutex>;
48 
49 template <class GuardType, class MutexType>
50 struct GenericGuardBool: GuardType
51 {
52  GenericGuardBool(MutexType& _m): GuardType(_m) {}
53  bool b = true;
54 };
55 template <class MutexType>
57 {
58  GenericUnguardBool(MutexType& _m): m(_m) { m.unlock(); }
59  ~GenericUnguardBool() { m.lock(); }
60  bool b = true;
61  MutexType& m;
62 };
63 template <class MutexType>
65 {
66  GenericUnguardSharedBool(MutexType& _m): m(_m) { m.unlock_shared(); }
67  ~GenericUnguardSharedBool() { m.lock_shared(); }
68  bool b = true;
69  MutexType& m;
70 };
71 
72 template <class N>
73 class Notified
74 {
75 public:
76  Notified() {}
77  Notified(N const& _v): m_value(_v) {}
78  Notified(Notified const&) = delete;
79  Notified& operator=(N const& _v) { UniqueGuard l(m_mutex); m_value = _v; m_cv.notify_all(); return *this; }
80 
81  operator N() const { UniqueGuard l(m_mutex); return m_value; }
82 
83  void wait() const { N old; { UniqueGuard l(m_mutex); old = m_value; } waitNot(old); }
84  void wait(N const& _v) const { UniqueGuard l(m_mutex); m_cv.wait(l, [&](){return m_value == _v;}); }
85  void waitNot(N const& _v) const { UniqueGuard l(m_mutex); m_cv.wait(l, [&](){return m_value != _v;}); }
86  template <class F> void wait(F const& _f) const { UniqueGuard l(m_mutex); m_cv.wait(l, _f); }
87 
88  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); }
89  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;}); }
90  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;}); }
91  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); }
92 
93 private:
94  mutable Mutex m_mutex;
95  mutable std::condition_variable m_cv;
96  N m_value;
97 };
98 
132 #define DEV_GUARDED(MUTEX) \
133  for (GenericGuardBool<Guard, Mutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)
134 #define DEV_READ_GUARDED(MUTEX) \
135  for (GenericGuardBool<ReadGuard, SharedMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)
136 #define DEV_WRITE_GUARDED(MUTEX) \
137  for (GenericGuardBool<WriteGuard, SharedMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)
138 #define DEV_RECURSIVE_GUARDED(MUTEX) \
139  for (GenericGuardBool<RecursiveGuard, RecursiveMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)
140 #define DEV_UNGUARDED(MUTEX) \
141  for (GenericUnguardBool<Mutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)
142 #define DEV_READ_UNGUARDED(MUTEX) \
143  for (GenericUnguardSharedBool<SharedMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)
144 #define DEV_WRITE_UNGUARDED(MUTEX) \
145  for (GenericUnguardBool<SharedMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)
146 
147 }
dev::SharedMutex
boost::shared_mutex SharedMutex
Definition: Guards.h:39
dev::Notified::Notified
Notified(Notified const &)=delete
dev::GenericUnguardBool::b
bool b
Definition: Guards.h:60
dev::GenericUnguardBool::~GenericUnguardBool
~GenericUnguardBool()
Definition: Guards.h:59
dev::GenericUnguardSharedBool
Definition: Guards.h:65
dev::UniqueGuard
std::unique_lock< std::mutex > UniqueGuard
Definition: Guards.h:42
dev::UpgradableGuard
boost::upgrade_lock< boost::shared_mutex > UpgradableGuard
Definition: Guards.h:45
dev::Guard
std::lock_guard< std::mutex > Guard
Definition: Guards.h:41
dev::Notified::operator=
Notified & operator=(N const &_v)
Definition: Guards.h:79
dev::Notified::wait
void wait(std::chrono::duration< R, P > _d) const
Definition: Guards.h:88
dev::GenericUnguardSharedBool::m
MutexType & m
Definition: Guards.h:69
dev::Notified::wait
void wait(std::chrono::duration< R, P > _d, N const &_v) const
Definition: Guards.h:89
dev::GenericUnguardBool::m
MutexType & m
Definition: Guards.h:61
dev::Notified::Notified
Notified()
Definition: Guards.h:76
dev::RecursiveGuard
std::lock_guard< std::recursive_mutex > RecursiveGuard
Definition: Guards.h:43
dev::GenericUnguardSharedBool::~GenericUnguardSharedBool
~GenericUnguardSharedBool()
Definition: Guards.h:67
dev::GenericGuardBool::b
bool b
Definition: Guards.h:53
dev::WriteGuard
boost::unique_lock< boost::shared_mutex > WriteGuard
Definition: Guards.h:47
dev::Notified::waitNot
void waitNot(std::chrono::duration< R, P > _d, N const &_v) const
Definition: Guards.h:90
dev::Notified::waitNot
void waitNot(N const &_v) const
Definition: Guards.h:85
dev::GenericUnguardBool
Definition: Guards.h:57
dev::GenericUnguardSharedBool::GenericUnguardSharedBool
GenericUnguardSharedBool(MutexType &_m)
Definition: Guards.h:66
F
#define F(x, y, z)
Definition: Hash.cpp:79
dev::ReadGuard
boost::shared_lock< boost::shared_mutex > ReadGuard
Definition: Guards.h:44
dev::Notified
Definition: Guards.h:74
dev::Mutex
std::mutex Mutex
Definition: Guards.h:37
dev::Notified::wait
void wait(F const &_f) const
Definition: Guards.h:86
dev::UpgradeGuard
boost::upgrade_to_unique_lock< boost::shared_mutex > UpgradeGuard
Definition: Guards.h:46
dev::Notified::wait
void wait(std::chrono::duration< R, P > _d, F const &_f) const
Definition: Guards.h:91
dev::Notified::Notified
Notified(N const &_v)
Definition: Guards.h:77
dev::RecursiveMutex
std::recursive_mutex RecursiveMutex
Definition: Guards.h:38
dev::Notified::wait
void wait() const
Definition: Guards.h:83
dev
Definition: Address.cpp:21
dev::GenericUnguardBool::GenericUnguardBool
GenericUnguardBool(MutexType &_m)
Definition: Guards.h:58
dev::GenericUnguardSharedBool::b
bool b
Definition: Guards.h:68
dev::GenericGuardBool::GenericGuardBool
GenericGuardBool(MutexType &_m)
Definition: Guards.h:52
dev::Notified::wait
void wait(N const &_v) const
Definition: Guards.h:84
dev::GenericGuardBool
Definition: Guards.h:51