15 #ifndef SHAKA_EMBEDDED_DEBUG_MUTEX_H_ 16 #define SHAKA_EMBEDDED_DEBUG_MUTEX_H_ 18 #include <glog/logging.h> 24 #include <unordered_set> 42 template <
typename _Mutex>
48 CHECK_EQ(locked_by_, std::thread::id())
49 <<
"Attempt to destroy locked mutex.";
57 CHECK(!holds_shared_lock())
58 <<
"Cannot hold shared and unique lock at once.";
59 CHECK_NE(locked_by_, std::this_thread::get_id())
60 <<
"This isn't a recursive mutex.";
61 #ifdef DEBUG_DEADLOCKS 62 auto scope = WaitingTracker::ThreadWaiting(
this);
69 locked_by_ = std::this_thread::get_id();
73 CHECK(!holds_shared_lock()) <<
"Cannot hold shared an unique lock at once.";
74 CHECK_NE(locked_by_, std::this_thread::get_id())
75 <<
"This isn't a recursive mutex.";
77 bool ret = mutex_.try_lock();
80 locked_by_ = std::this_thread::get_id();
86 CHECK_EQ(locked_by_, std::this_thread::get_id())
87 <<
"Attempt to unlock from wrong thread.";
88 locked_by_ = std::thread::id();
95 CHECK(!holds_shared_lock()) <<
"This isn't a recursive mutex.";
96 CHECK_NE(locked_by_, std::this_thread::get_id())
97 <<
"Cannot get shared lock with exclusive lock held.";
102 mutex_.lock_shared();
108 CHECK(!holds_shared_lock()) <<
"This isn't a recursive mutex.";
109 CHECK_NE(locked_by_, std::this_thread::get_id())
110 <<
"Cannot get shared lock with exclusive lock held.";
112 bool ret = mutex_.try_lock();
121 CHECK(holds_shared_lock()) <<
"Attempt to unlock from wrong thread.";
122 CHECK_EQ(locked_by_, std::thread::id())
123 <<
"Must call unlock() before calling unlock_shared() when upgrading.";
124 remove_shared_lock();
125 mutex_.unlock_shared();
129 bool holds_shared_lock() {
130 std::unique_lock<std::mutex>
lock(shared_locked_by_lock_);
131 return shared_locked_by_.count(std::this_thread::get_id()) > 0;
134 void add_shared_lock() {
135 std::unique_lock<std::mutex>
lock(shared_locked_by_lock_);
136 shared_locked_by_.insert(std::this_thread::get_id());
139 void remove_shared_lock() {
140 std::unique_lock<std::mutex>
lock(shared_locked_by_lock_);
141 shared_locked_by_.erase(std::this_thread::get_id());
144 std::atomic<std::thread::id> locked_by_;
145 std::atomic<bool> is_upgrading_{
false};
147 std::mutex shared_locked_by_lock_;
148 std::unordered_set<std::thread::id> shared_locked_by_;
151 #ifdef DEBUG_DEADLOCKS 155 class Mutex final :
public std::mutex {
157 explicit Mutex(
const std::string&) {}
167 #endif // SHAKA_EMBEDDED_DEBUG_MUTEX_H_
std::thread::id GetProvider() const override
SharedMutex(const std::string &)
DebugMutex(const std::string &name)
Mutex(const std::string &)