MySQL  8.0.26
Source Code Documentation
thr_mutex.h
Go to the documentation of this file.
1 #ifndef THR_MUTEX_INCLUDED
2 #define THR_MUTEX_INCLUDED
3 
4 /* Copyright (c) 2014, 2021, Oracle and/or its affiliates.
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License, version 2.0,
8  as published by the Free Software Foundation.
9 
10  This program is also distributed with certain software (including
11  but not limited to OpenSSL) that is licensed under separate terms,
12  as designated in a particular file or component or in included license
13  documentation. The authors of MySQL hereby grant you an additional
14  permission to link the program and your derivative works with the
15  separately licensed software that they have included with MySQL.
16 
17  This program is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  GNU General Public License, version 2.0, for more details.
21 
22  You should have received a copy of the GNU General Public License
23  along with this program; if not, write to the Free Software
24  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
25 
26 /**
27  @file include/thr_mutex.h
28  MySQL mutex implementation.
29 
30  There are three "layers":
31  1) native_mutex_*()
32  Functions that map directly down to OS primitives.
33  Windows - CriticalSection
34  Other OSes - pthread
35  2) my_mutex_*()
36  Functions that implement SAFE_MUTEX (default for debug),
37  Otherwise native_mutex_*() is used.
38  3) mysql_mutex_*()
39  Functions that include Performance Schema instrumentation.
40  See include/mysql/psi/mysql_thread.h
41 */
42 
43 #include <assert.h>
44 #include <stddef.h>
45 #include <stdlib.h>
46 #include <sys/types.h>
47 
48 #include "my_inttypes.h"
49 #include "my_macros.h"
50 #include "my_thread.h"
51 
52 /*
53  The following are part of the services ABI:
54  - native_mutex_t
55  - my_mutex_t
56 */
58 
59 /* Define mutex types, see my_thr_init.c */
60 #define MY_MUTEX_INIT_SLOW NULL
61 
62 /* Can be set in /usr/include/pthread.h */
63 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
64 extern native_mutexattr_t my_fast_mutexattr;
65 #define MY_MUTEX_INIT_FAST &my_fast_mutexattr
66 #else
67 #define MY_MUTEX_INIT_FAST NULL
68 #endif
69 
70 /* Can be set in /usr/include/pthread.h */
71 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
72 extern native_mutexattr_t my_errorcheck_mutexattr;
73 #define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr
74 #else
75 #define MY_MUTEX_INIT_ERRCHK NULL
76 #endif
77 
78 static inline int native_mutex_init(native_mutex_t *mutex,
79  const native_mutexattr_t *attr
80  MY_ATTRIBUTE((unused))) {
81 #ifdef _WIN32
82  InitializeCriticalSection(mutex);
83  return 0;
84 #else
85  return pthread_mutex_init(mutex, attr);
86 #endif
87 }
88 
89 static inline int native_mutex_lock(native_mutex_t *mutex) {
90 #ifdef _WIN32
91  EnterCriticalSection(mutex);
92  return 0;
93 #else
94  return pthread_mutex_lock(mutex);
95 #endif
96 }
97 
98 static inline int native_mutex_trylock(native_mutex_t *mutex) {
99 #ifdef _WIN32
100  if (TryEnterCriticalSection(mutex)) {
101  /* Don't allow recursive lock */
102  if (mutex->RecursionCount > 1) {
103  LeaveCriticalSection(mutex);
104  return EBUSY;
105  }
106  return 0;
107  }
108  return EBUSY;
109 #else
110  return pthread_mutex_trylock(mutex);
111 #endif
112 }
113 
114 static inline int native_mutex_unlock(native_mutex_t *mutex) {
115 #ifdef _WIN32
116  LeaveCriticalSection(mutex);
117  return 0;
118 #else
119  return pthread_mutex_unlock(mutex);
120 #endif
121 }
122 
123 static inline int native_mutex_destroy(native_mutex_t *mutex) {
124 #ifdef _WIN32
125  DeleteCriticalSection(mutex);
126  return 0;
127 #else
128  return pthread_mutex_destroy(mutex);
129 #endif
130 }
131 
132 #ifdef SAFE_MUTEX
133 /* safe_mutex adds checking to mutex for easier debugging */
134 struct safe_mutex_t {
135  native_mutex_t global, mutex;
136  const char *file;
137  uint line, count;
138  my_thread_t thread;
139 };
140 
141 void safe_mutex_global_init();
142 int safe_mutex_init(safe_mutex_t *mp, const native_mutexattr_t *attr,
143  const char *file, uint line);
144 int safe_mutex_lock(safe_mutex_t *mp, bool try_lock, const char *file,
145  uint line);
146 int safe_mutex_unlock(safe_mutex_t *mp, const char *file, uint line);
147 int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line);
148 
149 static inline void safe_mutex_assert_owner(safe_mutex_t *mp) {
150  assert(mp != nullptr);
151  native_mutex_lock(&mp->global);
152  assert(mp->count > 0 && my_thread_equal(my_thread_self(), mp->thread));
153  native_mutex_unlock(&mp->global);
154 }
155 
156 static inline void safe_mutex_assert_not_owner(safe_mutex_t *mp) {
157  assert(mp != nullptr);
158  native_mutex_lock(&mp->global);
159  assert(!mp->count || !my_thread_equal(my_thread_self(), mp->thread));
160  native_mutex_unlock(&mp->global);
161 }
162 #endif /* SAFE_MUTEX */
163 
164 static inline int my_mutex_init(my_mutex_t *mp, const native_mutexattr_t *attr
165 #ifdef SAFE_MUTEX
166  ,
167  const char *file, uint line
168 #endif
169 ) {
170 #ifdef SAFE_MUTEX
171  assert(mp != nullptr);
172  mp->m_u.m_safe_ptr = (safe_mutex_t *)malloc(sizeof(safe_mutex_t));
173  return safe_mutex_init(mp->m_u.m_safe_ptr, attr, file, line);
174 #else
175  return native_mutex_init(&mp->m_u.m_native, attr);
176 #endif
177 }
178 
179 static inline int my_mutex_lock(my_mutex_t *mp
180 #ifdef SAFE_MUTEX
181  ,
182  const char *file, uint line
183 #endif
184 ) {
185 #ifdef SAFE_MUTEX
186  assert(mp != nullptr);
187  assert(mp->m_u.m_safe_ptr != nullptr);
188  return safe_mutex_lock(mp->m_u.m_safe_ptr, false, file, line);
189 #else
190  return native_mutex_lock(&mp->m_u.m_native);
191 #endif
192 }
193 
194 static inline int my_mutex_trylock(my_mutex_t *mp
195 #ifdef SAFE_MUTEX
196  ,
197  const char *file, uint line
198 #endif
199 ) {
200 #ifdef SAFE_MUTEX
201  assert(mp != nullptr);
202  assert(mp->m_u.m_safe_ptr != nullptr);
203  return safe_mutex_lock(mp->m_u.m_safe_ptr, true, file, line);
204 #else
205  return native_mutex_trylock(&mp->m_u.m_native);
206 #endif
207 }
208 
209 static inline int my_mutex_unlock(my_mutex_t *mp
210 #ifdef SAFE_MUTEX
211  ,
212  const char *file, uint line
213 #endif
214 ) {
215 #ifdef SAFE_MUTEX
216  assert(mp != nullptr);
217  assert(mp->m_u.m_safe_ptr != nullptr);
218  return safe_mutex_unlock(mp->m_u.m_safe_ptr, file, line);
219 #else
220  return native_mutex_unlock(&mp->m_u.m_native);
221 #endif
222 }
223 
224 static inline int my_mutex_destroy(my_mutex_t *mp
225 #ifdef SAFE_MUTEX
226  ,
227  const char *file, uint line
228 #endif
229 ) {
230 #ifdef SAFE_MUTEX
231  assert(mp != nullptr);
232  assert(mp->m_u.m_safe_ptr != nullptr);
233  int rc = safe_mutex_destroy(mp->m_u.m_safe_ptr, file, line);
234  free(mp->m_u.m_safe_ptr);
235  mp->m_u.m_safe_ptr = nullptr;
236  return rc;
237 #else
238  return native_mutex_destroy(&mp->m_u.m_native);
239 #endif
240 }
241 
242 #endif /* THR_MUTEX_INCLUDED */
#define malloc(A)
Definition: fts0ast.h:41
#define free(A)
Definition: fts0ast.h:42
Some integer typedefs for easier portability.
Some common macros.
Defines to make different thread packages compatible.
static my_thread_t my_thread_self()
Definition: my_thread.h:84
static int my_thread_equal(my_thread_t t1, my_thread_t t2)
Definition: my_thread.h:92
pthread_t my_thread_t
Definition: my_thread_bits.h:47
static int count
Definition: myisam_ftdump.cc:42
Definition: os0file.h:85
Definition: thr_mutex_bits.h:60
union my_mutex_t::u m_u
static int my_mutex_init(my_mutex_t *mp, const native_mutexattr_t *attr)
Definition: thr_mutex.h:164
static int native_mutex_unlock(native_mutex_t *mutex)
Definition: thr_mutex.h:114
static int native_mutex_destroy(native_mutex_t *mutex)
Definition: thr_mutex.h:123
static int my_mutex_destroy(my_mutex_t *mp)
Definition: thr_mutex.h:224
static int native_mutex_trylock(native_mutex_t *mutex)
Definition: thr_mutex.h:98
static int native_mutex_lock(native_mutex_t *mutex)
Definition: thr_mutex.h:89
static int native_mutex_init(native_mutex_t *mutex, const native_mutexattr_t *attr)
Definition: thr_mutex.h:78
static int my_mutex_lock(my_mutex_t *mp)
Definition: thr_mutex.h:179
static int my_mutex_trylock(my_mutex_t *mp)
Definition: thr_mutex.h:194
static int my_mutex_unlock(my_mutex_t *mp)
Definition: thr_mutex.h:209
ABI for thd_mutex.
pthread_mutex_t native_mutex_t
Definition: thr_mutex_bits.h:54
pthread_mutexattr_t native_mutexattr_t
Definition: thr_mutex_bits.h:55
unsigned int uint
Definition: uca-dump.cc:29
native_mutex_t m_native
Definition: thr_mutex_bits.h:62
safe_mutex_t * m_safe_ptr
Definition: thr_mutex_bits.h:63