]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/fair_mutex.h
update ceph source to reef 18.2.0
[ceph.git] / ceph / src / common / fair_mutex.h
CommitLineData
a4b75251
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*-
2
3#pragma once
4
5#include "common/ceph_mutex.h"
6
7#include <thread>
8#include <string>
9
10namespace ceph {
11/// a FIFO mutex
12class fair_mutex {
13public:
14 fair_mutex(const std::string& name)
15 : mutex{ceph::make_mutex(name)}
16 {}
17 ~fair_mutex() = default;
18 fair_mutex(const fair_mutex&) = delete;
19 fair_mutex& operator=(const fair_mutex&) = delete;
20
21 void lock()
22 {
23 std::unique_lock lock(mutex);
24 const unsigned my_id = next_id++;
25 cond.wait(lock, [&] {
26 return my_id == unblock_id;
27 });
28 _set_locked_by();
29 }
30
31 bool try_lock()
32 {
33 std::lock_guard lock(mutex);
34 if (is_locked()) {
35 return false;
36 }
37 ++next_id;
38 _set_locked_by();
39 return true;
40 }
41
42 void unlock()
43 {
44 std::lock_guard lock(mutex);
45 ++unblock_id;
46 _reset_locked_by();
47 cond.notify_all();
48 }
49
50 bool is_locked() const
51 {
52 return next_id != unblock_id;
53 }
54
55#ifdef CEPH_DEBUG_MUTEX
56 bool is_locked_by_me() const {
57 return is_locked() && locked_by == std::this_thread::get_id();
58 }
59private:
60 void _set_locked_by() {
61 locked_by = std::this_thread::get_id();
62 }
63 void _reset_locked_by() {
64 locked_by = {};
65 }
66#else
67 void _set_locked_by() {}
68 void _reset_locked_by() {}
69#endif
70
71private:
72 unsigned next_id = 0;
73 unsigned unblock_id = 0;
74 ceph::condition_variable cond;
75 ceph::mutex mutex;
76#ifdef CEPH_DEBUG_MUTEX
77 std::thread::id locked_by = {};
78#endif
79};
80} // namespace ceph