root/trunk/dep/include/mysql/my_pthread.h @ 2

Revision 2, 26.8 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

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