MySQL  8.0.18
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, 2019, Oracle and/or its affiliates. All rights reserved.
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 <stddef.h>
44 #include <sys/types.h>
45 
46 #include "my_dbug.h"
47 #include "my_inttypes.h"
48 #include "my_macros.h"
49 #include "my_thread.h"
50 
51 /*
52  The following are part of the services ABI:
53  - native_mutex_t
54  - my_mutex_t
55 */
57 
58 /* Define mutex types, see my_thr_init.c */
59 #define MY_MUTEX_INIT_SLOW NULL
60 
61 /* Can be set in /usr/include/pthread.h */
62 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
63 extern native_mutexattr_t my_fast_mutexattr;
64 #define MY_MUTEX_INIT_FAST &my_fast_mutexattr
65 #else
66 #define MY_MUTEX_INIT_FAST NULL
67 #endif
68 
69 /* Can be set in /usr/include/pthread.h */
70 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
71 extern native_mutexattr_t my_errorcheck_mutexattr;
72 #define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr
73 #else
74 #define MY_MUTEX_INIT_ERRCHK NULL
75 #endif
76 
78  const native_mutexattr_t *attr
79  MY_ATTRIBUTE((unused))) {
80 #ifdef _WIN32
81  InitializeCriticalSection(mutex);
82  return 0;
83 #else
84  return pthread_mutex_init(mutex, attr);
85 #endif
86 }
87 
88 static inline int native_mutex_lock(native_mutex_t *mutex) {
89 #ifdef _WIN32
90  EnterCriticalSection(mutex);
91  return 0;
92 #else
93  return pthread_mutex_lock(mutex);
94 #endif
95 }
96 
98 #ifdef _WIN32
99  if (TryEnterCriticalSection(mutex)) {
100  /* Don't allow recursive lock */
101  if (mutex->RecursionCount > 1) {
102  LeaveCriticalSection(mutex);
103  return EBUSY;
104  }
105  return 0;
106  }
107  return EBUSY;
108 #else
109  return pthread_mutex_trylock(mutex);
110 #endif
111 }
112 
114 #ifdef _WIN32
115  LeaveCriticalSection(mutex);
116  return 0;
117 #else
118  return pthread_mutex_unlock(mutex);
119 #endif
120 }
121 
123 #ifdef _WIN32
124  DeleteCriticalSection(mutex);
125  return 0;
126 #else
127  return pthread_mutex_destroy(mutex);
128 #endif
129 }
130 
131 #ifdef SAFE_MUTEX
132 /* safe_mutex adds checking to mutex for easier debugging */
133 struct safe_mutex_t {
134  native_mutex_t global, mutex;
135  const char *file;
136  uint line, count;
137  my_thread_t thread;
138 };
139 
140 void safe_mutex_global_init();
141 int safe_mutex_init(safe_mutex_t *mp, const native_mutexattr_t *attr,
142  const char *file, uint line);
143 int safe_mutex_lock(safe_mutex_t *mp, bool try_lock, const char *file,
144  uint line);
145 int safe_mutex_unlock(safe_mutex_t *mp, const char *file, uint line);
146 int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line);
147 
148 static inline void safe_mutex_assert_owner(safe_mutex_t *mp) {
149  DBUG_ASSERT(mp != NULL);
150  native_mutex_lock(&mp->global);
151  DBUG_ASSERT(mp->count > 0 && my_thread_equal(my_thread_self(), mp->thread));
152  native_mutex_unlock(&mp->global);
153 }
154 
155 static inline void safe_mutex_assert_not_owner(safe_mutex_t *mp) {
156  DBUG_ASSERT(mp != NULL);
157  native_mutex_lock(&mp->global);
158  DBUG_ASSERT(!mp->count || !my_thread_equal(my_thread_self(), mp->thread));
159  native_mutex_unlock(&mp->global);
160 }
161 #endif /* SAFE_MUTEX */
162 
163 static inline int my_mutex_init(my_mutex_t *mp, const native_mutexattr_t *attr
164 #ifdef SAFE_MUTEX
165  ,
166  const char *file, uint line
167 #endif
168 ) {
169 #ifdef SAFE_MUTEX
170  DBUG_ASSERT(mp != NULL);
171  mp->m_u.m_safe_ptr = (safe_mutex_t *)malloc(sizeof(safe_mutex_t));
172  return safe_mutex_init(mp->m_u.m_safe_ptr, attr, file, line);
173 #else
174  return native_mutex_init(&mp->m_u.m_native, attr);
175 #endif
176 }
177 
178 static inline int my_mutex_lock(my_mutex_t *mp
179 #ifdef SAFE_MUTEX
180  ,
181  const char *file, uint line
182 #endif
183 ) {
184 #ifdef SAFE_MUTEX
185  DBUG_ASSERT(mp != NULL);
186  DBUG_ASSERT(mp->m_u.m_safe_ptr != NULL);
187  return safe_mutex_lock(mp->m_u.m_safe_ptr, false, file, line);
188 #else
189  return native_mutex_lock(&mp->m_u.m_native);
190 #endif
191 }
192 
193 static inline int my_mutex_trylock(my_mutex_t *mp
194 #ifdef SAFE_MUTEX
195  ,
196  const char *file, uint line
197 #endif
198 ) {
199 #ifdef SAFE_MUTEX
200  DBUG_ASSERT(mp != NULL);
201  DBUG_ASSERT(mp->m_u.m_safe_ptr != NULL);
202  return safe_mutex_lock(mp->m_u.m_safe_ptr, true, file, line);
203 #else
204  return native_mutex_trylock(&mp->m_u.m_native);
205 #endif
206 }
207 
208 static inline int my_mutex_unlock(my_mutex_t *mp
209 #ifdef SAFE_MUTEX
210  ,
211  const char *file, uint line
212 #endif
213 ) {
214 #ifdef SAFE_MUTEX
215  DBUG_ASSERT(mp != NULL);
216  DBUG_ASSERT(mp->m_u.m_safe_ptr != NULL);
217  return safe_mutex_unlock(mp->m_u.m_safe_ptr, file, line);
218 #else
219  return native_mutex_unlock(&mp->m_u.m_native);
220 #endif
221 }
222 
223 static inline int my_mutex_destroy(my_mutex_t *mp
224 #ifdef SAFE_MUTEX
225  ,
226  const char *file, uint line
227 #endif
228 ) {
229 #ifdef SAFE_MUTEX
230  DBUG_ASSERT(mp != NULL);
231  DBUG_ASSERT(mp->m_u.m_safe_ptr != NULL);
232  int rc = safe_mutex_destroy(mp->m_u.m_safe_ptr, file, line);
233  free(mp->m_u.m_safe_ptr);
234  mp->m_u.m_safe_ptr = NULL;
235  return rc;
236 #else
237  return native_mutex_destroy(&mp->m_u.m_native);
238 #endif
239 }
240 
241 #endif /* THR_MUTEX_INCLUDED */
Some common macros.
static int native_mutex_lock(native_mutex_t *mutex)
Definition: thr_mutex.h:88
#define free(A)
Definition: fts0ast.h:42
ssize_t count
Definition: memcached.c:386
union my_mutex_t::u m_u
static int my_mutex_destroy(my_mutex_t *mp)
Definition: thr_mutex.h:223
Some integer typedefs for easier portability.
static int native_mutex_destroy(native_mutex_t *mutex)
Definition: thr_mutex.h:122
pthread_mutex_t mutex
Definition: memcached.c:384
#define malloc(A)
Definition: fts0ast.h:41
static int my_mutex_init(my_mutex_t *mp, const native_mutexattr_t *attr)
Definition: thr_mutex.h:163
static int my_mutex_trylock(my_mutex_t *mp)
Definition: thr_mutex.h:193
static int my_mutex_unlock(my_mutex_t *mp)
Definition: thr_mutex.h:208
#define DBUG_ASSERT(A)
Definition: my_dbug.h:197
safe_mutex_t * m_safe_ptr
Definition: thr_mutex_bits.h:63
static int my_thread_equal(my_thread_t t1, my_thread_t t2)
Definition: my_thread.h:92
static int my_mutex_lock(my_mutex_t *mp)
Definition: thr_mutex.h:178
native_mutex_t m_native
Definition: thr_mutex_bits.h:62
unsigned int uint
Definition: uca-dump.cc:29
pthread_t my_thread_t
Definition: my_thread_bits.h:47
Defines to make different thread packages compatible.
pthread_mutex_t native_mutex_t
Definition: thr_mutex_bits.h:54
static int native_mutex_unlock(native_mutex_t *mutex)
Definition: thr_mutex.h:113
static int native_mutex_init(native_mutex_t *mutex, const native_mutexattr_t *attr)
Definition: thr_mutex.h:77
Definition: thr_mutex_bits.h:60
#define NULL
Definition: types.h:55
static my_thread_t my_thread_self()
Definition: my_thread.h:84
static int native_mutex_trylock(native_mutex_t *mutex)
Definition: thr_mutex.h:97
ABI for thd_mutex.
pthread_mutexattr_t native_mutexattr_t
Definition: thr_mutex_bits.h:55