]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/utilities/transactions/transaction_db_mutex_impl.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / rocksdb / utilities / transactions / transaction_db_mutex_impl.cc
CommitLineData
7c673cae 1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
11fdf7f2
TL
2// This source code is licensed under both the GPLv2 (found in the
3// COPYING file in the root directory) and Apache 2.0 License
4// (found in the LICENSE.Apache file in the root directory).
7c673cae
FG
5
6#ifndef ROCKSDB_LITE
7
8#include "utilities/transactions/transaction_db_mutex_impl.h"
9
10#include <chrono>
11#include <condition_variable>
12#include <functional>
13#include <mutex>
14
15#include "rocksdb/utilities/transaction_db_mutex.h"
16
17namespace rocksdb {
18
19class TransactionDBMutexImpl : public TransactionDBMutex {
20 public:
21 TransactionDBMutexImpl() {}
22 ~TransactionDBMutexImpl() {}
23
24 Status Lock() override;
25
26 Status TryLockFor(int64_t timeout_time) override;
27
28 void UnLock() override { mutex_.unlock(); }
29
30 friend class TransactionDBCondVarImpl;
31
32 private:
33 std::mutex mutex_;
34};
35
36class TransactionDBCondVarImpl : public TransactionDBCondVar {
37 public:
38 TransactionDBCondVarImpl() {}
39 ~TransactionDBCondVarImpl() {}
40
41 Status Wait(std::shared_ptr<TransactionDBMutex> mutex) override;
42
43 Status WaitFor(std::shared_ptr<TransactionDBMutex> mutex,
44 int64_t timeout_time) override;
45
46 void Notify() override { cv_.notify_one(); }
47
48 void NotifyAll() override { cv_.notify_all(); }
49
50 private:
51 std::condition_variable cv_;
52};
53
54std::shared_ptr<TransactionDBMutex>
55TransactionDBMutexFactoryImpl::AllocateMutex() {
56 return std::shared_ptr<TransactionDBMutex>(new TransactionDBMutexImpl());
57}
58
59std::shared_ptr<TransactionDBCondVar>
60TransactionDBMutexFactoryImpl::AllocateCondVar() {
61 return std::shared_ptr<TransactionDBCondVar>(new TransactionDBCondVarImpl());
62}
63
64Status TransactionDBMutexImpl::Lock() {
65 mutex_.lock();
66 return Status::OK();
67}
68
69Status TransactionDBMutexImpl::TryLockFor(int64_t timeout_time) {
70 bool locked = true;
71
72 if (timeout_time == 0) {
73 locked = mutex_.try_lock();
74 } else {
75 // Previously, this code used a std::timed_mutex. However, this was changed
76 // due to known bugs in gcc versions < 4.9.
77 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54562
78 //
79 // Since this mutex isn't held for long and only a single mutex is ever
80 // held at a time, it is reasonable to ignore the lock timeout_time here
81 // and only check it when waiting on the condition_variable.
82 mutex_.lock();
83 }
84
85 if (!locked) {
86 // timeout acquiring mutex
87 return Status::TimedOut(Status::SubCode::kMutexTimeout);
88 }
89
90 return Status::OK();
91}
92
93Status TransactionDBCondVarImpl::Wait(
94 std::shared_ptr<TransactionDBMutex> mutex) {
95 auto mutex_impl = reinterpret_cast<TransactionDBMutexImpl*>(mutex.get());
96
97 std::unique_lock<std::mutex> lock(mutex_impl->mutex_, std::adopt_lock);
98 cv_.wait(lock);
99
100 // Make sure unique_lock doesn't unlock mutex when it destructs
101 lock.release();
102
103 return Status::OK();
104}
105
106Status TransactionDBCondVarImpl::WaitFor(
107 std::shared_ptr<TransactionDBMutex> mutex, int64_t timeout_time) {
108 Status s;
109
110 auto mutex_impl = reinterpret_cast<TransactionDBMutexImpl*>(mutex.get());
111 std::unique_lock<std::mutex> lock(mutex_impl->mutex_, std::adopt_lock);
112
113 if (timeout_time < 0) {
114 // If timeout is negative, do not use a timeout
115 cv_.wait(lock);
116 } else {
117 auto duration = std::chrono::microseconds(timeout_time);
118 auto cv_status = cv_.wait_for(lock, duration);
119
120 // Check if the wait stopped due to timing out.
121 if (cv_status == std::cv_status::timeout) {
122 s = Status::TimedOut(Status::SubCode::kMutexTimeout);
123 }
124 }
125
126 // Make sure unique_lock doesn't unlock mutex when it destructs
127 lock.release();
128
129 // CV was signaled, or we spuriously woke up (but didn't time out)
130 return s;
131}
132
133} // namespace rocksdb
134
135#endif // ROCKSDB_LITE