| 1 | /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB | 
| 2 |                  2016 MariaDB Corporation AB | 
| 3 |     | 
| 4 |    This library is free software; you can redistribute it and/or | 
| 5 |    modify it under the terms of the GNU Library General Public | 
| 6 |    License as published by the Free Software Foundation; either | 
| 7 |    version 2 of the License, or (at your option) any later version. | 
| 8 |     | 
| 9 |    This library is distributed in the hope that it will be useful, | 
| 10 |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 11 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
| 12 |    Library General Public License for more details. | 
| 13 |     | 
| 14 |    You should have received a copy of the GNU Library General Public | 
| 15 |    License along with this library; if not, write to the Free | 
| 16 |    Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | 
| 17 |    MA 02111-1301, USA */ | 
| 18 |  | 
| 19 | /* Defines to make different thread packages compatible */ | 
| 20 |  | 
| 21 | #ifndef _my_pthread_h | 
| 22 | #define _my_pthread_h | 
| 23 |  | 
| 24 | #undef SAFE_MUTEX | 
| 25 |  | 
| 26 | #include <errno.h> | 
| 27 | #ifndef ETIME | 
| 28 | #define ETIME ETIMEDOUT				/* For FreeBSD */ | 
| 29 | #endif | 
| 30 |  | 
| 31 | #ifdef  __cplusplus | 
| 32 | extern "C"  { | 
| 33 | #endif /* __cplusplus */  | 
| 34 |  | 
| 35 | #if defined(_WIN32) | 
| 36 |  | 
| 37 | typedef CRITICAL_SECTION pthread_mutex_t; | 
| 38 |  | 
| 39 | typedef HANDLE		 pthread_t; | 
| 40 | typedef struct thread_attr { | 
| 41 |     DWORD dwStackSize ; | 
| 42 |     DWORD dwCreatingFlag ; | 
| 43 |     int priority ; | 
| 44 | } pthread_attr_t ; | 
| 45 |  | 
| 46 | typedef struct { int dummy; } pthread_condattr_t; | 
| 47 |  | 
| 48 | /* Implementation of posix conditions */ | 
| 49 |  | 
| 50 | typedef struct st_pthread_link { | 
| 51 |   DWORD thread_id; | 
| 52 |   struct st_pthread_link *next; | 
| 53 | } pthread_link; | 
| 54 |  | 
| 55 | typedef struct { | 
| 56 |   uint32 waiting; | 
| 57 |  | 
| 58 |   enum { | 
| 59 |     SIGNAL = 0, | 
| 60 |     BROADCAST = 1, | 
| 61 |     MAX_EVENTS = 2 | 
| 62 |   } EVENTS; | 
| 63 |   HANDLE events[MAX_EVENTS]; | 
| 64 |   CRITICAL_SECTION waiters_count_lock; | 
| 65 | } pthread_cond_t; | 
| 66 |  | 
| 67 | #ifndef _TIMESPEC_DEFINED | 
| 68 | #if (!defined(_MSC_VER) || _MSC_VER < 1900) | 
| 69 | struct timespec {		/* For pthread_cond_timedwait() */ | 
| 70 |     time_t tv_sec; | 
| 71 |     long tv_nsec; | 
| 72 | }; | 
| 73 | #endif | 
| 74 | #endif | 
| 75 |  | 
| 76 | typedef int pthread_mutexattr_t; | 
| 77 | #define pthread_self() GetCurrentThreadId() | 
| 78 |  | 
| 79 | #define pthread_handler_decl(A,B) void * __cdecl A(void *B) | 
| 80 | typedef void * (__cdecl *pthread_handler)(void *); | 
| 81 |  | 
| 82 | void win_pthread_init(void); | 
| 83 |  | 
| 84 | int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *); | 
| 85 | int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); | 
| 86 | int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); | 
| 87 | int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, | 
| 88 | 			   struct timespec *abstime); | 
| 89 | int pthread_cond_signal(pthread_cond_t *cond); | 
| 90 | int pthread_cond_broadcast(pthread_cond_t *cond); | 
| 91 | int pthread_cond_destroy(pthread_cond_t *cond); | 
| 92 | int pthread_attr_init(pthread_attr_t *connect_att); | 
| 93 | int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack); | 
| 94 | int pthread_attr_setprio(pthread_attr_t *connect_att,int priority); | 
| 95 | int pthread_attr_destroy(pthread_attr_t *connect_att); | 
| 96 | struct tm *localtime_r(const time_t *timep,struct tm *tmp); | 
| 97 |  | 
| 98 | void pthread_exit(void *a);	 /* was #define pthread_exit(A) ExitThread(A)*/ | 
| 99 |  | 
| 100 | #ifndef OS2 | 
| 101 | #define getpid() GetCurrentThreadId() | 
| 102 | #endif | 
| 103 |  | 
| 104 | #define HAVE_LOCALTIME_R		1 | 
| 105 | #define _REENTRANT			1 | 
| 106 | #define HAVE_PTHREAD_ATTR_SETSTACKSIZE	1 | 
| 107 |  | 
| 108 | #undef SAFE_MUTEX				/* This will cause conflicts */ | 
| 109 | #define pthread_key(T,V)  DWORD V | 
| 110 | #define pthread_key_create(A,B) ((*A=TlsAlloc())==0xFFFFFFFF) | 
| 111 | #define pthread_getspecific(A) (TlsGetValue(A)) | 
| 112 | #define my_pthread_getspecific(T,A) ((T) TlsGetValue(A)) | 
| 113 | #define my_pthread_getspecific_ptr(T,V) ((T) TlsGetValue(V)) | 
| 114 | #define my_pthread_setspecific_ptr(T,V) (!TlsSetValue((T),(V))) | 
| 115 | #define pthread_setspecific(A,B) (!TlsSetValue((A),(B))) | 
| 116 |  | 
| 117 |  | 
| 118 | #define pthread_equal(A,B) ((A) == (B)) | 
| 119 |  | 
| 120 | #define pthread_mutex_init(A,B)  InitializeCriticalSection(A) | 
| 121 | #define pthread_mutex_lock(A)	 (EnterCriticalSection(A),0) | 
| 122 | #define pthread_mutex_trylock(A) (WaitForSingleObject((A), 0) == WAIT_TIMEOUT) | 
| 123 | #define pthread_mutex_unlock(A)  LeaveCriticalSection(A) | 
| 124 | #define pthread_mutex_destroy(A) DeleteCriticalSection(A) | 
| 125 | #define my_pthread_setprio(A,B)  SetThreadPriority(GetCurrentThread(), (B)) | 
| 126 | #define pthread_kill(A,B) pthread_dummy(0) | 
| 127 |  | 
| 128 |  | 
| 129 | /* Dummy defines for easier code */ | 
| 130 | #define pthread_attr_setdetachstate(A,B) pthread_dummy(0) | 
| 131 | #define my_pthread_attr_setprio(A,B) pthread_attr_setprio(A,B) | 
| 132 | #define pthread_attr_setscope(A,B) | 
| 133 | #define pthread_detach_this_thread() | 
| 134 | #define pthread_condattr_init(A) | 
| 135 | #define pthread_condattr_destroy(A) | 
| 136 |  | 
| 137 | /*Irena: compiler does not like this: */ | 
| 138 | /*#define my_pthread_getprio(pthread_t thread_id) pthread_dummy(0) */ | 
| 139 | #define my_pthread_getprio(thread_id) pthread_dummy(0) | 
| 140 |  | 
| 141 | #elif defined(HAVE_UNIXWARE7_THREADS) | 
| 142 |  | 
| 143 | #include <thread.h> | 
| 144 | #include <synch.h> | 
| 145 |  | 
| 146 | #ifndef _REENTRANT | 
| 147 | #define _REENTRANT | 
| 148 | #endif | 
| 149 |  | 
| 150 | #define HAVE_NONPOSIX_SIGWAIT | 
| 151 | #define pthread_t thread_t | 
| 152 | #define pthread_cond_t cond_t | 
| 153 | #define pthread_mutex_t mutex_t | 
| 154 | #define pthread_key_t thread_key_t | 
| 155 | typedef int pthread_attr_t;			/* Needed by Unixware 7.0.0 */ | 
| 156 |  | 
| 157 | #define pthread_key_create(A,B) thr_keycreate((A),(B)) | 
| 158 |  | 
| 159 | #define pthread_handler_decl(A,B) void *A(void *B) | 
| 160 | #define pthread_key(T,V) pthread_key_t V | 
| 161 |  | 
| 162 | void *	my_pthread_getspecific_imp(pthread_key_t key); | 
| 163 | #define my_pthread_getspecific(A,B) ((A) my_pthread_getspecific_imp(B)) | 
| 164 | #define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,V) | 
| 165 |  | 
| 166 | #define pthread_setspecific(A,B) thr_setspecific(A,B) | 
| 167 | #define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,V) | 
| 168 |  | 
| 169 | #define pthread_create(A,B,C,D) thr_create(NULL,65536L,(C),(D),THR_DETACHED,(A)) | 
| 170 | #define pthread_cond_init(a,b) cond_init((a),USYNC_THREAD,NULL) | 
| 171 | #define pthread_cond_destroy(a) cond_destroy(a) | 
| 172 | #define pthread_cond_signal(a) cond_signal(a) | 
| 173 | #define pthread_cond_wait(a,b) cond_wait((a),(b)) | 
| 174 | #define pthread_cond_timedwait(a,b,c) cond_timedwait((a),(b),(c)) | 
| 175 | #define pthread_cond_broadcast(a) cond_broadcast(a) | 
| 176 |  | 
| 177 | #define pthread_mutex_init(a,b) mutex_init((a),USYNC_THREAD,NULL) | 
| 178 | #define pthread_mutex_lock(a) mutex_lock(a) | 
| 179 | #define pthread_mutex_unlock(a) mutex_unlock(a) | 
| 180 | #define pthread_mutex_destroy(a) mutex_destroy(a) | 
| 181 |  | 
| 182 | #define pthread_self() thr_self() | 
| 183 | #define pthread_exit(A) thr_exit(A) | 
| 184 | #define pthread_equal(A,B) (((A) == (B)) ? 1 : 0) | 
| 185 | #define pthread_kill(A,B) thr_kill((A),(B)) | 
| 186 | #define HAVE_PTHREAD_KILL | 
| 187 |  | 
| 188 | #define pthread_sigmask(A,B,C) thr_sigsetmask((A),(B),(C)) | 
| 189 |  | 
| 190 | extern int my_sigwait(const sigset_t *set,int *sig); | 
| 191 |  | 
| 192 | #define pthread_detach_this_thread() pthread_dummy(0) | 
| 193 |  | 
| 194 | #define pthread_attr_init(A) pthread_dummy(0) | 
| 195 | #define pthread_attr_destroy(A) pthread_dummy(0) | 
| 196 | #define pthread_attr_setscope(A,B) pthread_dummy(0) | 
| 197 | #define pthread_attr_setdetachstate(A,B) pthread_dummy(0) | 
| 198 | #define my_pthread_setprio(A,B) pthread_dummy (0) | 
| 199 | #define my_pthread_getprio(A) pthread_dummy (0) | 
| 200 | #define my_pthread_attr_setprio(A,B) pthread_dummy(0) | 
| 201 |  | 
| 202 | #else /* Normal threads */ | 
| 203 |  | 
| 204 | #ifdef HAVE_rts_threads | 
| 205 | #define sigwait org_sigwait | 
| 206 | #include <signal.h> | 
| 207 | #undef sigwait | 
| 208 | #endif | 
| 209 | #undef _REENTRANT			/* Fix if _REENTRANT is in pthread.h */ | 
| 210 | #include <pthread.h> | 
| 211 | #ifndef _REENTRANT | 
| 212 | #define _REENTRANT | 
| 213 | #endif | 
| 214 | #ifdef HAVE_THR_SETCONCURRENCY | 
| 215 | #include <thread.h>			/* Probably solaris */ | 
| 216 | #endif | 
| 217 | #ifdef HAVE_SCHED_H | 
| 218 | #include <sched.h> | 
| 219 | #endif | 
| 220 | #ifdef HAVE_SYNCH_H | 
| 221 | #include <synch.h> | 
| 222 | #endif | 
| 223 | #if defined(__EMX__) && (!defined(EMX_PTHREAD_REV) || (EMX_PTHREAD_REV < 2)) | 
| 224 | #error Requires at least rev 2 of EMX pthreads library. | 
| 225 | #endif | 
| 226 |  | 
| 227 | extern int my_pthread_getprio(pthread_t thread_id); | 
| 228 |  | 
| 229 | #define pthread_key(T,V) pthread_key_t V | 
| 230 | #define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,(V)) | 
| 231 | #define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,(void*) (V)) | 
| 232 | #define pthread_detach_this_thread() | 
| 233 | #define pthread_handler_decl(A,B) void *A(void *B) | 
| 234 | typedef void *(* pthread_handler)(void *); | 
| 235 |  | 
| 236 | /* Test first for RTS or FSU threads */ | 
| 237 |  | 
| 238 | #if defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) | 
| 239 | #define HAVE_rts_threads | 
| 240 | extern int my_pthread_create_detached; | 
| 241 | #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) | 
| 242 | #define PTHREAD_CREATE_DETACHED &my_pthread_create_detached | 
| 243 | #define PTHREAD_SCOPE_SYSTEM  PTHREAD_SCOPE_GLOBAL | 
| 244 | #define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_LOCAL | 
| 245 | #define USE_ALARM_THREAD | 
| 246 | #endif /* defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) */ | 
| 247 |  | 
| 248 | #if defined(HAVE_UNIXWARE7_POSIX) | 
| 249 | #undef HAVE_NONPOSIX_SIGWAIT | 
| 250 | #define HAVE_NONPOSIX_SIGWAIT	/* sigwait takes only 1 argument */ | 
| 251 | #endif | 
| 252 |  | 
| 253 | #ifndef HAVE_NONPOSIX_SIGWAIT | 
| 254 | #define my_sigwait(A,B) sigwait((A),(B)) | 
| 255 | #else | 
| 256 | int my_sigwait(const sigset_t *set,int *sig); | 
| 257 | #endif | 
| 258 |  | 
| 259 | #ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT | 
| 260 | #ifndef SAFE_MUTEX | 
| 261 | #define pthread_mutex_init(a,b) my_pthread_mutex_init((a),(b)) | 
| 262 | extern int my_pthread_mutex_init(pthread_mutex_t *mp, | 
| 263 | 				 const pthread_mutexattr_t *attr); | 
| 264 | #endif /* SAFE_MUTEX */ | 
| 265 | #define pthread_cond_init(a,b) my_pthread_cond_init((a),(b)) | 
| 266 | extern int my_pthread_cond_init(pthread_cond_t *mp, | 
| 267 | 				const pthread_condattr_t *attr); | 
| 268 | #endif /* HAVE_NONPOSIX_PTHREAD_MUTEX_INIT */ | 
| 269 |  | 
| 270 | #if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK) | 
| 271 | #define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C)) | 
| 272 | #endif | 
| 273 |  | 
| 274 | #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) | 
| 275 | int sigwait(sigset_t *setp, int *sigp);		/* Use our implementation */ | 
| 276 | #endif | 
| 277 | #if !defined(HAVE_SIGSET) && !defined(my_sigset) | 
| 278 | #define my_sigset(A,B) do { struct sigaction s; sigset_t set;           \ | 
| 279 |                          sigemptyset(&set);                             \ | 
| 280 |                          s.sa_handler = (B);                            \ | 
| 281 |                          s.sa_mask    = set;                            \ | 
| 282 |                          s.sa_flags   = 0;                              \ | 
| 283 |                          sigaction((A), &s, (struct sigaction *) NULL); \ | 
| 284 |                        } while (0) | 
| 285 | #elif !defined(my_sigset) | 
| 286 |   #define my_sigset(A,B) signal((A),(B)) | 
| 287 | #endif | 
| 288 |  | 
| 289 | #ifndef my_pthread_setprio | 
| 290 | #if defined(HAVE_PTHREAD_SETPRIO_NP)		/* FSU threads */ | 
| 291 | #define my_pthread_setprio(A,B) pthread_setprio_np((A),(B)) | 
| 292 | #elif defined(HAVE_PTHREAD_SETPRIO) | 
| 293 | #define my_pthread_setprio(A,B) pthread_setprio((A),(B)) | 
| 294 | #else | 
| 295 | extern void my_pthread_setprio(pthread_t thread_id,int prior); | 
| 296 | #endif | 
| 297 | #endif | 
| 298 |  | 
| 299 | #ifndef my_pthread_attr_setprio | 
| 300 | #ifdef HAVE_PTHREAD_ATTR_SETPRIO | 
| 301 | #define my_pthread_attr_setprio(A,B) pthread_attr_setprio((A),(B)) | 
| 302 | #else | 
| 303 | extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority); | 
| 304 | #endif | 
| 305 | #endif | 
| 306 |  | 
| 307 | #if !defined(HAVE_PTHREAD_ATTR_SETSCOPE) || defined(HAVE_DEC_3_2_THREADS) | 
| 308 | #define pthread_attr_setscope(A,B) | 
| 309 | #undef	HAVE_GETHOSTBYADDR_R			/* No definition */ | 
| 310 | #endif | 
| 311 |  | 
| 312 | #if defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT) && !defined(SAFE_MUTEX) | 
| 313 | extern int my_pthread_cond_timedwait(pthread_cond_t *cond, | 
| 314 | 				     pthread_mutex_t *mutex, | 
| 315 | 				     struct timespec *abstime); | 
| 316 | #define pthread_cond_timedwait(A,B,C) my_pthread_cond_timedwait((A),(B),(C)) | 
| 317 | #endif | 
| 318 |  | 
| 319 | #if !defined( HAVE_NONPOSIX_PTHREAD_GETSPECIFIC) | 
| 320 | #define my_pthread_getspecific(A,B) ((A) pthread_getspecific(B)) | 
| 321 | #else | 
| 322 | #define my_pthread_getspecific(A,B) ((A) my_pthread_getspecific_imp(B)) | 
| 323 | void *my_pthread_getspecific_imp(pthread_key_t key); | 
| 324 | #endif | 
| 325 |  | 
| 326 | #ifndef HAVE_LOCALTIME_R | 
| 327 | struct tm *localtime_r(const time_t *clock, struct tm *res); | 
| 328 | #endif | 
| 329 |  | 
| 330 | #ifdef HAVE_PTHREAD_CONDATTR_CREATE | 
| 331 | /* DCE threads on HPUX 10.20 */ | 
| 332 | #define pthread_condattr_init pthread_condattr_create | 
| 333 | #define pthread_condattr_destroy pthread_condattr_delete | 
| 334 | #endif | 
| 335 |  | 
| 336 | #ifdef HAVE_CTHREADS_WRAPPER			/* For MacOSX */ | 
| 337 | #define pthread_cond_destroy(A) pthread_dummy(0) | 
| 338 | #define pthread_mutex_destroy(A) pthread_dummy(0) | 
| 339 | #define pthread_attr_delete(A) pthread_dummy(0) | 
| 340 | #define pthread_condattr_delete(A) pthread_dummy(0) | 
| 341 | #define pthread_attr_setstacksize(A,B) pthread_dummy(0) | 
| 342 | #define pthread_equal(A,B) ((A) == (B)) | 
| 343 | #define pthread_cond_timedwait(a,b,c) pthread_cond_wait((a),(b)) | 
| 344 | #define pthread_attr_init(A) pthread_attr_create(A) | 
| 345 | #define pthread_attr_destroy(A) pthread_attr_delete(A) | 
| 346 | #define pthread_attr_setdetachstate(A,B) pthread_dummy(0) | 
| 347 | #define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D)) | 
| 348 | #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) | 
| 349 | #define pthread_kill(A,B) 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 | #ifdef HAVE_DARWIN_THREADS | 
| 355 | #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) | 
| 356 | #define pthread_kill(A,B) pthread_dummy(0) | 
| 357 | #define pthread_condattr_init(A) pthread_dummy(0) | 
| 358 | #define pthread_condattr_destroy(A) pthread_dummy(0) | 
| 359 | #define pthread_signal(A,B) pthread_dummy(0) | 
| 360 | #undef	pthread_detach_this_thread | 
| 361 | #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(tmp); } | 
| 362 | #undef sigset | 
| 363 | #define sigset(A,B) pthread_signal((A),(void (*)(int)) (B)) | 
| 364 | #endif | 
| 365 |  | 
| 366 | #if ((defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT)) || defined(HAVE_DEC_3_2_THREADS)) && !defined(HAVE_CTHREADS_WRAPPER) | 
| 367 | /* This is set on AIX_3_2 and Siemens unix (and DEC OSF/1 3.2 too) */ | 
| 368 | #define pthread_key_create(A,B) \ | 
| 369 | 		pthread_keycreate(A,(B) ?\ | 
| 370 | 				  (pthread_destructor_t) (B) :\ | 
| 371 | 				  (pthread_destructor_t) pthread_dummy) | 
| 372 | #define pthread_attr_init(A) pthread_attr_create(A) | 
| 373 | #define pthread_attr_destroy(A) pthread_attr_delete(A) | 
| 374 | #define pthread_attr_setdetachstate(A,B) pthread_dummy(0) | 
| 375 | #define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D)) | 
| 376 | #ifndef pthread_sigmask | 
| 377 | #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) | 
| 378 | #endif | 
| 379 | #define pthread_kill(A,B) pthread_dummy(0) | 
| 380 | #undef	pthread_detach_this_thread | 
| 381 | #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); } | 
| 382 | +#elif !defined(HAVE_PTHREAD_KILL) /* HAVE_PTHREAD_ATTR_CREATE && !HAVE_SIGWAIT */ | 
| 383 | #define HAVE_PTHREAD_KILL | 
| 384 | #endif | 
| 385 |  | 
| 386 | #endif /* defined(_WIN32) */ | 
| 387 |  | 
| 388 | #if defined(HPUX) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS) | 
| 389 | #undef pthread_cond_timedwait | 
| 390 | #define pthread_cond_timedwait(a,b,c) my_pthread_cond_timedwait((a),(b),(c)) | 
| 391 | int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, | 
| 392 | 			      struct timespec *abstime); | 
| 393 | #endif | 
| 394 |  | 
| 395 | #if defined(HAVE_POSIX1003_4a_MUTEX) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS) | 
| 396 | #undef pthread_mutex_trylock | 
| 397 | #define pthread_mutex_trylock(a) my_pthread_mutex_trylock((a)) | 
| 398 | int my_pthread_mutex_trylock(pthread_mutex_t *mutex); | 
| 399 | #endif | 
| 400 |  | 
| 401 | 	/* safe_mutex adds checking to mutex for easier debugging */ | 
| 402 |  | 
| 403 | typedef struct st_safe_mutex_t | 
| 404 | { | 
| 405 |   pthread_mutex_t global,mutex; | 
| 406 |   char *file; | 
| 407 |   uint line,count; | 
| 408 |   pthread_t thread; | 
| 409 | } safe_mutex_t; | 
| 410 |  | 
| 411 | int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr); | 
| 412 | int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line); | 
| 413 | int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line); | 
| 414 | int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line); | 
| 415 | int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file, | 
| 416 | 		   uint line); | 
| 417 | int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, | 
| 418 | 			struct timespec *abstime, const char *file, uint line); | 
| 419 |  | 
| 420 | 	/* Wrappers if safe mutex is actually used */ | 
| 421 | #ifdef SAFE_MUTEX | 
| 422 | #undef pthread_mutex_init | 
| 423 | #undef pthread_mutex_lock | 
| 424 | #undef pthread_mutex_unlock | 
| 425 | #undef pthread_mutex_destroy | 
| 426 | #undef pthread_mutex_wait | 
| 427 | #undef pthread_mutex_timedwait | 
| 428 | #undef pthread_mutex_t | 
| 429 | #undef pthread_cond_wait | 
| 430 | #undef pthread_cond_timedwait | 
| 431 | #undef pthread_mutex_trylock | 
| 432 | #define pthread_mutex_init(A,B) safe_mutex_init((A),(B)) | 
| 433 | #define pthread_mutex_lock(A) safe_mutex_lock((A),__FILE__,__LINE__) | 
| 434 | #define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__) | 
| 435 | #define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__) | 
| 436 | #define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__) | 
| 437 | #define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__) | 
| 438 | #define pthread_mutex_trylock(A) pthread_mutex_lock(A) | 
| 439 | #define pthread_mutex_t safe_mutex_t | 
| 440 | #define safe_mutex_assert_owner(mp) DBUG_ASSERT((mp)->count > 0 && pthread_equal(pthread_self(),(mp)->thread)) | 
| 441 | #else | 
| 442 | #define safe_mutex_assert_owner(mp) | 
| 443 | #endif /* SAFE_MUTEX */ | 
| 444 |  | 
| 445 | 	/* READ-WRITE thread locking */ | 
| 446 |  | 
| 447 | #if defined(USE_MUTEX_INSTEAD_OF_RW_LOCKS) | 
| 448 | /* use these defs for simple mutex locking */ | 
| 449 | #define rw_lock_t pthread_mutex_t | 
| 450 | #define my_rwlock_init(A,B) pthread_mutex_init((A),(B)) | 
| 451 | #define rw_rdlock(A) pthread_mutex_lock((A)) | 
| 452 | #define rw_wrlock(A) pthread_mutex_lock((A)) | 
| 453 | #define rw_tryrdlock(A) pthread_mutex_trylock((A)) | 
| 454 | #define rw_trywrlock(A) pthread_mutex_trylock((A)) | 
| 455 | #define rw_unlock(A) pthread_mutex_unlock((A)) | 
| 456 | #define rwlock_destroy(A) pthread_mutex_destroy((A)) | 
| 457 | #elif defined(HAVE_PTHREAD_RWLOCK_RDLOCK) | 
| 458 | #define rw_lock_t pthread_rwlock_t | 
| 459 | #define my_rwlock_init(A,B) pthread_rwlock_init((A),(B)) | 
| 460 | #define rw_rdlock(A) pthread_rwlock_rdlock(A) | 
| 461 | #define rw_wrlock(A) pthread_rwlock_wrlock(A) | 
| 462 | #define rw_tryrdlock(A) pthread_rwlock_tryrdlock((A)) | 
| 463 | #define rw_trywrlock(A) pthread_rwlock_trywrlock((A)) | 
| 464 | #define rw_unlock(A) pthread_rwlock_unlock(A) | 
| 465 | #define rwlock_destroy(A) pthread_rwlock_destroy(A) | 
| 466 | #elif defined(HAVE_RWLOCK_INIT) | 
| 467 | #ifdef HAVE_RWLOCK_T				/* For example Solaris 2.6-> */ | 
| 468 | #define rw_lock_t rwlock_t | 
| 469 | #endif | 
| 470 | #define my_rwlock_init(A,B) rwlock_init((A),USYNC_THREAD,0) | 
| 471 | #else | 
| 472 | /* Use our own version of read/write locks */ | 
| 473 | typedef struct _my_rw_lock_t { | 
| 474 | 	pthread_mutex_t lock;		/* lock for structure		*/ | 
| 475 | 	pthread_cond_t	readers;	/* waiting readers		*/ | 
| 476 | 	pthread_cond_t	writers;	/* waiting writers		*/ | 
| 477 | 	int		state;		/* -1:writer,0:free,>0:readers	*/ | 
| 478 | 	int		waiters;	/* number of waiting writers	*/ | 
| 479 | } my_rw_lock_t; | 
| 480 |  | 
| 481 | #define rw_lock_t my_rw_lock_t | 
| 482 | #define rw_rdlock(A) my_rw_rdlock((A)) | 
| 483 | #define rw_wrlock(A) my_rw_wrlock((A)) | 
| 484 | #define rw_tryrdlock(A) my_rw_tryrdlock((A)) | 
| 485 | #define rw_trywrlock(A) my_rw_trywrlock((A)) | 
| 486 | #define rw_unlock(A) my_rw_unlock((A)) | 
| 487 | #define rwlock_destroy(A) my_rwlock_destroy((A)) | 
| 488 |  | 
| 489 | extern int my_rwlock_init(my_rw_lock_t *, void *); | 
| 490 | extern int my_rwlock_destroy(my_rw_lock_t *); | 
| 491 | extern int my_rw_rdlock(my_rw_lock_t *); | 
| 492 | extern int my_rw_wrlock(my_rw_lock_t *); | 
| 493 | extern int my_rw_unlock(my_rw_lock_t *); | 
| 494 | extern int my_rw_tryrdlock(my_rw_lock_t *); | 
| 495 | extern int my_rw_trywrlock(my_rw_lock_t *); | 
| 496 | #endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */ | 
| 497 |  | 
| 498 | #define GETHOSTBYADDR_BUFF_SIZE 2048 | 
| 499 |  | 
| 500 | #ifndef HAVE_THR_SETCONCURRENCY | 
| 501 | #define thr_setconcurrency(A) pthread_dummy(0) | 
| 502 | #endif | 
| 503 | #if !defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && ! defined(pthread_attr_setstacksize) | 
| 504 | #define pthread_attr_setstacksize(A,B) pthread_dummy(0) | 
| 505 | #endif | 
| 506 |  | 
| 507 | /* Define mutex types */ | 
| 508 | #define MY_MUTEX_INIT_SLOW   NULL | 
| 509 | #define MY_MUTEX_INIT_FAST   NULL | 
| 510 | #define MY_MUTEX_INIT_ERRCHK NULL | 
| 511 |  | 
| 512 | extern my_bool my_thread_global_init(void); | 
| 513 | extern void my_thread_global_end(void); | 
| 514 | extern my_bool my_thread_init(void); | 
| 515 | extern void my_thread_end(void); | 
| 516 | extern const char *my_thread_name(void); | 
| 517 | extern long my_thread_id(void); | 
| 518 | extern int pthread_no_free(void *); | 
| 519 | extern int pthread_dummy(int); | 
| 520 |  | 
| 521 | /* All thread specific variables are in the following struct */ | 
| 522 |  | 
| 523 | #define THREAD_NAME_SIZE 10 | 
| 524 | #if defined(__ia64__) | 
| 525 | #define DEFAULT_THREAD_STACK	(128*1024) | 
| 526 | #else | 
| 527 | #define DEFAULT_THREAD_STACK	(64*1024) | 
| 528 | #endif | 
| 529 |  | 
| 530 | struct st_my_thread_var | 
| 531 | { | 
| 532 |   int thr_errno; | 
| 533 |   pthread_cond_t suspend; | 
| 534 |   pthread_mutex_t mutex; | 
| 535 |   pthread_mutex_t * volatile current_mutex; | 
| 536 |   pthread_cond_t * volatile current_cond; | 
| 537 |   pthread_t pthread_self; | 
| 538 |   long id; | 
| 539 |   int cmp_length; | 
| 540 |   int volatile abort; | 
| 541 | #ifndef DBUG_OFF | 
| 542 |   gptr dbug; | 
| 543 |   char name[THREAD_NAME_SIZE+1]; | 
| 544 | #endif | 
| 545 |   my_bool initialized; | 
| 546 | }; | 
| 547 |  | 
| 548 | extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const)); | 
| 549 | extern void **my_thread_var_dbug(); | 
| 550 | #define my_thread_var (_my_thread_var()) | 
| 551 | #define my_errno my_thread_var->thr_errno | 
| 552 |  | 
| 553 | 	/* statistics_xxx functions are for not essential statistic */ | 
| 554 |  | 
| 555 | #ifndef thread_safe_increment | 
| 556 | #ifdef HAVE_ATOMIC_ADD | 
| 557 | #define thread_safe_increment(V,L) atomic_add(1,(atomic_t*) &V); | 
| 558 | #define thread_safe_add(V,C,L)     atomic_add((C),(atomic_t*) &V); | 
| 559 | #define thread_safe_sub(V,C,L)     atomic_sub((C),(atomic_t*) &V); | 
| 560 | #define statistic_increment(V,L)   thread_safe_increment((V),(L)) | 
| 561 | #define statistic_add(V,C,L)       thread_safe_add((V),(C),(L)) | 
| 562 | #else | 
| 563 | #define thread_safe_increment(V,L) \ | 
| 564 | 	pthread_mutex_lock((L)); (V)++; pthread_mutex_unlock((L)); | 
| 565 | #define thread_safe_add(V,C,L) \ | 
| 566 | 	pthread_mutex_lock((L)); (V)+=(C); pthread_mutex_unlock((L)); | 
| 567 | #define thread_safe_sub(V,C,L) \ | 
| 568 | 	pthread_mutex_lock((L)); (V)-=(C); pthread_mutex_unlock((L)); | 
| 569 | #ifdef SAFE_STATISTICS | 
| 570 | #define statistic_increment(V,L)   thread_safe_increment((V),(L)) | 
| 571 | #define statistic_add(V,C,L)       thread_safe_add((V),(C),(L)) | 
| 572 | #else | 
| 573 | #define statistic_increment(V,L) (V)++ | 
| 574 | #define statistic_add(V,C,L)     (V)+=(C) | 
| 575 | #endif /* SAFE_STATISTICS */ | 
| 576 | #endif /* HAVE_ATOMIC_ADD */ | 
| 577 | #endif /* thread_safe_increment */ | 
| 578 |  | 
| 579 | #ifdef  __cplusplus | 
| 580 | } | 
| 581 | #endif | 
| 582 |  | 
| 583 | #endif /* _my_ptread_h */ | 
| 584 |  |