root/src/mysql/my_pthread.h @ 9

Revision 1, 25.3 kB (checked in by jinshiro, 17 years ago)
Line 
1/* Copyright (C) 2000 MySQL AB
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; either version 2 of the License, or
6   (at your option) any later version.
7
8   This program is distributed in the hope that it will be useful,
9   but WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   GNU General Public License for more details.
12
13   You should have received a copy of the GNU General Public License
14   along with this program; if not, write to the Free Software
15   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
16
17/* Defines to make different thread packages compatible */
18
19#ifndef _my_pthread_h
20#define _my_pthread_h
21
22#include <errno.h>
23#ifndef ETIME
24#define ETIME ETIMEDOUT                         /* For FreeBSD */
25#endif
26
27#ifdef  __cplusplus
28#define EXTERNC extern "C"
29extern "C" {
30#else
31#define EXTERNC
32#endif /* __cplusplus */ 
33
34#if defined(__WIN__) || defined(OS2)
35
36#ifdef OS2
37typedef ULONG     HANDLE;
38typedef ULONG     DWORD;
39typedef int sigset_t;
40#endif
41
42#ifdef OS2
43typedef HMTX             pthread_mutex_t;
44#else
45typedef CRITICAL_SECTION pthread_mutex_t;
46#endif
47typedef HANDLE           pthread_t;
48typedef struct thread_attr {
49    DWORD dwStackSize ;
50    DWORD dwCreatingFlag ;
51    int priority ;
52} pthread_attr_t ;
53
54typedef struct { int dummy; } pthread_condattr_t;
55
56/* Implementation of posix conditions */
57
58typedef struct st_pthread_link {
59  DWORD thread_id;
60  struct st_pthread_link *next;
61} pthread_link;
62
63typedef struct {
64  uint32 waiting;
65#ifdef OS2
66  HEV    semaphore;
67#else
68  HANDLE semaphore;
69#endif
70} pthread_cond_t;
71
72
73#ifndef OS2
74struct timespec {               /* For pthread_cond_timedwait() */
75    time_t tv_sec;
76    long tv_nsec;
77};
78#endif
79
80typedef int pthread_mutexattr_t;
81#define win_pthread_self my_thread_var->pthread_self
82#ifdef OS2
83#define pthread_handler_t EXTERNC void * _Optlink
84typedef void * (_Optlink *pthread_handler)(void *);
85#else
86#define pthread_handler_t EXTERNC void * __cdecl
87typedef void * (__cdecl *pthread_handler)(void *);
88#endif
89
90void win_pthread_init(void);
91int win_pthread_setspecific(void *A,void *B,uint length);
92int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *);
93int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
94int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
95int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
96                           struct timespec *abstime);
97int pthread_cond_signal(pthread_cond_t *cond);
98int pthread_cond_broadcast(pthread_cond_t *cond);
99int pthread_cond_destroy(pthread_cond_t *cond);
100int pthread_attr_init(pthread_attr_t *connect_att);
101int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack);
102int pthread_attr_setprio(pthread_attr_t *connect_att,int priority);
103int pthread_attr_destroy(pthread_attr_t *connect_att);
104struct tm *localtime_r(const time_t *timep,struct tm *tmp);
105struct tm *gmtime_r(const time_t *timep,struct tm *tmp);
106
107
108void pthread_exit(void *a);      /* was #define pthread_exit(A) ExitThread(A)*/
109
110#ifndef OS2
111#define ETIMEDOUT 145               /* Win32 doesn't have this */
112#define getpid() GetCurrentThreadId()
113#endif
114#define pthread_self() win_pthread_self
115#define HAVE_LOCALTIME_R                1
116#define _REENTRANT                      1
117#define HAVE_PTHREAD_ATTR_SETSTACKSIZE  1
118
119#ifdef USE_TLS                                  /* For LIBMYSQL.DLL */
120#undef SAFE_MUTEX                               /* This will cause conflicts */
121#define pthread_key(T,V)  DWORD V
122#define pthread_key_create(A,B) ((*A=TlsAlloc())==0xFFFFFFFF)
123#define pthread_key_delete(A) TlsFree(A)
124#define pthread_getspecific(A) (TlsGetValue(A))
125#define my_pthread_getspecific(T,A) ((T) TlsGetValue(A))
126#define my_pthread_getspecific_ptr(T,V) ((T) TlsGetValue(V))
127#define my_pthread_setspecific_ptr(T,V) (!TlsSetValue((T),(V)))
128#define pthread_setspecific(A,B) (!TlsSetValue((A),(B)))
129#else
130#define pthread_key(T,V) __declspec(thread) T V
131#define pthread_key_create(A,B) pthread_dummy(0)
132#define pthread_key_delete(A) pthread_dummy(0)
133#define pthread_getspecific(A) (&(A))
134#define my_pthread_getspecific(T,A) (&(A))
135#define my_pthread_getspecific_ptr(T,V) (V)
136#define my_pthread_setspecific_ptr(T,V) ((T)=(V),0)
137#define pthread_setspecific(A,B) win_pthread_setspecific(&(A),(B),sizeof(A))
138#endif /* USE_TLS */
139
140#define pthread_equal(A,B) ((A) == (B))
141#ifdef OS2
142extern int pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *);
143extern int pthread_mutex_lock (pthread_mutex_t *);
144extern int pthread_mutex_unlock (pthread_mutex_t *);
145extern int pthread_mutex_destroy (pthread_mutex_t *);
146#define my_pthread_setprio(A,B)  DosSetPriority(PRTYS_THREAD,PRTYC_NOCHANGE, B, A)
147#define pthread_kill(A,B) raise(B)
148#define pthread_exit(A) pthread_dummy()
149#else
150#define pthread_mutex_init(A,B)  (InitializeCriticalSection(A),0)
151#define pthread_mutex_lock(A)    (EnterCriticalSection(A),0)
152#define pthread_mutex_trylock(A) (WaitForSingleObject((A), 0) == WAIT_TIMEOUT)
153#define pthread_mutex_unlock(A)  LeaveCriticalSection(A)
154#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
155#define my_pthread_setprio(A,B)  SetThreadPriority(GetCurrentThread(), (B))
156#define pthread_kill(A,B) pthread_dummy(0)
157#endif /* OS2 */
158
159/* Dummy defines for easier code */
160#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
161#define my_pthread_attr_setprio(A,B) pthread_attr_setprio(A,B)
162#define pthread_attr_setscope(A,B)
163#define pthread_detach_this_thread()
164#define pthread_condattr_init(A)
165#define pthread_condattr_destroy(A)
166
167/*Irena: compiler does not like this: */
168/*#define my_pthread_getprio(pthread_t thread_id) pthread_dummy(0) */
169#define my_pthread_getprio(thread_id) pthread_dummy(0)
170
171#elif defined(HAVE_UNIXWARE7_THREADS)
172
173#include <thread.h>
174#include <synch.h>
175
176#ifndef _REENTRANT
177#define _REENTRANT
178#endif
179
180#define HAVE_NONPOSIX_SIGWAIT
181#define pthread_t thread_t
182#define pthread_cond_t cond_t
183#define pthread_mutex_t mutex_t
184#define pthread_key_t thread_key_t
185typedef int pthread_attr_t;                     /* Needed by Unixware 7.0.0 */
186
187#define pthread_key_create(A,B) thr_keycreate((A),(B))
188#define pthread_key_delete(A) thr_keydelete(A)
189
190#define pthread_handler_t EXTERNC void *
191#define pthread_key(T,V) pthread_key_t V
192
193void *  my_pthread_getspecific_imp(pthread_key_t key);
194#define my_pthread_getspecific(A,B) ((A) my_pthread_getspecific_imp(B))
195#define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,V)
196
197#define pthread_setspecific(A,B) thr_setspecific(A,B)
198#define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,V)
199
200#define pthread_create(A,B,C,D) thr_create(NULL,65536L,(C),(D),THR_DETACHED,(A))
201#define pthread_cond_init(a,b) cond_init((a),USYNC_THREAD,NULL)
202#define pthread_cond_destroy(a) cond_destroy(a)
203#define pthread_cond_signal(a) cond_signal(a)
204#define pthread_cond_wait(a,b) cond_wait((a),(b))
205#define pthread_cond_timedwait(a,b,c) cond_timedwait((a),(b),(c))
206#define pthread_cond_broadcast(a) cond_broadcast(a)
207
208#define pthread_mutex_init(a,b) mutex_init((a),USYNC_THREAD,NULL)
209#define pthread_mutex_lock(a) mutex_lock(a)
210#define pthread_mutex_unlock(a) mutex_unlock(a)
211#define pthread_mutex_destroy(a) mutex_destroy(a)
212
213#define pthread_self() thr_self()
214#define pthread_exit(A) thr_exit(A)
215#define pthread_equal(A,B) (((A) == (B)) ? 1 : 0)
216#define pthread_kill(A,B) thr_kill((A),(B))
217#define HAVE_PTHREAD_KILL
218
219#define pthread_sigmask(A,B,C) thr_sigsetmask((A),(B),(C))
220
221extern int my_sigwait(const sigset_t *set,int *sig);
222
223#define pthread_detach_this_thread() pthread_dummy(0)
224
225#define pthread_attr_init(A) pthread_dummy(0)
226#define pthread_attr_destroy(A) pthread_dummy(0)
227#define pthread_attr_setscope(A,B) pthread_dummy(0)
228#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
229#define my_pthread_setprio(A,B) pthread_dummy (0)
230#define my_pthread_getprio(A) pthread_dummy (0)
231#define my_pthread_attr_setprio(A,B) pthread_dummy(0)
232
233#else /* Normal threads */
234
235#ifdef HAVE_rts_threads
236#define sigwait org_sigwait
237#include <signal.h>
238#undef sigwait
239#endif
240#include <pthread.h>
241#ifndef _REENTRANT
242#define _REENTRANT
243#endif
244#ifdef HAVE_THR_SETCONCURRENCY
245#include <thread.h>                     /* Probably solaris */
246#endif
247#ifdef HAVE_SCHED_H
248#include <sched.h>
249#endif
250#ifdef HAVE_SYNCH_H
251#include <synch.h>
252#endif
253#if defined(__EMX__) && (!defined(EMX_PTHREAD_REV) || (EMX_PTHREAD_REV < 2))
254#error Requires at least rev 2 of EMX pthreads library.
255#endif
256
257#ifdef __NETWARE__
258void my_pthread_exit(void *status);
259#define pthread_exit(A) my_pthread_exit(A)
260#endif
261
262extern int my_pthread_getprio(pthread_t thread_id);
263
264#define pthread_key(T,V) pthread_key_t V
265#define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,(V))
266#define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,(void*) (V))
267#define pthread_detach_this_thread()
268#define pthread_handler_t EXTERNC void *
269typedef void *(* pthread_handler)(void *);
270
271/* Test first for RTS or FSU threads */
272
273#if defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM)
274#define HAVE_rts_threads
275extern int my_pthread_create_detached;
276#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
277#define PTHREAD_CREATE_DETACHED &my_pthread_create_detached
278#define PTHREAD_SCOPE_SYSTEM  PTHREAD_SCOPE_GLOBAL
279#define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_LOCAL
280#define USE_ALARM_THREAD
281#elif defined(HAVE_mit_thread)
282#define USE_ALARM_THREAD
283#undef  HAVE_LOCALTIME_R
284#define HAVE_LOCALTIME_R
285#undef  HAVE_GMTIME_R
286#define HAVE_GMTIME_R
287#undef  HAVE_PTHREAD_ATTR_SETSCOPE
288#define HAVE_PTHREAD_ATTR_SETSCOPE
289#undef HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE        /* If we are running linux */
290#undef HAVE_RWLOCK_T
291#undef HAVE_RWLOCK_INIT
292#undef HAVE_PTHREAD_RWLOCK_RDLOCK
293#undef HAVE_SNPRINTF
294
295#define my_pthread_attr_setprio(A,B)
296#endif /* defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) */
297
298#if defined(_BSDI_VERSION) && _BSDI_VERSION < 199910
299int sigwait(sigset_t *set, int *sig);
300#endif
301
302#ifndef HAVE_NONPOSIX_SIGWAIT
303#define my_sigwait(A,B) sigwait((A),(B))
304#else
305int my_sigwait(const sigset_t *set,int *sig);
306#endif
307
308#ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT
309#ifndef SAFE_MUTEX
310#define pthread_mutex_init(a,b) my_pthread_mutex_init((a),(b))
311extern int my_pthread_mutex_init(pthread_mutex_t *mp,
312                                 const pthread_mutexattr_t *attr);
313#endif /* SAFE_MUTEX */
314#define pthread_cond_init(a,b) my_pthread_cond_init((a),(b))
315extern int my_pthread_cond_init(pthread_cond_t *mp,
316                                const pthread_condattr_t *attr);
317#endif /* HAVE_NONPOSIX_PTHREAD_MUTEX_INIT */
318
319#if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK)
320#define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C))
321#endif
322
323#if !defined(HAVE_SIGWAIT) && !defined(HAVE_mit_thread) && !defined(HAVE_rts_threads) && !defined(sigwait) && !defined(alpha_linux_port) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS) && !defined(_AIX)
324int sigwait(sigset_t *setp, int *sigp);         /* Use our implemention */
325#endif
326
327
328/*
329  We define my_sigset() and use that instead of the system sigset() so that
330  we can favor an implementation based on sigaction(). On some systems, such
331  as Mac OS X, sigset() results in flags such as SA_RESTART being set, and
332  we want to make sure that no such flags are set.
333*/
334#if defined(HAVE_SIGACTION) && !defined(my_sigset)
335#define my_sigset(A,B) do { struct sigaction s; sigset_t set;              \
336                            sigemptyset(&set);                             \
337                            s.sa_handler = (B);                            \
338                            s.sa_mask    = set;                            \
339                            s.sa_flags   = 0;                              \
340                            sigaction((A), &s, (struct sigaction *) NULL); \
341                          } while (0)
342#elif defined(HAVE_SIGSET) && !defined(my_sigset)
343#define my_sigset(A,B) sigset((A),(B))
344#elif !defined(my_sigset)
345#define my_sigset(A,B) signal((A),(B))
346#endif
347
348#ifndef my_pthread_setprio
349#if defined(HAVE_PTHREAD_SETPRIO_NP)            /* FSU threads */
350#define my_pthread_setprio(A,B) pthread_setprio_np((A),(B))
351#elif defined(HAVE_PTHREAD_SETPRIO)
352#define my_pthread_setprio(A,B) pthread_setprio((A),(B))
353#else
354extern void my_pthread_setprio(pthread_t thread_id,int prior);
355#endif
356#endif
357
358#ifndef my_pthread_attr_setprio
359#ifdef HAVE_PTHREAD_ATTR_SETPRIO
360#define my_pthread_attr_setprio(A,B) pthread_attr_setprio((A),(B))
361#else
362extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority);
363#endif
364#endif
365
366#if !defined(HAVE_PTHREAD_ATTR_SETSCOPE) || defined(HAVE_DEC_3_2_THREADS)
367#define pthread_attr_setscope(A,B)
368#undef  HAVE_GETHOSTBYADDR_R                    /* No definition */
369#endif
370
371#if defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT) && !defined(SAFE_MUTEX)
372extern int my_pthread_cond_timedwait(pthread_cond_t *cond,
373                                     pthread_mutex_t *mutex,
374                                     struct timespec *abstime);
375#define pthread_cond_timedwait(A,B,C) my_pthread_cond_timedwait((A),(B),(C))
376#endif
377
378#if defined(OS2)
379#define my_pthread_getspecific(T,A) ((T) &(A))
380#define pthread_setspecific(A,B) win_pthread_setspecific(&(A),(B),sizeof(A))
381#elif !defined( HAVE_NONPOSIX_PTHREAD_GETSPECIFIC)
382#define my_pthread_getspecific(A,B) ((A) pthread_getspecific(B))
383#else
384#define my_pthread_getspecific(A,B) ((A) my_pthread_getspecific_imp(B))
385void *my_pthread_getspecific_imp(pthread_key_t key);
386#endif /* OS2 */
387
388#ifndef HAVE_LOCALTIME_R
389struct tm *localtime_r(const time_t *clock, struct tm *res);
390#endif
391
392#ifndef HAVE_GMTIME_R
393struct tm *gmtime_r(const time_t *clock, struct tm *res);
394#endif
395
396#ifdef HAVE_PTHREAD_CONDATTR_CREATE
397/* DCE threads on HPUX 10.20 */
398#define pthread_condattr_init pthread_condattr_create
399#define pthread_condattr_destroy pthread_condattr_delete
400#endif
401
402/* FSU THREADS */
403#if !defined(HAVE_PTHREAD_KEY_DELETE) && !defined(pthread_key_delete)
404#define pthread_key_delete(A) pthread_dummy(0)
405#endif
406
407#ifdef HAVE_CTHREADS_WRAPPER                    /* For MacOSX */
408#define pthread_cond_destroy(A) pthread_dummy(0)
409#define pthread_mutex_destroy(A) pthread_dummy(0)
410#define pthread_attr_delete(A) pthread_dummy(0)
411#define pthread_condattr_delete(A) pthread_dummy(0)
412#define pthread_attr_setstacksize(A,B) pthread_dummy(0)
413#define pthread_equal(A,B) ((A) == (B))
414#define pthread_cond_timedwait(a,b,c) pthread_cond_wait((a),(b))
415#define pthread_attr_init(A) pthread_attr_create(A)
416#define pthread_attr_destroy(A) pthread_attr_delete(A)
417#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
418#define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D))
419#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
420#define pthread_kill(A,B) pthread_dummy(0)
421#undef  pthread_detach_this_thread
422#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); }
423#endif
424
425#ifdef HAVE_DARWIN5_THREADS
426#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
427#define pthread_kill(A,B) pthread_dummy(0)
428#define pthread_condattr_init(A) pthread_dummy(0)
429#define pthread_condattr_destroy(A) pthread_dummy(0)
430#undef  pthread_detach_this_thread
431#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(tmp); }
432#endif
433
434#if ((defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT)) || defined(HAVE_DEC_3_2_THREADS)) && !defined(HAVE_CTHREADS_WRAPPER)
435/* This is set on AIX_3_2 and Siemens unix (and DEC OSF/1 3.2 too) */
436#define pthread_key_create(A,B) \
437                pthread_keycreate(A,(B) ?\
438                                  (pthread_destructor_t) (B) :\
439                                  (pthread_destructor_t) pthread_dummy)
440#define pthread_attr_init(A) pthread_attr_create(A)
441#define pthread_attr_destroy(A) pthread_attr_delete(A)
442#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
443#define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D))
444#ifndef pthread_sigmask
445#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
446#endif
447#define pthread_kill(A,B) pthread_dummy(0)
448#undef  pthread_detach_this_thread
449#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); }
450#elif !defined(__NETWARE__) /* HAVE_PTHREAD_ATTR_CREATE && !HAVE_SIGWAIT */
451#define HAVE_PTHREAD_KILL
452#endif
453
454#endif /* defined(__WIN__) */
455
456#if defined(HPUX10) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS)
457#undef pthread_cond_timedwait
458#define pthread_cond_timedwait(a,b,c) my_pthread_cond_timedwait((a),(b),(c))
459int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
460                              struct timespec *abstime);
461#endif
462
463#if defined(HPUX10)
464#define pthread_attr_getstacksize(A,B) my_pthread_attr_getstacksize(A,B)
465void my_pthread_attr_getstacksize(pthread_attr_t *attrib, size_t *size);
466#endif
467
468#if defined(HAVE_POSIX1003_4a_MUTEX) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS)
469#undef pthread_mutex_trylock
470#define pthread_mutex_trylock(a) my_pthread_mutex_trylock((a))
471int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
472#endif
473
474        /* safe_mutex adds checking to mutex for easier debugging */
475
476#if defined(__NETWARE__) && !defined(SAFE_MUTEX_DETECT_DESTROY)
477#define SAFE_MUTEX_DETECT_DESTROY
478#endif
479
480typedef struct st_safe_mutex_t
481{
482  pthread_mutex_t global,mutex;
483  const char *file;
484  uint line,count;
485  pthread_t thread;
486#ifdef SAFE_MUTEX_DETECT_DESTROY
487  struct st_safe_mutex_info_t *info;    /* to track destroying of mutexes */
488#endif
489} safe_mutex_t;
490
491#ifdef SAFE_MUTEX_DETECT_DESTROY
492/*
493  Used to track the destroying of mutexes. This needs to be a seperate
494  structure because the safe_mutex_t structure could be freed before
495  the mutexes are destroyed.
496*/
497
498typedef struct st_safe_mutex_info_t
499{
500  struct st_safe_mutex_info_t *next;
501  struct st_safe_mutex_info_t *prev;
502  const char *init_file;
503  uint32 init_line;
504} safe_mutex_info_t;
505#endif /* SAFE_MUTEX_DETECT_DESTROY */
506
507int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr,
508                    const char *file, uint line);
509int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line);
510int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line);
511int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line);
512int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file,
513                   uint line);
514int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
515                        struct timespec *abstime, const char *file, uint line);
516void safe_mutex_global_init(void);
517void safe_mutex_end(FILE *file);
518
519        /* Wrappers if safe mutex is actually used */
520#ifdef SAFE_MUTEX
521#undef pthread_mutex_init
522#undef pthread_mutex_lock
523#undef pthread_mutex_unlock
524#undef pthread_mutex_destroy
525#undef pthread_mutex_wait
526#undef pthread_mutex_timedwait
527#undef pthread_mutex_t
528#undef pthread_cond_wait
529#undef pthread_cond_timedwait
530#undef pthread_mutex_trylock
531#define pthread_mutex_init(A,B) safe_mutex_init((A),(B),__FILE__,__LINE__)
532#define pthread_mutex_lock(A) safe_mutex_lock((A),__FILE__,__LINE__)
533#define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__)
534#define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__)
535#define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__)
536#define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__)
537#define pthread_mutex_trylock(A) pthread_mutex_lock(A)
538#define pthread_mutex_t safe_mutex_t
539#define safe_mutex_assert_owner(mp) \
540          DBUG_ASSERT((mp)->count > 0 && \
541                      pthread_equal(pthread_self(), (mp)->thread))
542#define safe_mutex_assert_not_owner(mp) \
543          DBUG_ASSERT(! (mp)->count || \
544                      ! pthread_equal(pthread_self(), (mp)->thread))
545#else
546#define safe_mutex_assert_owner(mp)
547#define safe_mutex_assert_not_owner(mp)
548#endif /* SAFE_MUTEX */
549
550        /* READ-WRITE thread locking */
551
552#ifdef HAVE_BROKEN_RWLOCK                       /* For OpenUnix */
553#undef HAVE_PTHREAD_RWLOCK_RDLOCK
554#undef HAVE_RWLOCK_INIT
555#undef HAVE_RWLOCK_T
556#endif
557
558#if defined(USE_MUTEX_INSTEAD_OF_RW_LOCKS)
559/* use these defs for simple mutex locking */
560#define rw_lock_t pthread_mutex_t
561#define my_rwlock_init(A,B) pthread_mutex_init((A),(B))
562#define rw_rdlock(A) pthread_mutex_lock((A))
563#define rw_wrlock(A) pthread_mutex_lock((A))
564#define rw_tryrdlock(A) pthread_mutex_trylock((A))
565#define rw_trywrlock(A) pthread_mutex_trylock((A))
566#define rw_unlock(A) pthread_mutex_unlock((A))
567#define rwlock_destroy(A) pthread_mutex_destroy((A))
568#elif defined(HAVE_PTHREAD_RWLOCK_RDLOCK)
569#define rw_lock_t pthread_rwlock_t
570#define my_rwlock_init(A,B) pthread_rwlock_init((A),(B))
571#define rw_rdlock(A) pthread_rwlock_rdlock(A)
572#define rw_wrlock(A) pthread_rwlock_wrlock(A)
573#define rw_tryrdlock(A) pthread_rwlock_tryrdlock((A))
574#define rw_trywrlock(A) pthread_rwlock_trywrlock((A))
575#define rw_unlock(A) pthread_rwlock_unlock(A)
576#define rwlock_destroy(A) pthread_rwlock_destroy(A)
577#elif defined(HAVE_RWLOCK_INIT)
578#ifdef HAVE_RWLOCK_T                            /* For example Solaris 2.6-> */
579#define rw_lock_t rwlock_t
580#endif
581#define my_rwlock_init(A,B) rwlock_init((A),USYNC_THREAD,0)
582#else
583/* Use our own version of read/write locks */
584typedef struct _my_rw_lock_t {
585        pthread_mutex_t lock;           /* lock for structure           */
586        pthread_cond_t  readers;        /* waiting readers              */
587        pthread_cond_t  writers;        /* waiting writers              */
588        int             state;          /* -1:writer,0:free,>0:readers  */
589        int             waiters;        /* number of waiting writers    */
590} my_rw_lock_t;
591
592#define rw_lock_t my_rw_lock_t
593#define rw_rdlock(A) my_rw_rdlock((A))
594#define rw_wrlock(A) my_rw_wrlock((A))
595#define rw_tryrdlock(A) my_rw_tryrdlock((A))
596#define rw_trywrlock(A) my_rw_trywrlock((A))
597#define rw_unlock(A) my_rw_unlock((A))
598#define rwlock_destroy(A) my_rwlock_destroy((A))
599
600extern int my_rwlock_init(my_rw_lock_t *, void *);
601extern int my_rwlock_destroy(my_rw_lock_t *);
602extern int my_rw_rdlock(my_rw_lock_t *);
603extern int my_rw_wrlock(my_rw_lock_t *);
604extern int my_rw_unlock(my_rw_lock_t *);
605extern int my_rw_tryrdlock(my_rw_lock_t *);
606extern int my_rw_trywrlock(my_rw_lock_t *);
607#endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */
608
609#define GETHOSTBYADDR_BUFF_SIZE 2048
610
611#ifndef HAVE_THR_SETCONCURRENCY
612#define thr_setconcurrency(A) pthread_dummy(0)
613#endif
614#if !defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && ! defined(pthread_attr_setstacksize)
615#define pthread_attr_setstacksize(A,B) pthread_dummy(0)
616#endif
617
618/* Define mutex types, see my_thr_init.c */
619#define MY_MUTEX_INIT_SLOW   NULL
620#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
621extern pthread_mutexattr_t my_fast_mutexattr;
622#define MY_MUTEX_INIT_FAST &my_fast_mutexattr
623#else
624#define MY_MUTEX_INIT_FAST   NULL
625#endif
626#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
627extern pthread_mutexattr_t my_errorcheck_mutexattr;
628#define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr
629#else
630#define MY_MUTEX_INIT_ERRCHK   NULL
631#endif
632
633extern my_bool my_thread_global_init(void);
634extern void my_thread_global_end(void);
635extern my_bool my_thread_init(void);
636extern void my_thread_end(void);
637extern const char *my_thread_name(void);
638extern long my_thread_id(void);
639extern int pthread_no_free(void *);
640extern int pthread_dummy(int);
641
642/* All thread specific variables are in the following struct */
643
644#define THREAD_NAME_SIZE 10
645#ifndef DEFAULT_THREAD_STACK
646#if SIZEOF_CHARP > 4
647/*
648  MySQL can survive with 32K, but some glibc libraries require > 128K stack
649  To resolve hostnames. Also recursive stored procedures needs stack.
650*/
651#define DEFAULT_THREAD_STACK    (256*1024L)
652#else
653#define DEFAULT_THREAD_STACK    (192*1024)
654#endif
655#endif
656
657struct st_my_thread_var
658{
659  int thr_errno;
660  pthread_cond_t suspend;
661  pthread_mutex_t mutex;
662  pthread_mutex_t * volatile current_mutex;
663  pthread_cond_t * volatile current_cond;
664  pthread_t pthread_self;
665  long id;
666  int cmp_length;
667  int volatile abort;
668  my_bool init;
669  struct st_my_thread_var *next,**prev;
670  void *opt_info;
671#ifndef DBUG_OFF
672  gptr dbug;
673  char name[THREAD_NAME_SIZE+1];
674#endif
675};
676
677extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
678#define my_thread_var (_my_thread_var())
679#define my_errno my_thread_var->thr_errno
680/*
681  Keep track of shutdown,signal, and main threads so that my_end() will not
682  report errors with them
683*/
684extern pthread_t shutdown_th, main_th, signal_th;
685
686        /* statistics_xxx functions are for not essential statistic */
687
688#ifndef thread_safe_increment
689#ifdef HAVE_ATOMIC_ADD
690#define thread_safe_increment(V,L) atomic_inc((atomic_t*) &V)
691#define thread_safe_decrement(V,L) atomic_dec((atomic_t*) &V)
692#define thread_safe_add(V,C,L)     atomic_add((C),(atomic_t*) &V)
693#define thread_safe_sub(V,C,L)     atomic_sub((C),(atomic_t*) &V)
694#else
695#define thread_safe_increment(V,L) \
696        (pthread_mutex_lock((L)), (V)++, pthread_mutex_unlock((L)))
697#define thread_safe_decrement(V,L) \
698        (pthread_mutex_lock((L)), (V)--, pthread_mutex_unlock((L)))
699#define thread_safe_add(V,C,L) (pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L)))
700#define thread_safe_sub(V,C,L) \
701        (pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L)))
702#endif /* HAVE_ATOMIC_ADD */
703#ifdef SAFE_STATISTICS
704#define statistic_increment(V,L)   thread_safe_increment((V),(L))
705#define statistic_decrement(V,L)   thread_safe_decrement((V),(L))
706#define statistic_add(V,C,L)       thread_safe_add((V),(C),(L))
707#else
708#define statistic_decrement(V,L) (V)--
709#define statistic_increment(V,L) (V)++
710#define statistic_add(V,C,L)     (V)+=(C)
711#endif /* SAFE_STATISTICS */
712#endif /* thread_safe_increment */
713
714#ifdef  __cplusplus
715}
716#endif
717#endif /* _my_ptread_h */
Note: See TracBrowser for help on using the browser.