1 | /* |
2 | Copyright (c) 2015, Facebook, Inc. |
3 | |
4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by |
6 | the Free Software Foundation; version 2 of the License. |
7 | |
8 | This program is distributed in the hope that it will be useful, |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | GNU General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU General Public License |
14 | along with this program; if not, write to the Free Software |
15 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
16 | |
17 | #pragma once |
18 | |
19 | /* C++ standard header file */ |
20 | #include <chrono> |
21 | #include <condition_variable> |
22 | #include <functional> |
23 | #include <mutex> |
24 | #include <unordered_map> |
25 | |
26 | /* MySQL header files */ |
27 | #include "./my_sys.h" |
28 | #include "mysql/plugin.h" |
29 | |
30 | /* RocksDB header files */ |
31 | #include "rocksdb/utilities/transaction_db_mutex.h" |
32 | #include "rdb_mariadb_port.h" |
33 | |
34 | namespace myrocks { |
35 | |
36 | class Rdb_mutex : public rocksdb::TransactionDBMutex { |
37 | Rdb_mutex(const Rdb_mutex &p) = delete; |
38 | Rdb_mutex &operator=(const Rdb_mutex &p) = delete; |
39 | |
40 | public: |
41 | Rdb_mutex(); |
42 | virtual ~Rdb_mutex(); |
43 | |
44 | /* |
45 | Override parent class's virtual methods of interrest. |
46 | */ |
47 | |
48 | // Attempt to acquire lock. Return OK on success, or other Status on failure. |
49 | // If returned status is OK, TransactionDB will eventually call UnLock(). |
50 | virtual rocksdb::Status Lock() override; |
51 | |
52 | // Attempt to acquire lock. If timeout is non-negative, operation should be |
53 | // failed after this many microseconds. |
54 | // Returns OK on success, |
55 | // TimedOut if timed out, |
56 | // or other Status on failure. |
57 | // If returned status is OK, TransactionDB will eventually call UnLock(). |
58 | virtual rocksdb::Status |
59 | TryLockFor(int64_t timeout_time MY_ATTRIBUTE((__unused__))) override; |
60 | |
61 | // Unlock Mutex that was successfully locked by Lock() or TryLockUntil() |
62 | virtual void UnLock() override; |
63 | |
64 | private: |
65 | mysql_mutex_t m_mutex; |
66 | friend class Rdb_cond_var; |
67 | |
68 | #ifndef STANDALONE_UNITTEST |
69 | void set_unlock_action(const PSI_stage_info *const old_stage_arg); |
70 | std::unordered_map<THD *, std::shared_ptr<PSI_stage_info>> m_old_stage_info; |
71 | #endif |
72 | }; |
73 | |
74 | class Rdb_cond_var : public rocksdb::TransactionDBCondVar { |
75 | Rdb_cond_var(const Rdb_cond_var &) = delete; |
76 | Rdb_cond_var &operator=(const Rdb_cond_var &) = delete; |
77 | |
78 | public: |
79 | Rdb_cond_var(); |
80 | virtual ~Rdb_cond_var(); |
81 | |
82 | /* |
83 | Override parent class's virtual methods of interrest. |
84 | */ |
85 | |
86 | // Block current thread until condition variable is notified by a call to |
87 | // Notify() or NotifyAll(). Wait() will be called with mutex locked. |
88 | // Returns OK if notified. |
89 | // Returns non-OK if TransactionDB should stop waiting and fail the operation. |
90 | // May return OK spuriously even if not notified. |
91 | virtual rocksdb::Status |
92 | Wait(const std::shared_ptr<rocksdb::TransactionDBMutex> mutex) override; |
93 | |
94 | // Block current thread until condition variable is notifiesd by a call to |
95 | // Notify() or NotifyAll(), or if the timeout is reached. |
96 | // If timeout is non-negative, operation should be failed after this many |
97 | // microseconds. |
98 | // If implementing a custom version of this class, the implementation may |
99 | // choose to ignore the timeout. |
100 | // |
101 | // Returns OK if notified. |
102 | // Returns TimedOut if timeout is reached. |
103 | // Returns other status if TransactionDB should otherwis stop waiting and |
104 | // fail the operation. |
105 | // May return OK spuriously even if not notified. |
106 | virtual rocksdb::Status |
107 | WaitFor(const std::shared_ptr<rocksdb::TransactionDBMutex> mutex, |
108 | int64_t timeout_time) override; |
109 | |
110 | // If any threads are waiting on *this, unblock at least one of the |
111 | // waiting threads. |
112 | virtual void Notify() override; |
113 | |
114 | // Unblocks all threads waiting on *this. |
115 | virtual void NotifyAll() override; |
116 | |
117 | private: |
118 | mysql_cond_t m_cond; |
119 | }; |
120 | |
121 | class Rdb_mutex_factory : public rocksdb::TransactionDBMutexFactory { |
122 | public: |
123 | Rdb_mutex_factory(const Rdb_mutex_factory &) = delete; |
124 | Rdb_mutex_factory &operator=(const Rdb_mutex_factory &) = delete; |
125 | Rdb_mutex_factory() {} |
126 | /* |
127 | Override parent class's virtual methods of interrest. |
128 | */ |
129 | |
130 | virtual std::shared_ptr<rocksdb::TransactionDBMutex> |
131 | AllocateMutex() override { |
132 | return std::make_shared<Rdb_mutex>(); |
133 | } |
134 | |
135 | virtual std::shared_ptr<rocksdb::TransactionDBCondVar> |
136 | AllocateCondVar() override { |
137 | return std::make_shared<Rdb_cond_var>(); |
138 | } |
139 | |
140 | virtual ~Rdb_mutex_factory() {} |
141 | }; |
142 | |
143 | } // namespace myrocks |
144 | |