Clone of PhatAC @ https://github.com/floaterxk/PhatAC

thr_mutex.h 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #ifndef THR_MUTEX_INCLUDED
  2. #define THR_MUTEX_INCLUDED
  3. /* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  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. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
  14. /**
  15. MySQL mutex implementation.
  16. There are three "layers":
  17. 1) native_mutex_*()
  18. Functions that map directly down to OS primitives.
  19. Windows - CriticalSection
  20. Other OSes - pthread
  21. 2) my_mutex_*()
  22. Functions that implement SAFE_MUTEX (default for debug),
  23. Otherwise native_mutex_*() is used.
  24. 3) mysql_mutex_*()
  25. Functions that include Performance Schema instrumentation.
  26. See include/mysql/psi/mysql_thread.h
  27. */
  28. #include <my_global.h>
  29. #include "my_thread.h"
  30. C_MODE_START
  31. #ifdef _WIN32
  32. typedef CRITICAL_SECTION native_mutex_t;
  33. typedef int native_mutexattr_t;
  34. #else
  35. typedef pthread_mutex_t native_mutex_t;
  36. typedef pthread_mutexattr_t native_mutexattr_t;
  37. #endif
  38. /* Define mutex types, see my_thr_init.c */
  39. #define MY_MUTEX_INIT_SLOW NULL
  40. /* Can be set in /usr/include/pthread.h */
  41. #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
  42. extern native_mutexattr_t my_fast_mutexattr;
  43. #define MY_MUTEX_INIT_FAST &my_fast_mutexattr
  44. #else
  45. #define MY_MUTEX_INIT_FAST NULL
  46. #endif
  47. /* Can be set in /usr/include/pthread.h */
  48. #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
  49. extern native_mutexattr_t my_errorcheck_mutexattr;
  50. #define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr
  51. #else
  52. #define MY_MUTEX_INIT_ERRCHK NULL
  53. #endif
  54. static inline int native_mutex_init(native_mutex_t *mutex,
  55. const native_mutexattr_t *attr)
  56. {
  57. #ifdef _WIN32
  58. InitializeCriticalSection(mutex);
  59. return 0;
  60. #else
  61. return pthread_mutex_init(mutex, attr);
  62. #endif
  63. }
  64. static inline int native_mutex_lock(native_mutex_t *mutex)
  65. {
  66. #ifdef _WIN32
  67. EnterCriticalSection(mutex);
  68. return 0;
  69. #else
  70. return pthread_mutex_lock(mutex);
  71. #endif
  72. }
  73. static inline int native_mutex_trylock(native_mutex_t *mutex)
  74. {
  75. #ifdef _WIN32
  76. if (TryEnterCriticalSection(mutex))
  77. {
  78. /* Don't allow recursive lock */
  79. if (mutex->RecursionCount > 1){
  80. LeaveCriticalSection(mutex);
  81. return EBUSY;
  82. }
  83. return 0;
  84. }
  85. return EBUSY;
  86. #else
  87. return pthread_mutex_trylock(mutex);
  88. #endif
  89. }
  90. static inline int native_mutex_unlock(native_mutex_t *mutex)
  91. {
  92. #ifdef _WIN32
  93. LeaveCriticalSection(mutex);
  94. return 0;
  95. #else
  96. return pthread_mutex_unlock(mutex);
  97. #endif
  98. }
  99. static inline int native_mutex_destroy(native_mutex_t *mutex)
  100. {
  101. #ifdef _WIN32
  102. DeleteCriticalSection(mutex);
  103. return 0;
  104. #else
  105. return pthread_mutex_destroy(mutex);
  106. #endif
  107. }
  108. #ifdef SAFE_MUTEX
  109. /* safe_mutex adds checking to mutex for easier debugging */
  110. typedef struct st_safe_mutex_t
  111. {
  112. native_mutex_t global, mutex;
  113. const char *file;
  114. uint line, count;
  115. my_thread_t thread;
  116. } my_mutex_t;
  117. void safe_mutex_global_init();
  118. int safe_mutex_init(my_mutex_t *mp, const native_mutexattr_t *attr,
  119. const char *file, uint line);
  120. int safe_mutex_lock(my_mutex_t *mp, my_bool try_lock, const char *file, uint line);
  121. int safe_mutex_unlock(my_mutex_t *mp, const char *file, uint line);
  122. int safe_mutex_destroy(my_mutex_t *mp, const char *file, uint line);
  123. static inline void safe_mutex_assert_owner(const my_mutex_t *mp)
  124. {
  125. DBUG_ASSERT(mp->count > 0 &&
  126. my_thread_equal(my_thread_self(), mp->thread));
  127. }
  128. static inline void safe_mutex_assert_not_owner(const my_mutex_t *mp)
  129. {
  130. DBUG_ASSERT(!mp->count ||
  131. !my_thread_equal(my_thread_self(), mp->thread));
  132. }
  133. #else
  134. typedef native_mutex_t my_mutex_t;
  135. #endif
  136. static inline int my_mutex_init(my_mutex_t *mp, const native_mutexattr_t *attr
  137. #ifdef SAFE_MUTEX
  138. , const char *file, uint line
  139. #endif
  140. )
  141. {
  142. #ifdef SAFE_MUTEX
  143. return safe_mutex_init(mp, attr, file, line);
  144. #else
  145. return native_mutex_init(mp, attr);
  146. #endif
  147. }
  148. static inline int my_mutex_lock(my_mutex_t *mp
  149. #ifdef SAFE_MUTEX
  150. , const char *file, uint line
  151. #endif
  152. )
  153. {
  154. #ifdef SAFE_MUTEX
  155. return safe_mutex_lock(mp, FALSE, file, line);
  156. #else
  157. return native_mutex_lock(mp);
  158. #endif
  159. }
  160. static inline int my_mutex_trylock(my_mutex_t *mp
  161. #ifdef SAFE_MUTEX
  162. , const char *file, uint line
  163. #endif
  164. )
  165. {
  166. #ifdef SAFE_MUTEX
  167. return safe_mutex_lock(mp, TRUE, file, line);
  168. #else
  169. return native_mutex_trylock(mp);
  170. #endif
  171. }
  172. static inline int my_mutex_unlock(my_mutex_t *mp
  173. #ifdef SAFE_MUTEX
  174. , const char *file, uint line
  175. #endif
  176. )
  177. {
  178. #ifdef SAFE_MUTEX
  179. return safe_mutex_unlock(mp, file, line);
  180. #else
  181. return native_mutex_unlock(mp);
  182. #endif
  183. }
  184. static inline int my_mutex_destroy(my_mutex_t *mp
  185. #ifdef SAFE_MUTEX
  186. , const char *file, uint line
  187. #endif
  188. )
  189. {
  190. #ifdef SAFE_MUTEX
  191. return safe_mutex_destroy(mp, file, line);
  192. #else
  193. return native_mutex_destroy(mp);
  194. #endif
  195. }
  196. C_MODE_END
  197. #endif /* THR_MUTEX_INCLUDED */