1 /* 2 Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. 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, version 2.0, 6 as published by the Free Software Foundation. 7 8 This program is also distributed with certain software (including 9 but not limited to OpenSSL) that is licensed under separate terms, 10 as designated in a particular file or component or in included license 11 documentation. The authors of MySQL hereby grant you an additional 12 permission to link the program and your derivative works with the 13 separately licensed software that they have included with MySQL. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License, version 2.0, for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; if not, write to the Free Software 22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23 */ 24 25 #ifndef NDB_MUTEX_H 26 #define NDB_MUTEX_H 27 28 #include <ndb_global.h> 29 #include <thr_mutex.h> 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #if !defined NDB_MUTEX_STAT && !defined NDB_MUTEX_DEADLOCK_DETECTOR 36 typedef native_mutex_t NdbMutex; 37 #else 38 typedef struct { 39 native_mutex_t mutex; 40 #ifdef NDB_MUTEX_STAT 41 unsigned cnt_lock; 42 unsigned cnt_lock_contention; 43 unsigned cnt_trylock_ok; 44 unsigned cnt_trylock_nok; 45 unsigned long long min_lock_wait_time_ns; 46 unsigned long long sum_lock_wait_time_ns; 47 unsigned long long max_lock_wait_time_ns; 48 unsigned long long min_hold_time_ns; 49 unsigned long long sum_hold_time_ns; 50 unsigned long long max_hold_time_ns; 51 unsigned long long lock_start_time_ns; 52 char name[32]; 53 #endif 54 #ifdef NDB_MUTEX_DEADLOCK_DETECTOR 55 struct ndb_mutex_state * m_mutex_state; 56 #endif 57 } NdbMutex; 58 #endif 59 60 /** 61 * Create a mutex 62 * - the allocated mutex should be released by calling 63 * NdbMutex_Destroy 64 * 65 * returnvalue: pointer to the mutex structure 66 */ 67 NdbMutex* NdbMutex_Create(void); 68 NdbMutex* NdbMutex_CreateWithName(const char * name); 69 70 /** 71 * Initialize a mutex created with file-storage or on the stack 72 * 73 * * p_mutex: pointer to the mutex structure 74 * * returnvalue: 0 = succeeded, -1 = failed 75 */ 76 int NdbMutex_Init(NdbMutex* p_mutex); 77 int NdbMutex_InitWithName(NdbMutex* p_mutex, const char * name); 78 79 /** 80 * Destroy a mutex 81 * 82 * * p_mutex: pointer to the mutex structure 83 * * returnvalue: 0 = succeeded, -1 = failed 84 */ 85 int NdbMutex_Destroy(NdbMutex* p_mutex); 86 int NdbMutex_Deinit(NdbMutex* p_mutex); 87 88 /** 89 * Lock a mutex 90 * 91 * * p_mutex: pointer to the mutex structure 92 * * returnvalue: 0 = succeeded, -1 = failed 93 */ 94 int NdbMutex_Lock(NdbMutex* p_mutex); 95 96 /** 97 * Unlock a mutex 98 * 99 * * p_mutex: pointer to the mutex structure 100 * * returnvalue: 0 = succeeded, -1 = failed 101 */ 102 int NdbMutex_Unlock(NdbMutex* p_mutex); 103 104 /** 105 * Try to lock a mutex 106 * 107 * * p_mutex: pointer to the mutex structure 108 * * returnvalue: 0 = succeeded, -1 = failed 109 */ 110 int NdbMutex_Trylock(NdbMutex* p_mutex); 111 112 #ifdef __cplusplus 113 } 114 #endif 115 116 #ifdef __cplusplus 117 class NdbLockable { 118 friend class Guard; 119 friend class Guard2; 120 public: NdbLockable()121 NdbLockable() { m_mutex = NdbMutex_Create(); } ~NdbLockable()122 ~NdbLockable() { NdbMutex_Destroy(m_mutex); } 123 lock()124 void lock() { NdbMutex_Lock(m_mutex); } unlock()125 void unlock(){ NdbMutex_Unlock(m_mutex);} tryLock()126 bool tryLock(){ return NdbMutex_Trylock(m_mutex) == 0;} 127 getMutex()128 NdbMutex* getMutex() {return m_mutex;}; 129 130 protected: 131 NdbMutex * m_mutex; 132 }; 133 134 class Guard { 135 public: Guard(NdbMutex * mtx)136 Guard(NdbMutex *mtx) : m_mtx(mtx) { NdbMutex_Lock(m_mtx); }; Guard(NdbLockable & l)137 Guard(NdbLockable & l) : m_mtx(l.m_mutex) { NdbMutex_Lock(m_mtx); }; ~Guard()138 ~Guard() { NdbMutex_Unlock(m_mtx); }; 139 private: 140 NdbMutex *m_mtx; 141 }; 142 143 class Guard2 144 { 145 public: Guard2(NdbMutex * mtx)146 Guard2(NdbMutex *mtx) : m_mtx(mtx) { if (m_mtx) NdbMutex_Lock(m_mtx);}; Guard2(NdbLockable & l)147 Guard2(NdbLockable & l) : m_mtx(l.m_mutex) { if(m_mtx)NdbMutex_Lock(m_mtx);}; ~Guard2()148 ~Guard2() { if (m_mtx) NdbMutex_Unlock(m_mtx); }; 149 private: 150 NdbMutex *m_mtx; 151 }; 152 153 #endif 154 155 #endif 156