Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / common / Mutex.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
2 // vim: ts=8 sw=2 smarttab
3 /*
4  * Ceph - scalable distributed file system
5  *
6  * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
7  *
8  * This is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License version 2.1, as published by the Free Software 
11  * Foundation.  See file COPYING.
12  * 
13  */
14
15 #ifndef CEPH_MUTEX_H
16 #define CEPH_MUTEX_H
17
18 #include "include/assert.h"
19 #include "lockdep.h"
20 #include "common/ceph_context.h"
21
22 #include <pthread.h>
23
24 using namespace ceph;
25
26 class PerfCounters;
27
28 enum {
29   l_mutex_first = 999082,
30   l_mutex_wait,
31   l_mutex_last
32 };
33
34 class Mutex {
35 private:
36   std::string name;
37   int id;
38   bool recursive;
39   bool lockdep;
40   bool backtrace;  // gather backtrace on lock acquisition
41
42   pthread_mutex_t _m;
43   int nlock;
44   pthread_t locked_by;
45   CephContext *cct;
46   PerfCounters *logger;
47
48   // don't allow copying.
49   void operator=(const Mutex &M);
50   Mutex(const Mutex &M);
51
52   void _register() {
53     id = lockdep_register(name.c_str());
54   }
55   void _will_lock() { // about to lock
56     id = lockdep_will_lock(name.c_str(), id, backtrace);
57   }
58   void _locked() {    // just locked
59     id = lockdep_locked(name.c_str(), id, backtrace);
60   }
61   void _will_unlock() {  // about to unlock
62     id = lockdep_will_unlock(name.c_str(), id);
63   }
64
65 public:
66   Mutex(const std::string &n, bool r = false, bool ld=true, bool bt=false,
67         CephContext *cct = 0);
68   ~Mutex();
69   bool is_locked() const {
70     return (nlock > 0);
71   }
72   bool is_locked_by_me() const {
73     return nlock > 0 && locked_by == pthread_self();
74   }
75
76   bool TryLock() {
77     int r = pthread_mutex_trylock(&_m);
78     if (r == 0) {
79       if (lockdep && g_lockdep) _locked();
80       _post_lock();
81     }
82     return r == 0;
83   }
84
85   void Lock(bool no_lockdep=false);
86
87   void _post_lock() {
88     if (!recursive) {
89       assert(nlock == 0);
90       locked_by = pthread_self();
91     };
92     nlock++;
93   }
94
95   void _pre_unlock() {
96     assert(nlock > 0);
97     --nlock;
98     if (!recursive) {
99       assert(locked_by == pthread_self());
100       locked_by = 0;
101       assert(nlock == 0);
102     }
103   }
104   void Unlock();
105
106   friend class Cond;
107
108
109 public:
110   class Locker {
111     Mutex &mutex;
112
113   public:
114     explicit Locker(Mutex& m) : mutex(m) {
115       mutex.Lock();
116     }
117     ~Locker() {
118       mutex.Unlock();
119     }
120   };
121 };
122
123
124 #endif