]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/utilities/transactions/transaction_db_mutex_impl.cc
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
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).
8 #include "utilities/transactions/transaction_db_mutex_impl.h"
11 #include <condition_variable>
15 #include "rocksdb/utilities/transaction_db_mutex.h"
17 namespace ROCKSDB_NAMESPACE
{
19 class TransactionDBMutexImpl
: public TransactionDBMutex
{
21 TransactionDBMutexImpl() {}
22 ~TransactionDBMutexImpl() override
{}
24 Status
Lock() override
;
26 Status
TryLockFor(int64_t timeout_time
) override
;
28 void UnLock() override
{ mutex_
.unlock(); }
30 friend class TransactionDBCondVarImpl
;
36 class TransactionDBCondVarImpl
: public TransactionDBCondVar
{
38 TransactionDBCondVarImpl() {}
39 ~TransactionDBCondVarImpl() override
{}
41 Status
Wait(std::shared_ptr
<TransactionDBMutex
> mutex
) override
;
43 Status
WaitFor(std::shared_ptr
<TransactionDBMutex
> mutex
,
44 int64_t timeout_time
) override
;
46 void Notify() override
{ cv_
.notify_one(); }
48 void NotifyAll() override
{ cv_
.notify_all(); }
51 std::condition_variable cv_
;
54 std::shared_ptr
<TransactionDBMutex
>
55 TransactionDBMutexFactoryImpl::AllocateMutex() {
56 return std::shared_ptr
<TransactionDBMutex
>(new TransactionDBMutexImpl());
59 std::shared_ptr
<TransactionDBCondVar
>
60 TransactionDBMutexFactoryImpl::AllocateCondVar() {
61 return std::shared_ptr
<TransactionDBCondVar
>(new TransactionDBCondVarImpl());
64 Status
TransactionDBMutexImpl::Lock() {
69 Status
TransactionDBMutexImpl::TryLockFor(int64_t timeout_time
) {
72 if (timeout_time
== 0) {
73 locked
= mutex_
.try_lock();
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
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.
86 // timeout acquiring mutex
87 return Status::TimedOut(Status::SubCode::kMutexTimeout
);
93 Status
TransactionDBCondVarImpl::Wait(
94 std::shared_ptr
<TransactionDBMutex
> mutex
) {
95 auto mutex_impl
= reinterpret_cast<TransactionDBMutexImpl
*>(mutex
.get());
97 std::unique_lock
<std::mutex
> lock(mutex_impl
->mutex_
, std::adopt_lock
);
100 // Make sure unique_lock doesn't unlock mutex when it destructs
106 Status
TransactionDBCondVarImpl::WaitFor(
107 std::shared_ptr
<TransactionDBMutex
> mutex
, int64_t timeout_time
) {
110 auto mutex_impl
= reinterpret_cast<TransactionDBMutexImpl
*>(mutex
.get());
111 std::unique_lock
<std::mutex
> lock(mutex_impl
->mutex_
, std::adopt_lock
);
113 if (timeout_time
< 0) {
114 // If timeout is negative, do not use a timeout
117 auto duration
= std::chrono::microseconds(timeout_time
);
118 auto cv_status
= cv_
.wait_for(lock
, duration
);
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
);
126 // Make sure unique_lock doesn't unlock mutex when it destructs
129 // CV was signaled, or we spuriously woke up (but didn't time out)
133 } // namespace ROCKSDB_NAMESPACE
135 #endif // ROCKSDB_LITE