namespace ceph {
namespace mutex_debug_detail {
-class mutex_debugging_base {
+
+class mutex_debugging_base
+{
protected:
std::string name;
int id;
}
};
-template<typename Mutex>
-class mutex_debugging : public mutex_debugging_base {
- Mutex* impl;
-
-public:
- mutex_debugging(const std::string &n = std::string(), bool bt = false) :
- mutex_debugging_base(n, bt), impl(static_cast<Mutex*>(this)) {}
-
- ~mutex_debugging() = default;
-
- void _post_lock() {
- if (!impl->recursive)
- ceph_assert(nlock == 0);
- locked_by = std::this_thread::get_id();
- nlock++;
- }
-
- void _pre_unlock() {
- ceph_assert(nlock > 0);
- --nlock;
- ceph_assert(locked_by == std::this_thread::get_id());
- if (!impl->recursive)
- ceph_assert(nlock == 0);
- if (nlock == 0)
- locked_by = std::thread::id();
- }
-
- bool try_lock(bool no_lockdep = false) {
- bool locked = impl->try_lock_impl();
- if (locked) {
- if (g_lockdep && !no_lockdep)
- _locked();
- _post_lock();
- }
- return locked;
- }
-
- void lock(bool no_lockdep = false) {
- if (g_lockdep && !no_lockdep)
- _will_lock();
-
- if (try_lock())
- return;
-
- auto t = before_lock_blocks();
- impl->lock_impl();
- after_lock_blocks(t, no_lockdep);
- _post_lock();
- }
-
- void unlock(bool no_lockdep = false) {
- _pre_unlock();
- if (!no_lockdep && g_lockdep)
- _will_unlock();
- impl->unlock_impl();
- }
-};
-
// Since this is a /debugging/ mutex just define it in terms of the
// pthread error check mutex.
template<bool Recursive>
-class mutex_debug_impl : public mutex_debugging<mutex_debug_impl<Recursive> > {
+class mutex_debug_impl : public mutex_debugging_base
+{
private:
pthread_mutex_t m;
public:
static constexpr bool recursive = Recursive;
// Mutex concept is DefaultConstructible
- mutex_debug_impl(const std::string &n = std::string(), bool bt = false) :
- mutex_debugging<mutex_debug_impl<Recursive> >(n, bt) {
+ mutex_debug_impl(const std::string &n = std::string(), bool bt = false)
+ : mutex_debugging_base(n, bt) {
pthread_mutexattr_t a;
pthread_mutexattr_init(&a);
int r;
pthread_mutex_t* native_handle() {
return &m;
}
+
+ void _post_lock() {
+ if (!recursive)
+ ceph_assert(nlock == 0);
+ locked_by = std::this_thread::get_id();
+ nlock++;
+ }
+
+ void _pre_unlock() {
+ ceph_assert(nlock > 0);
+ --nlock;
+ ceph_assert(locked_by == std::this_thread::get_id());
+ if (!recursive)
+ ceph_assert(nlock == 0);
+ if (nlock == 0)
+ locked_by = std::thread::id();
+ }
+
+ bool try_lock(bool no_lockdep = false) {
+ bool locked = try_lock_impl();
+ if (locked) {
+ if (g_lockdep && !no_lockdep)
+ _locked();
+ _post_lock();
+ }
+ return locked;
+ }
+
+ void lock(bool no_lockdep = false) {
+ if (g_lockdep && !no_lockdep)
+ _will_lock();
+
+ if (try_lock())
+ return;
+
+ auto t = before_lock_blocks();
+ lock_impl();
+ after_lock_blocks(t, no_lockdep);
+ _post_lock();
+ }
+
+ void unlock(bool no_lockdep = false) {
+ _pre_unlock();
+ if (!no_lockdep && g_lockdep)
+ _will_unlock();
+ unlock_impl();
+ }
+
};
+
+
} // namespace mutex_debug_detail
typedef mutex_debug_detail::mutex_debug_impl<false> mutex_debug;
typedef mutex_debug_detail::mutex_debug_impl<true> mutex_recursive_debug;