diff --git a/storage/rocksdb/rdb_mutex_wrapper.h b/storage/rocksdb/rdb_mutex_wrapper.h index c38910958639b1ad006265f19f8f2d9f1b097c27..009b8002f7457c2b20359e4d179bd76f3318da8e 100644 --- a/storage/rocksdb/rdb_mutex_wrapper.h +++ b/storage/rocksdb/rdb_mutex_wrapper.h @@ -59,4 +59,117 @@ class Rdb_mutex : public rocksdb::TransactionDBMutex { // or other Status on failure. // If returned status is OK, TransactionDB will eventually call UnLock(). virtual rocksdb::Status TryLockFor( - int64_t timeout_time MY_ATTRIBUTE((__unused__))) override; \ No newline at end of file + int64_t timeout_time MY_ATTRIBUTE((__unused__))) override; + + // Unlock Mutex that was successfully locked by Lock() or TryLockUntil() + virtual void UnLock() override; + + private: + mysql_mutex_t m_mutex; + friend class Rdb_cond_var; + +#ifndef STANDALONE_UNITTEST + void set_unlock_action(const PSI_stage_info *const old_stage_arg); + std::unordered_map> m_old_stage_info; +#endif +}; + +class Rdb_cond_var : public rocksdb::TransactionDBCondVar { + Rdb_cond_var(const Rdb_cond_var &) = delete; + Rdb_cond_var &operator=(const Rdb_cond_var &) = delete; + + public: +#ifdef HAVE_PSI_INTERFACE + explicit Rdb_cond_var(PSI_memory_key psi_key); +#else + Rdb_cond_var(); +#endif + virtual ~Rdb_cond_var() override; + + /* + Override parent class's virtual methods of interrest. + */ + + // Block current thread until condition variable is notified by a call to + // Notify() or NotifyAll(). Wait() will be called with mutex locked. + // Returns OK if notified. + // Returns non-OK if TransactionDB should stop waiting and fail the operation. + // May return OK spuriously even if not notified. + virtual rocksdb::Status Wait( + const std::shared_ptr mutex) override; + + // Block current thread until condition variable is notifiesd by a call to + // Notify() or NotifyAll(), or if the timeout is reached. + // If timeout is non-negative, operation should be failed after this many + // microseconds. + // If implementing a custom version of this class, the implementation may + // choose to ignore the timeout. + // + // Returns OK if notified. + // Returns TimedOut if timeout is reached. + // Returns other status if TransactionDB should otherwis stop waiting and + // fail the operation. + // May return OK spuriously even if not notified. + virtual rocksdb::Status WaitFor( + const std::shared_ptr mutex, + int64_t timeout_time) override; + + // If any threads are waiting on *this, unblock at least one of the + // waiting threads. + virtual void Notify() override; + + // Unblocks all threads waiting on *this. + virtual void NotifyAll() override; + + private: + mysql_cond_t m_cond; +}; + +class Rdb_mutex_factory : public rocksdb::TransactionDBMutexFactory { + public: + Rdb_mutex_factory(const Rdb_mutex_factory &) = delete; + Rdb_mutex_factory &operator=(const Rdb_mutex_factory &) = delete; + Rdb_mutex_factory() {} + /* + Override parent class's virtual methods of interrest. + */ + + virtual std::shared_ptr AllocateMutex() + override { + return std::make_shared(); + } + + virtual std::shared_ptr AllocateCondVar() + override { + return std::make_shared(PSI_NOT_INSTRUMENTED); + } + +#ifdef HAVE_PSI_INTERFACE + virtual std::shared_ptr AllocateCondVar( + PSI_memory_key psi_key) { + return std::make_shared(psi_key); + } +#endif + + virtual ~Rdb_mutex_factory() override {} +}; + +/// A wrapper around sql mutex that tracks initialization state. +struct Rds_mysql_mutex : public mysql_mutex_t { + bool m_initialized = false; + + void init(my_core::PSI_mutex_key &key, native_mutexattr_t *attr) { + mysql_mutex_init(key, this, attr); + m_initialized = true; + } + + void destroy() { + if (!m_initialized) { + return; + } + mysql_mutex_destroy(this); + m_initialized = false; + } +}; + +} // namespace myrocks