MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
my_pthread.h
1 /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
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 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
15 
16 /* Defines to make different thread packages compatible */
17 
18 #ifndef _my_pthread_h
19 #define _my_pthread_h
20 
21 #include "my_global.h" /* myf */
22 
23 #ifndef ETIME
24 #define ETIME ETIMEDOUT /* For FreeBSD */
25 #endif
26 
27 #ifdef __cplusplus
28 #define EXTERNC extern "C"
29 extern "C" {
30 #else
31 #define EXTERNC
32 #endif /* __cplusplus */
33 
34 #if defined(__WIN__)
35 typedef CRITICAL_SECTION pthread_mutex_t;
36 typedef DWORD pthread_t;
37 typedef struct thread_attr {
38  DWORD dwStackSize ;
39  DWORD dwCreatingFlag ;
40 } pthread_attr_t ;
41 
42 typedef struct { int dummy; } pthread_condattr_t;
43 
44 /* Implementation of posix conditions */
45 
46 typedef struct st_pthread_link {
47  DWORD thread_id;
48  struct st_pthread_link *next;
49 } pthread_link;
50 
56 typedef union
57 {
58  /* Native condition (used on Vista and later) */
59  CONDITION_VARIABLE native_cond;
60 
61  /* Own implementation (used on XP) */
62  struct
63  {
64  uint32 waiting;
65  CRITICAL_SECTION lock_waiting;
66  enum
67  {
68  SIGNAL= 0,
69  BROADCAST= 1,
70  MAX_EVENTS= 2
71  } EVENTS;
72  HANDLE events[MAX_EVENTS];
73  HANDLE broadcast_block_event;
74  };
75 } pthread_cond_t;
76 
77 
78 typedef int pthread_mutexattr_t;
79 #define pthread_self() GetCurrentThreadId()
80 #define pthread_handler_t EXTERNC void * __cdecl
81 typedef void * (__cdecl *pthread_handler)(void *);
82 
83 typedef volatile LONG my_pthread_once_t;
84 #define MY_PTHREAD_ONCE_INIT 0
85 #define MY_PTHREAD_ONCE_INPROGRESS 1
86 #define MY_PTHREAD_ONCE_DONE 2
87 
88 /*
89  Struct and macros to be used in combination with the
90  windows implementation of pthread_cond_timedwait
91 */
92 
93 /*
94  Declare a union to make sure FILETIME is properly aligned
95  so it can be used directly as a 64 bit value. The value
96  stored is in 100ns units.
97  */
98  union ft64 {
99  FILETIME ft;
100  __int64 i64;
101  };
102 struct timespec {
103  union ft64 tv;
104  /* The max timeout value in millisecond for pthread_cond_timedwait */
105  long max_timeout_msec;
106 };
107 #define set_timespec_time_nsec(ABSTIME,TIME,NSEC) do { \
108  (ABSTIME).tv.i64= (TIME)+(__int64)(NSEC)/100; \
109  (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
110 } while(0)
111 
112 #define set_timespec_nsec(ABSTIME,NSEC) do { \
113  union ft64 tv; \
114  GetSystemTimeAsFileTime(&tv.ft); \
115  set_timespec_time_nsec((ABSTIME), tv.i64, (NSEC)); \
116 } while(0)
117 
127 #define cmp_timespec(TS1, TS2) \
128  ((TS1.tv.i64 > TS2.tv.i64) ? 1 : \
129  ((TS1.tv.i64 < TS2.tv.i64) ? -1 : 0))
130 
131 #define diff_timespec(TS1, TS2) \
132  ((TS1.tv.i64 - TS2.tv.i64) * 100)
133 
134 int win_pthread_mutex_trylock(pthread_mutex_t *mutex);
135 int pthread_create(pthread_t *, const pthread_attr_t *, pthread_handler, void *);
136 int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
137 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
138 int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
139  struct timespec *abstime);
140 int pthread_cond_signal(pthread_cond_t *cond);
141 int pthread_cond_broadcast(pthread_cond_t *cond);
142 int pthread_cond_destroy(pthread_cond_t *cond);
143 int pthread_attr_init(pthread_attr_t *connect_att);
144 int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack);
145 int pthread_attr_destroy(pthread_attr_t *connect_att);
146 int my_pthread_once(my_pthread_once_t *once_control,void (*init_routine)(void));
147 struct tm *localtime_r(const time_t *timep,struct tm *tmp);
148 struct tm *gmtime_r(const time_t *timep,struct tm *tmp);
149 
150 void pthread_exit(void *a);
151 int pthread_join(pthread_t thread, void **value_ptr);
152 int pthread_cancel(pthread_t thread);
153 
154 #ifndef ETIMEDOUT
155 #define ETIMEDOUT 145 /* Win32 doesn't have this */
156 #endif
157 #define HAVE_LOCALTIME_R 1
158 #define _REENTRANT 1
159 #define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
160 
161 
162 #undef SAFE_MUTEX /* This will cause conflicts */
163 #define pthread_key(T,V) DWORD V
164 #define pthread_key_create(A,B) ((*A=TlsAlloc())==0xFFFFFFFF)
165 #define pthread_key_delete(A) TlsFree(A)
166 #define my_pthread_setspecific_ptr(T,V) (!TlsSetValue((T),(V)))
167 #define pthread_setspecific(A,B) (!TlsSetValue((A),(B)))
168 #define pthread_getspecific(A) (TlsGetValue(A))
169 #define my_pthread_getspecific(T,A) ((T) TlsGetValue(A))
170 #define my_pthread_getspecific_ptr(T,V) ((T) TlsGetValue(V))
171 
172 #define pthread_equal(A,B) ((A) == (B))
173 #define pthread_mutex_init(A,B) (InitializeCriticalSection(A),0)
174 #define pthread_mutex_lock(A) (EnterCriticalSection(A),0)
175 #define pthread_mutex_trylock(A) win_pthread_mutex_trylock((A))
176 #define pthread_mutex_unlock(A) (LeaveCriticalSection(A), 0)
177 #define pthread_mutex_destroy(A) (DeleteCriticalSection(A), 0)
178 #define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH)
179 
180 
181 /* Dummy defines for easier code */
182 #define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
183 #define pthread_attr_setscope(A,B)
184 #define pthread_detach_this_thread()
185 #define pthread_condattr_init(A)
186 #define pthread_condattr_destroy(A)
187 #define pthread_yield() SwitchToThread()
188 #define my_sigset(A,B) signal(A,B)
189 
190 #else /* Normal threads */
191 
192 #ifdef HAVE_rts_threads
193 #define sigwait org_sigwait
194 #include <signal.h>
195 #undef sigwait
196 #endif
197 #include <pthread.h>
198 #ifndef _REENTRANT
199 #define _REENTRANT
200 #endif
201 #ifdef HAVE_THR_SETCONCURRENCY
202 #include <thread.h> /* Probably solaris */
203 #endif
204 #ifdef HAVE_SCHED_H
205 #include <sched.h>
206 #endif
207 #ifdef HAVE_SYNCH_H
208 #include <synch.h>
209 #endif
210 
211 #define pthread_key(T,V) pthread_key_t V
212 #define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,(V))
213 #define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,(void*) (V))
214 #define pthread_detach_this_thread()
215 #define pthread_handler_t EXTERNC void *
216 typedef void *(* pthread_handler)(void *);
217 
218 #define my_pthread_once_t pthread_once_t
219 #if defined(PTHREAD_ONCE_INITIALIZER)
220 #define MY_PTHREAD_ONCE_INIT PTHREAD_ONCE_INITIALIZER
221 #else
222 #define MY_PTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
223 #endif
224 #define my_pthread_once(C,F) pthread_once(C,F)
225 
226 /* Test first for RTS or FSU threads */
227 
228 #if defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM)
229 #define HAVE_rts_threads
230 extern int my_pthread_create_detached;
231 #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
232 #define PTHREAD_CREATE_DETACHED &my_pthread_create_detached
233 #define PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_GLOBAL
234 #define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_LOCAL
235 #define USE_ALARM_THREAD
236 #endif /* defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) */
237 
238 #if defined(_BSDI_VERSION) && _BSDI_VERSION < 199910
239 int sigwait(sigset_t *set, int *sig);
240 #endif
241 
242 #ifndef HAVE_NONPOSIX_SIGWAIT
243 #define my_sigwait(A,B) sigwait((A),(B))
244 #else
245 int my_sigwait(const sigset_t *set,int *sig);
246 #endif
247 
248 #ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT
249 #ifndef SAFE_MUTEX
250 #define pthread_mutex_init(a,b) my_pthread_mutex_init((a),(b))
251 extern int my_pthread_mutex_init(pthread_mutex_t *mp,
252  const pthread_mutexattr_t *attr);
253 #endif /* SAFE_MUTEX */
254 #define pthread_cond_init(a,b) my_pthread_cond_init((a),(b))
255 extern int my_pthread_cond_init(pthread_cond_t *mp,
256  const pthread_condattr_t *attr);
257 #endif /* HAVE_NONPOSIX_PTHREAD_MUTEX_INIT */
258 
259 #if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK)
260 #define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C))
261 #endif
262 
263 #if !defined(HAVE_SIGWAIT) && !defined(HAVE_rts_threads) && !defined(sigwait) && !defined(alpha_linux_port) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS) && !defined(_AIX)
264 int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */
265 #endif
266 
267 
268 /*
269  We define my_sigset() and use that instead of the system sigset() so that
270  we can favor an implementation based on sigaction(). On some systems, such
271  as Mac OS X, sigset() results in flags such as SA_RESTART being set, and
272  we want to make sure that no such flags are set.
273 */
274 #if defined(HAVE_SIGACTION) && !defined(my_sigset)
275 #define my_sigset(A,B) do { struct sigaction l_s; sigset_t l_set; \
276  DBUG_ASSERT((A) != 0); \
277  sigemptyset(&l_set); \
278  l_s.sa_handler = (B); \
279  l_s.sa_mask = l_set; \
280  l_s.sa_flags = 0; \
281  sigaction((A), &l_s, NULL); \
282  } while (0)
283 #elif defined(HAVE_SIGSET) && !defined(my_sigset)
284 #define my_sigset(A,B) sigset((A),(B))
285 #elif !defined(my_sigset)
286 #define my_sigset(A,B) signal((A),(B))
287 #endif
288 
289 #if !defined(HAVE_PTHREAD_ATTR_SETSCOPE) || defined(HAVE_DEC_3_2_THREADS)
290 #define pthread_attr_setscope(A,B)
291 #undef HAVE_GETHOSTBYADDR_R /* No definition */
292 #endif
293 
294 #if defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT) && !defined(SAFE_MUTEX)
295 extern int my_pthread_cond_timedwait(pthread_cond_t *cond,
296  pthread_mutex_t *mutex,
297  struct timespec *abstime);
298 #define pthread_cond_timedwait(A,B,C) my_pthread_cond_timedwait((A),(B),(C))
299 #endif
300 
301 #if !defined( HAVE_NONPOSIX_PTHREAD_GETSPECIFIC)
302 #define my_pthread_getspecific(A,B) ((A) pthread_getspecific(B))
303 #else
304 #define my_pthread_getspecific(A,B) ((A) my_pthread_getspecific_imp(B))
305 void *my_pthread_getspecific_imp(pthread_key_t key);
306 #endif
307 
308 #ifndef HAVE_LOCALTIME_R
309 struct tm *localtime_r(const time_t *clock, struct tm *res);
310 #endif
311 
312 #ifndef HAVE_GMTIME_R
313 struct tm *gmtime_r(const time_t *clock, struct tm *res);
314 #endif
315 
316 #ifdef HAVE_PTHREAD_CONDATTR_CREATE
317 /* DCE threads on HPUX 10.20 */
318 #define pthread_condattr_init pthread_condattr_create
319 #define pthread_condattr_destroy pthread_condattr_delete
320 #endif
321 
322 /* FSU THREADS */
323 #if !defined(HAVE_PTHREAD_KEY_DELETE) && !defined(pthread_key_delete)
324 #define pthread_key_delete(A) pthread_dummy(0)
325 #endif
326 
327 #ifdef HAVE_CTHREADS_WRAPPER /* For MacOSX */
328 #define pthread_cond_destroy(A) pthread_dummy(0)
329 #define pthread_mutex_destroy(A) pthread_dummy(0)
330 #define pthread_attr_delete(A) pthread_dummy(0)
331 #define pthread_condattr_delete(A) pthread_dummy(0)
332 #define pthread_attr_setstacksize(A,B) pthread_dummy(0)
333 #define pthread_equal(A,B) ((A) == (B))
334 #define pthread_cond_timedwait(a,b,c) pthread_cond_wait((a),(b))
335 #define pthread_attr_init(A) pthread_attr_create(A)
336 #define pthread_attr_destroy(A) pthread_attr_delete(A)
337 #define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
338 #define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D))
339 #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
340 #define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH)
341 #undef pthread_detach_this_thread
342 #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); }
343 #endif
344 
345 #ifdef HAVE_DARWIN5_THREADS
346 #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
347 #define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH)
348 #define pthread_condattr_init(A) pthread_dummy(0)
349 #define pthread_condattr_destroy(A) pthread_dummy(0)
350 #undef pthread_detach_this_thread
351 #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(tmp); }
352 #endif
353 
354 #if ((defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT)) || defined(HAVE_DEC_3_2_THREADS)) && !defined(HAVE_CTHREADS_WRAPPER)
355 /* This is set on AIX_3_2 and Siemens unix (and DEC OSF/1 3.2 too) */
356 #define pthread_key_create(A,B) \
357  pthread_keycreate(A,(B) ?\
358  (pthread_destructor_t) (B) :\
359  (pthread_destructor_t) pthread_dummy)
360 #define pthread_attr_init(A) pthread_attr_create(A)
361 #define pthread_attr_destroy(A) pthread_attr_delete(A)
362 #define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
363 #define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D))
364 #ifndef pthread_sigmask
365 #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
366 #endif
367 #define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH)
368 #undef pthread_detach_this_thread
369 #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); }
370 #else /* HAVE_PTHREAD_ATTR_CREATE && !HAVE_SIGWAIT */
371 #define HAVE_PTHREAD_KILL
372 #endif
373 
374 #endif /* defined(__WIN__) */
375 
376 #if defined(HPUX10) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS)
377 #undef pthread_cond_timedwait
378 #define pthread_cond_timedwait(a,b,c) my_pthread_cond_timedwait((a),(b),(c))
379 int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
380  struct timespec *abstime);
381 #endif
382 
383 #if defined(HPUX10)
384 #define pthread_attr_getstacksize(A,B) my_pthread_attr_getstacksize(A,B)
385 void my_pthread_attr_getstacksize(pthread_attr_t *attrib, size_t *size);
386 #endif
387 
388 #if defined(HAVE_POSIX1003_4a_MUTEX) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS)
389 #undef pthread_mutex_trylock
390 #define pthread_mutex_trylock(a) my_pthread_mutex_trylock((a))
391 int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
392 #endif
393 
394 #if !defined(HAVE_PTHREAD_YIELD_ONE_ARG) && !defined(HAVE_PTHREAD_YIELD_ZERO_ARG)
395 /* no pthread_yield() available */
396 #ifdef HAVE_SCHED_YIELD
397 #define pthread_yield() sched_yield()
398 #elif defined(HAVE_PTHREAD_YIELD_NP) /* can be Mac OS X */
399 #define pthread_yield() pthread_yield_np()
400 #elif defined(HAVE_THR_YIELD)
401 #define pthread_yield() thr_yield()
402 #endif
403 #endif
404 
405 /*
406  The defines set_timespec and set_timespec_nsec should be used
407  for calculating an absolute time at which
408  pthread_cond_timedwait should timeout
409 */
410 #define set_timespec(ABSTIME,SEC) set_timespec_nsec((ABSTIME),(SEC)*1000000000ULL)
411 
412 #ifndef set_timespec_nsec
413 #define set_timespec_nsec(ABSTIME,NSEC) \
414  set_timespec_time_nsec((ABSTIME),my_getsystime(),(NSEC))
415 #endif /* !set_timespec_nsec */
416 
417 /* adapt for two different flavors of struct timespec */
418 #ifdef HAVE_TIMESPEC_TS_SEC
419 #define MY_tv_sec ts_sec
420 #define MY_tv_nsec ts_nsec
421 #else
422 #define MY_tv_sec tv_sec
423 #define MY_tv_nsec tv_nsec
424 #endif /* HAVE_TIMESPEC_TS_SEC */
425 
426 #ifndef set_timespec_time_nsec
427 #define set_timespec_time_nsec(ABSTIME,TIME,NSEC) do { \
428  ulonglong nsec= (NSEC); \
429  ulonglong now= (TIME) + (nsec/100); \
430  (ABSTIME).MY_tv_sec= (now / 10000000ULL); \
431  (ABSTIME).MY_tv_nsec= (now % 10000000ULL * 100 + (nsec % 100)); \
432 } while(0)
433 #endif /* !set_timespec_time_nsec */
434 
444 #ifdef HAVE_TIMESPEC_TS_SEC
445 #ifndef cmp_timespec
446 #define cmp_timespec(TS1, TS2) \
447  ((TS1.ts_sec > TS2.ts_sec || \
448  (TS1.ts_sec == TS2.ts_sec && TS1.ts_nsec > TS2.ts_nsec)) ? 1 : \
449  ((TS1.ts_sec < TS2.ts_sec || \
450  (TS1.ts_sec == TS2.ts_sec && TS1.ts_nsec < TS2.ts_nsec)) ? -1 : 0))
451 #endif /* !cmp_timespec */
452 #else
453 #ifndef cmp_timespec
454 #define cmp_timespec(TS1, TS2) \
455  ((TS1.tv_sec > TS2.tv_sec || \
456  (TS1.tv_sec == TS2.tv_sec && TS1.tv_nsec > TS2.tv_nsec)) ? 1 : \
457  ((TS1.tv_sec < TS2.tv_sec || \
458  (TS1.tv_sec == TS2.tv_sec && TS1.tv_nsec < TS2.tv_nsec)) ? -1 : 0))
459 #endif /* !cmp_timespec */
460 #endif /* HAVE_TIMESPEC_TS_SEC */
461 
462 #ifdef HAVE_TIMESPEC_TS_SEC
463 #ifndef diff_timespec
464 #define diff_timespec(TS1, TS2) \
465  ((TS1.ts_sec - TS2.ts_sec) * 1000000000ULL + TS1.ts_nsec - TS2.ts_nsec)
466 #endif /* !diff_timespec */
467 #else
468 #ifndef diff_timespec
469 #define diff_timespec(TS1, TS2) \
470  ((TS1.tv_sec - TS2.tv_sec) * 1000000000ULL + TS1.tv_nsec - TS2.tv_nsec)
471 #endif /* !diff_timespec */
472 #endif /* HAVE_TIMESPEC_TS_SEC */
473 
474  /* safe_mutex adds checking to mutex for easier debugging */
475 
476 typedef struct st_safe_mutex_t
477 {
478  pthread_mutex_t global,mutex;
479  const char *file;
480  uint line,count;
481  pthread_t thread;
482 #ifdef SAFE_MUTEX_DETECT_DESTROY
483  struct st_safe_mutex_info_t *info; /* to track destroying of mutexes */
484 #endif
485 } safe_mutex_t;
486 
487 #ifdef SAFE_MUTEX_DETECT_DESTROY
488 /*
489  Used to track the destroying of mutexes. This needs to be a seperate
490  structure because the safe_mutex_t structure could be freed before
491  the mutexes are destroyed.
492 */
493 
494 typedef struct st_safe_mutex_info_t
495 {
496  struct st_safe_mutex_info_t *next;
497  struct st_safe_mutex_info_t *prev;
498  const char *init_file;
499  uint32 init_line;
500 } safe_mutex_info_t;
501 #endif /* SAFE_MUTEX_DETECT_DESTROY */
502 
503 int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr,
504  const char *file, uint line);
505 int safe_mutex_lock(safe_mutex_t *mp, my_bool try_lock, const char *file, uint line);
506 int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line);
507 int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line);
508 int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file,
509  uint line);
510 int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
511  const struct timespec *abstime,
512  const char *file, uint line);
513 void safe_mutex_global_init(void);
514 void safe_mutex_end(FILE *file);
515 
516  /* Wrappers if safe mutex is actually used */
517 #ifdef SAFE_MUTEX
518 #define safe_mutex_assert_owner(mp) \
519  DBUG_ASSERT((mp)->count > 0 && \
520  pthread_equal(pthread_self(), (mp)->thread))
521 #define safe_mutex_assert_not_owner(mp) \
522  DBUG_ASSERT(! (mp)->count || \
523  ! pthread_equal(pthread_self(), (mp)->thread))
524 
525 #define my_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__)
526 #define my_cond_wait(A,B) safe_cond_wait((A), (B), __FILE__, __LINE__)
527 
528 #elif defined(MY_PTHREAD_FASTMUTEX)
529 
530 #define safe_mutex_assert_owner(mp) do {} while (0)
531 #define safe_mutex_assert_not_owner(mp) do {} while (0)
532 
533 #define my_cond_timedwait(A,B,C) pthread_cond_timedwait((A), &(B)->mutex, (C))
534 #define my_cond_wait(A,B) pthread_cond_wait((A), &(B)->mutex)
535 
536 #else
537 
538 #define safe_mutex_assert_owner(mp) do {} while (0)
539 #define safe_mutex_assert_not_owner(mp) do {} while (0)
540 
541 #define my_cond_timedwait(A,B,C) pthread_cond_timedwait((A),(B),(C))
542 #define my_cond_wait(A,B) pthread_cond_wait((A), (B))
543 
544 #endif /* !SAFE_MUTEX && ! MY_PTHREAD_FASTMUTEX */
545 
546 #if defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX)
547 typedef struct st_my_pthread_fastmutex_t
548 {
549  pthread_mutex_t mutex;
550  uint spins;
551  uint rng_state;
552 } my_pthread_fastmutex_t;
553 void fastmutex_global_init(void);
554 
555 int my_pthread_fastmutex_init(my_pthread_fastmutex_t *mp,
556  const pthread_mutexattr_t *attr);
557 int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp);
558 
559 #endif /* defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) */
560 
561  /* READ-WRITE thread locking */
562 
563 #ifdef HAVE_BROKEN_RWLOCK /* For OpenUnix */
564 #undef HAVE_PTHREAD_RWLOCK_RDLOCK
565 #undef HAVE_RWLOCK_INIT
566 #undef HAVE_RWLOCK_T
567 #endif
568 
569 #if defined(USE_MUTEX_INSTEAD_OF_RW_LOCKS)
570 /* use these defs for simple mutex locking */
571 #define rw_lock_t pthread_mutex_t
572 #define my_rwlock_init(A,B) pthread_mutex_init((A),(B))
573 #define rw_rdlock(A) pthread_mutex_lock((A))
574 #define rw_wrlock(A) pthread_mutex_lock((A))
575 #define rw_tryrdlock(A) pthread_mutex_trylock((A))
576 #define rw_trywrlock(A) pthread_mutex_trylock((A))
577 #define rw_unlock(A) pthread_mutex_unlock((A))
578 #define rwlock_destroy(A) pthread_mutex_destroy((A))
579 #elif defined(HAVE_PTHREAD_RWLOCK_RDLOCK)
580 #define rw_lock_t pthread_rwlock_t
581 #define my_rwlock_init(A,B) pthread_rwlock_init((A),(B))
582 #define rw_rdlock(A) pthread_rwlock_rdlock(A)
583 #define rw_wrlock(A) pthread_rwlock_wrlock(A)
584 #define rw_tryrdlock(A) pthread_rwlock_tryrdlock((A))
585 #define rw_trywrlock(A) pthread_rwlock_trywrlock((A))
586 #define rw_unlock(A) pthread_rwlock_unlock(A)
587 #define rwlock_destroy(A) pthread_rwlock_destroy(A)
588 #elif defined(HAVE_RWLOCK_INIT)
589 #ifdef HAVE_RWLOCK_T /* For example Solaris 2.6-> */
590 #define rw_lock_t rwlock_t
591 #endif
592 #define my_rwlock_init(A,B) rwlock_init((A),USYNC_THREAD,0)
593 #else
594 /* Use our own version of read/write locks */
595 #define NEED_MY_RW_LOCK 1
596 #define rw_lock_t my_rw_lock_t
597 #define my_rwlock_init(A,B) my_rw_init((A))
598 #define rw_rdlock(A) my_rw_rdlock((A))
599 #define rw_wrlock(A) my_rw_wrlock((A))
600 #define rw_tryrdlock(A) my_rw_tryrdlock((A))
601 #define rw_trywrlock(A) my_rw_trywrlock((A))
602 #define rw_unlock(A) my_rw_unlock((A))
603 #define rwlock_destroy(A) my_rw_destroy((A))
604 #define rw_lock_assert_write_owner(A) my_rw_lock_assert_write_owner((A))
605 #define rw_lock_assert_not_write_owner(A) my_rw_lock_assert_not_write_owner((A))
606 #endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */
607 
608 
640 typedef struct st_rw_pr_lock_t {
645  pthread_mutex_t lock;
650  pthread_cond_t no_active_readers;
656  my_bool active_writer;
657 #ifdef SAFE_MUTEX
658 
659  pthread_t writer_thread;
660 #endif
661 } rw_pr_lock_t;
662 
663 extern int rw_pr_init(rw_pr_lock_t *);
664 extern int rw_pr_rdlock(rw_pr_lock_t *);
665 extern int rw_pr_wrlock(rw_pr_lock_t *);
666 extern int rw_pr_unlock(rw_pr_lock_t *);
667 extern int rw_pr_destroy(rw_pr_lock_t *);
668 #ifdef SAFE_MUTEX
669 #define rw_pr_lock_assert_write_owner(A) \
670  DBUG_ASSERT((A)->active_writer && pthread_equal(pthread_self(), \
671  (A)->writer_thread))
672 #define rw_pr_lock_assert_not_write_owner(A) \
673  DBUG_ASSERT(! (A)->active_writer || ! pthread_equal(pthread_self(), \
674  (A)->writer_thread))
675 #else
676 #define rw_pr_lock_assert_write_owner(A)
677 #define rw_pr_lock_assert_not_write_owner(A)
678 #endif /* SAFE_MUTEX */
679 
680 
681 #ifdef NEED_MY_RW_LOCK
682 
683 #ifdef _WIN32
684 
694 typedef union
695 {
696  /* Native rwlock (is_srwlock == TRUE) */
697  struct
698  {
699  SRWLOCK srwlock; /* native reader writer lock */
700  BOOL have_exclusive_srwlock; /* used for unlock */
701  };
702 
703  /*
704  Portable implementation (is_srwlock == FALSE)
705  Fields are identical with Unix my_rw_lock_t fields.
706  */
707  struct
708  {
709  pthread_mutex_t lock; /* lock for structure */
710  pthread_cond_t readers; /* waiting readers */
711  pthread_cond_t writers; /* waiting writers */
712  int state; /* -1:writer,0:free,>0:readers */
713  int waiters; /* number of waiting writers */
714 #ifdef SAFE_MUTEX
715  pthread_t write_thread;
716 #endif
717  };
718 } my_rw_lock_t;
719 
720 
721 #else /* _WIN32 */
722 
723 /*
724  On systems which don't support native read/write locks we have
725  to use own implementation.
726 */
727 typedef struct st_my_rw_lock_t {
728  pthread_mutex_t lock; /* lock for structure */
729  pthread_cond_t readers; /* waiting readers */
730  pthread_cond_t writers; /* waiting writers */
731  int state; /* -1:writer,0:free,>0:readers */
732  int waiters; /* number of waiting writers */
733 #ifdef SAFE_MUTEX
734  pthread_t write_thread;
735 #endif
736 } my_rw_lock_t;
737 
738 #endif
740 extern int my_rw_init(my_rw_lock_t *);
741 extern int my_rw_destroy(my_rw_lock_t *);
742 extern int my_rw_rdlock(my_rw_lock_t *);
743 extern int my_rw_wrlock(my_rw_lock_t *);
744 extern int my_rw_unlock(my_rw_lock_t *);
745 extern int my_rw_tryrdlock(my_rw_lock_t *);
746 extern int my_rw_trywrlock(my_rw_lock_t *);
747 #ifdef SAFE_MUTEX
748 #define my_rw_lock_assert_write_owner(A) \
749  DBUG_ASSERT((A)->state == -1 && pthread_equal(pthread_self(), \
750  (A)->write_thread))
751 #define my_rw_lock_assert_not_write_owner(A) \
752  DBUG_ASSERT((A)->state >= 0 || ! pthread_equal(pthread_self(), \
753  (A)->write_thread))
754 #else
755 #define my_rw_lock_assert_write_owner(A)
756 #define my_rw_lock_assert_not_write_owner(A)
757 #endif
758 #endif /* NEED_MY_RW_LOCK */
759 
760 
761 #define GETHOSTBYADDR_BUFF_SIZE 2048
762 
763 #ifndef HAVE_THR_SETCONCURRENCY
764 #define thr_setconcurrency(A) pthread_dummy(0)
765 #endif
766 #if !defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && ! defined(pthread_attr_setstacksize)
767 #define pthread_attr_setstacksize(A,B) pthread_dummy(0)
768 #endif
769 
770 /* Define mutex types, see my_thr_init.c */
771 #define MY_MUTEX_INIT_SLOW NULL
772 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
773 extern pthread_mutexattr_t my_fast_mutexattr;
774 #define MY_MUTEX_INIT_FAST &my_fast_mutexattr
775 #else
776 #define MY_MUTEX_INIT_FAST NULL
777 #endif
778 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
779 extern pthread_mutexattr_t my_errorcheck_mutexattr;
780 #define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr
781 #else
782 #define MY_MUTEX_INIT_ERRCHK NULL
783 #endif
784 
785 #ifndef ESRCH
786 /* Define it to something */
787 #define ESRCH 1
788 #endif
789 
790 typedef ulong my_thread_id;
791 
792 extern my_bool my_thread_global_init(void);
793 extern void my_thread_global_reinit(void);
794 extern void my_thread_global_end(void);
795 extern my_bool my_thread_init(void);
796 extern void my_thread_end(void);
797 extern const char *my_thread_name(void);
798 extern my_thread_id my_thread_dbug_id(void);
799 extern int pthread_dummy(int);
800 
801 #ifndef HAVE_PTHREAD_ATTR_GETGUARDSIZE
802 static inline int pthread_attr_getguardsize(pthread_attr_t *attr,
803  size_t *guardsize)
804 {
805  *guardsize= 0;
806  return 0;
807 }
808 #endif
809 
810 /* All thread specific variables are in the following struct */
811 
812 #define THREAD_NAME_SIZE 10
813 #ifndef DEFAULT_THREAD_STACK
814 #if SIZEOF_CHARP > 4
815 /*
816  MySQL can survive with 32K, but some glibc libraries require > 128K stack
817  To resolve hostnames. Also recursive stored procedures needs stack.
818 */
819 #define DEFAULT_THREAD_STACK (256*1024L)
820 #else
821 #define DEFAULT_THREAD_STACK (192*1024)
822 #endif
823 #endif
824 
825 #include <mysql/psi/mysql_thread.h>
826 
827 #define INSTRUMENT_ME 0
828 
830 {
831  int thr_errno;
832  mysql_cond_t suspend;
833  mysql_mutex_t mutex;
834  mysql_mutex_t * volatile current_mutex;
835  mysql_cond_t * volatile current_cond;
836  pthread_t pthread_self;
837  my_thread_id id;
838  int cmp_length;
839  int volatile abort;
840  my_bool init;
841  struct st_my_thread_var *next,**prev;
842  void *opt_info;
843  void *stack_ends_here;
844 #ifndef DBUG_OFF
845  void *dbug;
846  char name[THREAD_NAME_SIZE+1];
847 #endif
848 };
849 
850 extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
851 extern int set_mysys_var(struct st_my_thread_var *mysys_var);
852 extern void **my_thread_var_dbug();
853 extern uint my_thread_end_wait_time;
854 #define my_thread_var (_my_thread_var())
855 #define my_errno my_thread_var->thr_errno
856 /*
857  Keep track of shutdown,signal, and main threads so that my_end() will not
858  report errors with them
859 */
860 
861 /* Which kind of thread library is in use */
862 
863 #define THD_LIB_OTHER 1
864 #define THD_LIB_NPTL 2
865 #define THD_LIB_LT 4
866 
867 extern uint thd_lib_detected;
868 
869 /*
870  thread_safe_xxx functions are for critical statistic or counters.
871  The implementation is guaranteed to be thread safe, on all platforms.
872  Note that the calling code should *not* assume the counter is protected
873  by the mutex given, as the implementation of these helpers may change
874  to use my_atomic operations instead.
875 */
876 
877 #ifndef thread_safe_increment
878 #ifdef _WIN32
879 #define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V))
880 #define thread_safe_decrement(V,L) InterlockedDecrement((long*) &(V))
881 #else
882 #define thread_safe_increment(V,L) \
883  (mysql_mutex_lock((L)), (V)++, mysql_mutex_unlock((L)))
884 #define thread_safe_decrement(V,L) \
885  (mysql_mutex_lock((L)), (V)--, mysql_mutex_unlock((L)))
886 #endif
887 #endif
888 
889 #ifndef thread_safe_add
890 #ifdef _WIN32
891 #define thread_safe_add(V,C,L) InterlockedExchangeAdd((long*) &(V),(C))
892 #define thread_safe_sub(V,C,L) InterlockedExchangeAdd((long*) &(V),-(long) (C))
893 #else
894 #define thread_safe_add(V,C,L) \
895  (mysql_mutex_lock((L)), (V)+=(C), mysql_mutex_unlock((L)))
896 #define thread_safe_sub(V,C,L) \
897  (mysql_mutex_lock((L)), (V)-=(C), mysql_mutex_unlock((L)))
898 #endif
899 #endif
900 
901 
902 /*
903  statistics_xxx functions are for non critical statistic,
904  maintained in global variables.
905  When compiling with SAFE_STATISTICS:
906  - race conditions can not occur.
907  - some locking occurs, which may cause performance degradation.
908 
909  When compiling without SAFE_STATISTICS:
910  - race conditions can occur, making the result slightly inaccurate.
911  - the lock given is not honored.
912 */
913 #ifdef SAFE_STATISTICS
914 #define statistic_increment(V,L) thread_safe_increment((V),(L))
915 #define statistic_decrement(V,L) thread_safe_decrement((V),(L))
916 #define statistic_add(V,C,L) thread_safe_add((V),(C),(L))
917 #define statistic_sub(V,C,L) thread_safe_sub((V),(C),(L))
918 #else
919 #define statistic_decrement(V,L) (V)--
920 #define statistic_increment(V,L) (V)++
921 #define statistic_add(V,C,L) (V)+=(C)
922 #define statistic_sub(V,C,L) (V)-=(C)
923 #endif /* SAFE_STATISTICS */
924 
925 /*
926  No locking needed, the counter is owned by the thread
927 */
928 #define status_var_increment(V) (V)++
929 #define status_var_decrement(V) (V)--
930 #define status_var_add(V,C) (V)+=(C)
931 #define status_var_sub(V,C) (V)-=(C)
932 
933 #ifdef __cplusplus
934 }
935 #endif
936 #endif /* _my_ptread_h */