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