summaryrefslogtreecommitdiffstats
path: root/src/common/Mutex.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/Mutex.h')
-rw-r--r--src/common/Mutex.h113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/common/Mutex.h b/src/common/Mutex.h
new file mode 100644
index 00000000..792ba323
--- /dev/null
+++ b/src/common/Mutex.h
@@ -0,0 +1,113 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_MUTEX_H
+#define CEPH_MUTEX_H
+
+#include "include/ceph_assert.h"
+#include "lockdep.h"
+
+#include <string>
+#include <pthread.h>
+#include <mutex>
+
+using namespace ceph;
+
+class Mutex {
+private:
+ std::string name;
+ int id;
+ bool recursive;
+ bool lockdep;
+ bool backtrace; // gather backtrace on lock acquisition
+
+ pthread_mutex_t _m;
+ int nlock;
+ pthread_t locked_by;
+
+ // don't allow copying.
+ void operator=(const Mutex &M);
+ Mutex(const Mutex &M);
+
+ void _register() {
+ id = lockdep_register(name.c_str());
+ }
+ void _will_lock() { // about to lock
+ id = lockdep_will_lock(name.c_str(), id, backtrace, recursive);
+ }
+ void _locked() { // just locked
+ id = lockdep_locked(name.c_str(), id, backtrace);
+ }
+ void _will_unlock() { // about to unlock
+ id = lockdep_will_unlock(name.c_str(), id);
+ }
+
+public:
+ Mutex(const std::string &n, bool r = false, bool ld=true, bool bt=false);
+ ~Mutex();
+ bool is_locked() const {
+ return (nlock > 0);
+ }
+ bool is_locked_by_me() const {
+ return nlock > 0 && locked_by == pthread_self();
+ }
+
+ bool TryLock() {
+ return try_lock();
+ }
+ bool try_lock() {
+ int r = pthread_mutex_trylock(&_m);
+ if (r == 0) {
+ if (lockdep && g_lockdep) _locked();
+ _post_lock();
+ }
+ return r == 0;
+ }
+
+ void Lock(bool no_lockdep=false) {
+ lock(no_lockdep);
+ }
+ void lock(bool no_lockdep=false);
+
+ void _post_lock() {
+ if (!recursive) {
+ ceph_assert(nlock == 0);
+ locked_by = pthread_self();
+ };
+ nlock++;
+ }
+
+ void _pre_unlock() {
+ ceph_assert(nlock > 0);
+ --nlock;
+ if (!recursive) {
+ ceph_assert(locked_by == pthread_self());
+ locked_by = 0;
+ ceph_assert(nlock == 0);
+ }
+ }
+ void Unlock() {
+ unlock();
+ }
+ void unlock();
+
+ friend class Cond;
+
+
+public:
+ typedef std::lock_guard<Mutex> Locker;
+};
+
+
+#endif