]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
11fdf7f2 | 18 | #include "include/ceph_assert.h" |
7c673cae | 19 | #include "lockdep.h" |
7c673cae | 20 | |
11fdf7f2 | 21 | #include <string> |
7c673cae | 22 | #include <pthread.h> |
11fdf7f2 | 23 | #include <mutex> |
7c673cae FG |
24 | |
25 | using namespace ceph; | |
26 | ||
7c673cae FG |
27 | class Mutex { |
28 | private: | |
29 | std::string name; | |
30 | int id; | |
31 | bool recursive; | |
32 | bool lockdep; | |
33 | bool backtrace; // gather backtrace on lock acquisition | |
34 | ||
35 | pthread_mutex_t _m; | |
36 | int nlock; | |
37 | pthread_t locked_by; | |
7c673cae FG |
38 | |
39 | // don't allow copying. | |
40 | void operator=(const Mutex &M); | |
41 | Mutex(const Mutex &M); | |
42 | ||
43 | void _register() { | |
44 | id = lockdep_register(name.c_str()); | |
45 | } | |
46 | void _will_lock() { // about to lock | |
11fdf7f2 | 47 | id = lockdep_will_lock(name.c_str(), id, backtrace, recursive); |
7c673cae FG |
48 | } |
49 | void _locked() { // just locked | |
50 | id = lockdep_locked(name.c_str(), id, backtrace); | |
51 | } | |
52 | void _will_unlock() { // about to unlock | |
53 | id = lockdep_will_unlock(name.c_str(), id); | |
54 | } | |
55 | ||
56 | public: | |
11fdf7f2 | 57 | Mutex(const std::string &n, bool r = false, bool ld=true, bool bt=false); |
7c673cae FG |
58 | ~Mutex(); |
59 | bool is_locked() const { | |
60 | return (nlock > 0); | |
61 | } | |
62 | bool is_locked_by_me() const { | |
63 | return nlock > 0 && locked_by == pthread_self(); | |
64 | } | |
65 | ||
66 | bool TryLock() { | |
11fdf7f2 TL |
67 | return try_lock(); |
68 | } | |
69 | bool try_lock() { | |
7c673cae FG |
70 | int r = pthread_mutex_trylock(&_m); |
71 | if (r == 0) { | |
72 | if (lockdep && g_lockdep) _locked(); | |
73 | _post_lock(); | |
74 | } | |
75 | return r == 0; | |
76 | } | |
77 | ||
11fdf7f2 TL |
78 | void Lock(bool no_lockdep=false) { |
79 | lock(no_lockdep); | |
80 | } | |
81 | void lock(bool no_lockdep=false); | |
7c673cae FG |
82 | |
83 | void _post_lock() { | |
84 | if (!recursive) { | |
11fdf7f2 | 85 | ceph_assert(nlock == 0); |
7c673cae FG |
86 | locked_by = pthread_self(); |
87 | }; | |
88 | nlock++; | |
89 | } | |
90 | ||
91 | void _pre_unlock() { | |
11fdf7f2 | 92 | ceph_assert(nlock > 0); |
7c673cae FG |
93 | --nlock; |
94 | if (!recursive) { | |
11fdf7f2 | 95 | ceph_assert(locked_by == pthread_self()); |
7c673cae | 96 | locked_by = 0; |
11fdf7f2 | 97 | ceph_assert(nlock == 0); |
7c673cae FG |
98 | } |
99 | } | |
11fdf7f2 TL |
100 | void Unlock() { |
101 | unlock(); | |
102 | } | |
103 | void unlock(); | |
7c673cae FG |
104 | |
105 | friend class Cond; | |
106 | ||
107 | ||
108 | public: | |
11fdf7f2 | 109 | typedef std::lock_guard<Mutex> Locker; |
7c673cae FG |
110 | }; |
111 | ||
112 | ||
113 | #endif |