OSDN Git Service

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