00001 /* Copyright (C) 2000 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 /* Defines to make different thread packages compatible */ 00018 00019 #ifndef _my_pthread_h 00020 #define _my_pthread_h 00021 00022 #include <errno.h> 00023 #ifndef ETIME 00024 #define ETIME ETIMEDOUT /* For FreeBSD */ 00025 #endif 00026 00027 #ifdef __cplusplus 00028 #define EXTERNC extern "C" 00029 extern "C" { 00030 #else 00031 #define EXTERNC 00032 #endif /* __cplusplus */ 00033 00034 #if defined(__WIN__) 00035 00036 typedef CRITICAL_SECTION pthread_mutex_t; 00037 typedef HANDLE pthread_t; 00038 typedef struct thread_attr { 00039 DWORD dwStackSize ; 00040 DWORD dwCreatingFlag ; 00041 int priority ; 00042 } pthread_attr_t ; 00043 00044 typedef struct { int dummy; } pthread_condattr_t; 00045 00046 /* Implementation of posix conditions */ 00047 00048 typedef struct st_pthread_link { 00049 DWORD thread_id; 00050 struct st_pthread_link *next; 00051 } pthread_link; 00052 00053 typedef struct { 00054 uint32 waiting; 00055 HANDLE semaphore; 00056 } pthread_cond_t; 00057 00058 00059 struct timespec { /* For pthread_cond_timedwait() */ 00060 time_t tv_sec; 00061 long tv_nsec; 00062 }; 00063 00064 typedef int pthread_mutexattr_t; 00065 #define win_pthread_self my_thread_var->pthread_self 00066 #define pthread_handler_t EXTERNC void * __cdecl 00067 typedef void * (__cdecl *pthread_handler)(void *); 00068 00069 void win_pthread_init(void); 00070 int win_pthread_setspecific(void *A,void *B,uint length); 00071 int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *); 00072 int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); 00073 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); 00074 int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, 00075 struct timespec *abstime); 00076 int pthread_cond_signal(pthread_cond_t *cond); 00077 int pthread_cond_broadcast(pthread_cond_t *cond); 00078 int pthread_cond_destroy(pthread_cond_t *cond); 00079 int pthread_attr_init(pthread_attr_t *connect_att); 00080 int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack); 00081 int pthread_attr_setprio(pthread_attr_t *connect_att,int priority); 00082 int pthread_attr_destroy(pthread_attr_t *connect_att); 00083 struct tm *localtime_r(const time_t *timep,struct tm *tmp); 00084 struct tm *gmtime_r(const time_t *timep,struct tm *tmp); 00085 00086 00087 void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/ 00088 00089 #define ETIMEDOUT 145 /* Win32 doesn't have this */ 00090 #define getpid() GetCurrentThreadId() 00091 #define pthread_self() win_pthread_self 00092 #define HAVE_LOCALTIME_R 1 00093 #define _REENTRANT 1 00094 #define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1 00095 00096 /* 00097 Windows has two ways to use thread local storage. The most efficient 00098 is using __declspec(thread), but that does not work properly when 00099 used in a .dll that is loaded at runtime, after program load. So for 00100 libmysql.dll and libmysqld.dll we define USE_TLS in order to use the 00101 TlsXxx() API instead, which works in all cases. 00102 */ 00103 #ifdef USE_TLS /* For LIBMYSQL.DLL */ 00104 #undef SAFE_MUTEX /* This will cause conflicts */ 00105 #define pthread_key(T,V) DWORD V 00106 #define pthread_key_create(A,B) ((*A=TlsAlloc())==0xFFFFFFFF) 00107 #define pthread_key_delete(A) TlsFree(A) 00108 #define pthread_getspecific(A) (TlsGetValue(A)) 00109 #define my_pthread_getspecific(T,A) ((T) TlsGetValue(A)) 00110 #define my_pthread_getspecific_ptr(T,V) ((T) TlsGetValue(V)) 00111 #define my_pthread_setspecific_ptr(T,V) (!TlsSetValue((T),(V))) 00112 #define pthread_setspecific(A,B) (!TlsSetValue((A),(B))) 00113 #else 00114 #define pthread_key(T,V) __declspec(thread) T V 00115 #define pthread_key_create(A,B) pthread_dummy(0) 00116 #define pthread_key_delete(A) pthread_dummy(0) 00117 #define pthread_getspecific(A) (&(A)) 00118 #define my_pthread_getspecific(T,A) (&(A)) 00119 #define my_pthread_getspecific_ptr(T,V) (V) 00120 #define my_pthread_setspecific_ptr(T,V) ((T)=(V),0) 00121 #define pthread_setspecific(A,B) win_pthread_setspecific(&(A),(B),sizeof(A)) 00122 #endif /* USE_TLS */ 00123 00124 #define pthread_equal(A,B) ((A) == (B)) 00125 #define pthread_mutex_init(A,B) (InitializeCriticalSection(A),0) 00126 #define pthread_mutex_lock(A) (EnterCriticalSection(A),0) 00127 #define pthread_mutex_trylock(A) (WaitForSingleObject((A), 0) == WAIT_TIMEOUT) 00128 #define pthread_mutex_unlock(A) LeaveCriticalSection(A) 00129 #define pthread_mutex_destroy(A) DeleteCriticalSection(A) 00130 #define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B)) 00131 #define pthread_kill(A,B) pthread_dummy(0) 00132 00133 /* Dummy defines for easier code */ 00134 #define pthread_attr_setdetachstate(A,B) pthread_dummy(0) 00135 #define my_pthread_attr_setprio(A,B) pthread_attr_setprio(A,B) 00136 #define pthread_attr_setscope(A,B) 00137 #define pthread_detach_this_thread() 00138 #define pthread_condattr_init(A) 00139 #define pthread_condattr_destroy(A) 00140 00141 /*Irena: compiler does not like this: */ 00142 /*#define my_pthread_getprio(pthread_t thread_id) pthread_dummy(0) */ 00143 #define my_pthread_getprio(thread_id) pthread_dummy(0) 00144 00145 #else /* Normal threads */ 00146 00147 #ifdef HAVE_rts_threads 00148 #define sigwait org_sigwait 00149 #include <signal.h> 00150 #undef sigwait 00151 #endif 00152 #include <pthread.h> 00153 #ifndef _REENTRANT 00154 #define _REENTRANT 00155 #endif 00156 #ifdef HAVE_THR_SETCONCURRENCY 00157 #include <thread.h> /* Probably solaris */ 00158 #endif 00159 #ifdef HAVE_SCHED_H 00160 #include <sched.h> 00161 #endif 00162 #ifdef HAVE_SYNCH_H 00163 #include <synch.h> 00164 #endif 00165 00166 #ifdef __NETWARE__ 00167 void my_pthread_exit(void *status); 00168 #define pthread_exit(A) my_pthread_exit(A) 00169 #endif 00170 00171 extern int my_pthread_getprio(pthread_t thread_id); 00172 00173 #define pthread_key(T,V) pthread_key_t V 00174 #define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,(V)) 00175 #define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,(void*) (V)) 00176 #define pthread_detach_this_thread() 00177 #define pthread_handler_t EXTERNC void * 00178 typedef void *(* pthread_handler)(void *); 00179 00180 /* Test first for RTS or FSU threads */ 00181 00182 #if defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) 00183 #define HAVE_rts_threads 00184 extern int my_pthread_create_detached; 00185 #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) 00186 #define PTHREAD_CREATE_DETACHED &my_pthread_create_detached 00187 #define PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_GLOBAL 00188 #define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_LOCAL 00189 #define USE_ALARM_THREAD 00190 #endif /* defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) */ 00191 00192 #if defined(_BSDI_VERSION) && _BSDI_VERSION < 199910 00193 int sigwait(sigset_t *set, int *sig); 00194 #endif 00195 00196 #ifndef HAVE_NONPOSIX_SIGWAIT 00197 #define my_sigwait(A,B) sigwait((A),(B)) 00198 #else 00199 int my_sigwait(const sigset_t *set,int *sig); 00200 #endif 00201 00202 #ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT 00203 #ifndef SAFE_MUTEX 00204 #define pthread_mutex_init(a,b) my_pthread_mutex_init((a),(b)) 00205 extern int my_pthread_mutex_init(pthread_mutex_t *mp, 00206 const pthread_mutexattr_t *attr); 00207 #endif /* SAFE_MUTEX */ 00208 #define pthread_cond_init(a,b) my_pthread_cond_init((a),(b)) 00209 extern int my_pthread_cond_init(pthread_cond_t *mp, 00210 const pthread_condattr_t *attr); 00211 #endif /* HAVE_NONPOSIX_PTHREAD_MUTEX_INIT */ 00212 00213 #if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK) 00214 #define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C)) 00215 #endif 00216 00217 #if !defined(HAVE_SIGWAIT) && !defined(HAVE_rts_threads) && !defined(sigwait) && !defined(alpha_linux_port) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS) && !defined(_AIX) 00218 int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */ 00219 #endif 00220 00221 00222 /* 00223 We define my_sigset() and use that instead of the system sigset() so that 00224 we can favor an implementation based on sigaction(). On some systems, such 00225 as Mac OS X, sigset() results in flags such as SA_RESTART being set, and 00226 we want to make sure that no such flags are set. 00227 */ 00228 #if defined(HAVE_SIGACTION) && !defined(my_sigset) 00229 #define my_sigset(A,B) do { struct sigaction s; sigset_t set; int rc; \ 00230 DBUG_ASSERT((A) != 0); \ 00231 sigemptyset(&set); \ 00232 s.sa_handler = (B); \ 00233 s.sa_mask = set; \ 00234 s.sa_flags = 0; \ 00235 rc= sigaction((A), &s, (struct sigaction *) NULL);\ 00236 DBUG_ASSERT(rc == 0); \ 00237 } while (0) 00238 #elif defined(HAVE_SIGSET) && !defined(my_sigset) 00239 #define my_sigset(A,B) sigset((A),(B)) 00240 #elif !defined(my_sigset) 00241 #define my_sigset(A,B) signal((A),(B)) 00242 #endif 00243 00244 #ifndef my_pthread_setprio 00245 #if defined(HAVE_PTHREAD_SETPRIO_NP) /* FSU threads */ 00246 #define my_pthread_setprio(A,B) pthread_setprio_np((A),(B)) 00247 #elif defined(HAVE_PTHREAD_SETPRIO) 00248 #define my_pthread_setprio(A,B) pthread_setprio((A),(B)) 00249 #else 00250 extern void my_pthread_setprio(pthread_t thread_id,int prior); 00251 #endif 00252 #endif 00253 00254 #ifndef my_pthread_attr_setprio 00255 #ifdef HAVE_PTHREAD_ATTR_SETPRIO 00256 #define my_pthread_attr_setprio(A,B) pthread_attr_setprio((A),(B)) 00257 #else 00258 extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority); 00259 #endif 00260 #endif 00261 00262 #if !defined(HAVE_PTHREAD_ATTR_SETSCOPE) || defined(HAVE_DEC_3_2_THREADS) 00263 #define pthread_attr_setscope(A,B) 00264 #undef HAVE_GETHOSTBYADDR_R /* No definition */ 00265 #endif 00266 00267 #if defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT) && !defined(SAFE_MUTEX) 00268 extern int my_pthread_cond_timedwait(pthread_cond_t *cond, 00269 pthread_mutex_t *mutex, 00270 struct timespec *abstime); 00271 #define pthread_cond_timedwait(A,B,C) my_pthread_cond_timedwait((A),(B),(C)) 00272 #endif 00273 00274 #if !defined( HAVE_NONPOSIX_PTHREAD_GETSPECIFIC) 00275 #define my_pthread_getspecific(A,B) ((A) pthread_getspecific(B)) 00276 #else 00277 #define my_pthread_getspecific(A,B) ((A) my_pthread_getspecific_imp(B)) 00278 void *my_pthread_getspecific_imp(pthread_key_t key); 00279 #endif 00280 00281 #ifndef HAVE_LOCALTIME_R 00282 struct tm *localtime_r(const time_t *clock, struct tm *res); 00283 #endif 00284 00285 #ifndef HAVE_GMTIME_R 00286 struct tm *gmtime_r(const time_t *clock, struct tm *res); 00287 #endif 00288 00289 #ifdef HAVE_PTHREAD_CONDATTR_CREATE 00290 /* DCE threads on HPUX 10.20 */ 00291 #define pthread_condattr_init pthread_condattr_create 00292 #define pthread_condattr_destroy pthread_condattr_delete 00293 #endif 00294 00295 /* FSU THREADS */ 00296 #if !defined(HAVE_PTHREAD_KEY_DELETE) && !defined(pthread_key_delete) 00297 #define pthread_key_delete(A) pthread_dummy(0) 00298 #endif 00299 00300 #ifdef HAVE_CTHREADS_WRAPPER /* For MacOSX */ 00301 #define pthread_cond_destroy(A) pthread_dummy(0) 00302 #define pthread_mutex_destroy(A) pthread_dummy(0) 00303 #define pthread_attr_delete(A) pthread_dummy(0) 00304 #define pthread_condattr_delete(A) pthread_dummy(0) 00305 #define pthread_attr_setstacksize(A,B) pthread_dummy(0) 00306 #define pthread_equal(A,B) ((A) == (B)) 00307 #define pthread_cond_timedwait(a,b,c) pthread_cond_wait((a),(b)) 00308 #define pthread_attr_init(A) pthread_attr_create(A) 00309 #define pthread_attr_destroy(A) pthread_attr_delete(A) 00310 #define pthread_attr_setdetachstate(A,B) pthread_dummy(0) 00311 #define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D)) 00312 #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) 00313 #define pthread_kill(A,B) pthread_dummy(0) 00314 #undef pthread_detach_this_thread 00315 #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); } 00316 #endif 00317 00318 #ifdef HAVE_DARWIN5_THREADS 00319 #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) 00320 #define pthread_kill(A,B) pthread_dummy(0) 00321 #define pthread_condattr_init(A) pthread_dummy(0) 00322 #define pthread_condattr_destroy(A) pthread_dummy(0) 00323 #undef pthread_detach_this_thread 00324 #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(tmp); } 00325 #endif 00326 00327 #if ((defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT)) || defined(HAVE_DEC_3_2_THREADS)) && !defined(HAVE_CTHREADS_WRAPPER) 00328 /* This is set on AIX_3_2 and Siemens unix (and DEC OSF/1 3.2 too) */ 00329 #define pthread_key_create(A,B) \ 00330 pthread_keycreate(A,(B) ?\ 00331 (pthread_destructor_t) (B) :\ 00332 (pthread_destructor_t) pthread_dummy) 00333 #define pthread_attr_init(A) pthread_attr_create(A) 00334 #define pthread_attr_destroy(A) pthread_attr_delete(A) 00335 #define pthread_attr_setdetachstate(A,B) pthread_dummy(0) 00336 #define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D)) 00337 #ifndef pthread_sigmask 00338 #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) 00339 #endif 00340 #define pthread_kill(A,B) pthread_dummy(0) 00341 #undef pthread_detach_this_thread 00342 #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); } 00343 #elif !defined(__NETWARE__) /* HAVE_PTHREAD_ATTR_CREATE && !HAVE_SIGWAIT */ 00344 #define HAVE_PTHREAD_KILL 00345 #endif 00346 00347 #endif /* defined(__WIN__) */ 00348 00349 #if defined(HPUX10) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS) 00350 #undef pthread_cond_timedwait 00351 #define pthread_cond_timedwait(a,b,c) my_pthread_cond_timedwait((a),(b),(c)) 00352 int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, 00353 struct timespec *abstime); 00354 #endif 00355 00356 #if defined(HPUX10) 00357 #define pthread_attr_getstacksize(A,B) my_pthread_attr_getstacksize(A,B) 00358 void my_pthread_attr_getstacksize(pthread_attr_t *attrib, size_t *size); 00359 #endif 00360 00361 #if defined(HAVE_POSIX1003_4a_MUTEX) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS) 00362 #undef pthread_mutex_trylock 00363 #define pthread_mutex_trylock(a) my_pthread_mutex_trylock((a)) 00364 int my_pthread_mutex_trylock(pthread_mutex_t *mutex); 00365 #endif 00366 00367 /* safe_mutex adds checking to mutex for easier debugging */ 00368 00369 #if defined(__NETWARE__) && !defined(SAFE_MUTEX_DETECT_DESTROY) 00370 #define SAFE_MUTEX_DETECT_DESTROY 00371 #endif 00372 00373 typedef struct st_safe_mutex_t 00374 { 00375 pthread_mutex_t global,mutex; 00376 const char *file; 00377 uint line,count; 00378 pthread_t thread; 00379 #ifdef SAFE_MUTEX_DETECT_DESTROY 00380 struct st_safe_mutex_info_t *info; /* to track destroying of mutexes */ 00381 #endif 00382 } safe_mutex_t; 00383 00384 #ifdef SAFE_MUTEX_DETECT_DESTROY 00385 /* 00386 Used to track the destroying of mutexes. This needs to be a seperate 00387 structure because the safe_mutex_t structure could be freed before 00388 the mutexes are destroyed. 00389 */ 00390 00391 typedef struct st_safe_mutex_info_t 00392 { 00393 struct st_safe_mutex_info_t *next; 00394 struct st_safe_mutex_info_t *prev; 00395 const char *init_file; 00396 uint32 init_line; 00397 } safe_mutex_info_t; 00398 #endif /* SAFE_MUTEX_DETECT_DESTROY */ 00399 00400 int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr, 00401 const char *file, uint line); 00402 int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line); 00403 int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line); 00404 int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line); 00405 int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file, 00406 uint line); 00407 int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, 00408 struct timespec *abstime, const char *file, uint line); 00409 void safe_mutex_global_init(void); 00410 void safe_mutex_end(FILE *file); 00411 00412 /* Wrappers if safe mutex is actually used */ 00413 #ifdef SAFE_MUTEX 00414 #undef pthread_mutex_init 00415 #undef pthread_mutex_lock 00416 #undef pthread_mutex_unlock 00417 #undef pthread_mutex_destroy 00418 #undef pthread_mutex_wait 00419 #undef pthread_mutex_timedwait 00420 #undef pthread_mutex_t 00421 #undef pthread_cond_wait 00422 #undef pthread_cond_timedwait 00423 #undef pthread_mutex_trylock 00424 #define pthread_mutex_init(A,B) safe_mutex_init((A),(B),__FILE__,__LINE__) 00425 #define pthread_mutex_lock(A) safe_mutex_lock((A),__FILE__,__LINE__) 00426 #define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__) 00427 #define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__) 00428 #define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__) 00429 #define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__) 00430 #define pthread_mutex_trylock(A) pthread_mutex_lock(A) 00431 #define pthread_mutex_t safe_mutex_t 00432 #define safe_mutex_assert_owner(mp) \ 00433 DBUG_ASSERT((mp)->count > 0 && \ 00434 pthread_equal(pthread_self(), (mp)->thread)) 00435 #define safe_mutex_assert_not_owner(mp) \ 00436 DBUG_ASSERT(! (mp)->count || \ 00437 ! pthread_equal(pthread_self(), (mp)->thread)) 00438 #else 00439 #define safe_mutex_assert_owner(mp) 00440 #define safe_mutex_assert_not_owner(mp) 00441 #endif /* SAFE_MUTEX */ 00442 00443 #if defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) 00444 typedef struct st_my_pthread_fastmutex_t 00445 { 00446 pthread_mutex_t mutex; 00447 uint spins; 00448 } my_pthread_fastmutex_t; 00449 00450 int my_pthread_fastmutex_init(my_pthread_fastmutex_t *mp, 00451 const pthread_mutexattr_t *attr); 00452 int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp); 00453 00454 #undef pthread_mutex_init 00455 #undef pthread_mutex_lock 00456 #undef pthread_mutex_unlock 00457 #undef pthread_mutex_destroy 00458 #undef pthread_mutex_wait 00459 #undef pthread_mutex_timedwait 00460 #undef pthread_mutex_t 00461 #undef pthread_cond_wait 00462 #undef pthread_cond_timedwait 00463 #undef pthread_mutex_trylock 00464 #define pthread_mutex_init(A,B) my_pthread_fastmutex_init((A),(B)) 00465 #define pthread_mutex_lock(A) my_pthread_fastmutex_lock(A) 00466 #define pthread_mutex_unlock(A) pthread_mutex_unlock(&(A)->mutex) 00467 #define pthread_mutex_destroy(A) pthread_mutex_destroy(&(A)->mutex) 00468 #define pthread_cond_wait(A,B) pthread_cond_wait((A),&(B)->mutex) 00469 #define pthread_cond_timedwait(A,B,C) pthread_cond_timedwait((A),&(B)->mutex,(C)) 00470 #define pthread_mutex_trylock(A) pthread_mutex_trylock(&(A)->mutex) 00471 #define pthread_mutex_t my_pthread_fastmutex_t 00472 #endif /* defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) */ 00473 00474 /* READ-WRITE thread locking */ 00475 00476 #ifdef HAVE_BROKEN_RWLOCK /* For OpenUnix */ 00477 #undef HAVE_PTHREAD_RWLOCK_RDLOCK 00478 #undef HAVE_RWLOCK_INIT 00479 #undef HAVE_RWLOCK_T 00480 #endif 00481 00482 #if defined(USE_MUTEX_INSTEAD_OF_RW_LOCKS) 00483 /* use these defs for simple mutex locking */ 00484 #define rw_lock_t pthread_mutex_t 00485 #define my_rwlock_init(A,B) pthread_mutex_init((A),(B)) 00486 #define rw_rdlock(A) pthread_mutex_lock((A)) 00487 #define rw_wrlock(A) pthread_mutex_lock((A)) 00488 #define rw_tryrdlock(A) pthread_mutex_trylock((A)) 00489 #define rw_trywrlock(A) pthread_mutex_trylock((A)) 00490 #define rw_unlock(A) pthread_mutex_unlock((A)) 00491 #define rwlock_destroy(A) pthread_mutex_destroy((A)) 00492 #elif defined(HAVE_PTHREAD_RWLOCK_RDLOCK) 00493 #define rw_lock_t pthread_rwlock_t 00494 #define my_rwlock_init(A,B) pthread_rwlock_init((A),(B)) 00495 #define rw_rdlock(A) pthread_rwlock_rdlock(A) 00496 #define rw_wrlock(A) pthread_rwlock_wrlock(A) 00497 #define rw_tryrdlock(A) pthread_rwlock_tryrdlock((A)) 00498 #define rw_trywrlock(A) pthread_rwlock_trywrlock((A)) 00499 #define rw_unlock(A) pthread_rwlock_unlock(A) 00500 #define rwlock_destroy(A) pthread_rwlock_destroy(A) 00501 #elif defined(HAVE_RWLOCK_INIT) 00502 #ifdef HAVE_RWLOCK_T /* For example Solaris 2.6-> */ 00503 #define rw_lock_t rwlock_t 00504 #endif 00505 #define my_rwlock_init(A,B) rwlock_init((A),USYNC_THREAD,0) 00506 #else 00507 /* Use our own version of read/write locks */ 00508 typedef struct _my_rw_lock_t { 00509 pthread_mutex_t lock; /* lock for structure */ 00510 pthread_cond_t readers; /* waiting readers */ 00511 pthread_cond_t writers; /* waiting writers */ 00512 int state; /* -1:writer,0:free,>0:readers */ 00513 int waiters; /* number of waiting writers */ 00514 } my_rw_lock_t; 00515 00516 #define rw_lock_t my_rw_lock_t 00517 #define rw_rdlock(A) my_rw_rdlock((A)) 00518 #define rw_wrlock(A) my_rw_wrlock((A)) 00519 #define rw_tryrdlock(A) my_rw_tryrdlock((A)) 00520 #define rw_trywrlock(A) my_rw_trywrlock((A)) 00521 #define rw_unlock(A) my_rw_unlock((A)) 00522 #define rwlock_destroy(A) my_rwlock_destroy((A)) 00523 00524 extern int my_rwlock_init(my_rw_lock_t *, void *); 00525 extern int my_rwlock_destroy(my_rw_lock_t *); 00526 extern int my_rw_rdlock(my_rw_lock_t *); 00527 extern int my_rw_wrlock(my_rw_lock_t *); 00528 extern int my_rw_unlock(my_rw_lock_t *); 00529 extern int my_rw_tryrdlock(my_rw_lock_t *); 00530 extern int my_rw_trywrlock(my_rw_lock_t *); 00531 #endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */ 00532 00533 #define GETHOSTBYADDR_BUFF_SIZE 2048 00534 00535 #ifndef HAVE_THR_SETCONCURRENCY 00536 #define thr_setconcurrency(A) pthread_dummy(0) 00537 #endif 00538 #if !defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && ! defined(pthread_attr_setstacksize) 00539 #define pthread_attr_setstacksize(A,B) pthread_dummy(0) 00540 #endif 00541 00542 /* Define mutex types, see my_thr_init.c */ 00543 #define MY_MUTEX_INIT_SLOW NULL 00544 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP 00545 extern pthread_mutexattr_t my_fast_mutexattr; 00546 #define MY_MUTEX_INIT_FAST &my_fast_mutexattr 00547 #else 00548 #define MY_MUTEX_INIT_FAST NULL 00549 #endif 00550 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP 00551 extern pthread_mutexattr_t my_errorcheck_mutexattr; 00552 #define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr 00553 #else 00554 #define MY_MUTEX_INIT_ERRCHK NULL 00555 #endif 00556 00557 extern my_bool my_thread_global_init(void); 00558 extern void my_thread_global_end(void); 00559 extern my_bool my_thread_init(void); 00560 extern void my_thread_end(void); 00561 extern const char *my_thread_name(void); 00562 extern long my_thread_id(void); 00563 extern int pthread_no_free(void *); 00564 extern int pthread_dummy(int); 00565 00566 /* All thread specific variables are in the following struct */ 00567 00568 #define THREAD_NAME_SIZE 10 00569 #ifndef DEFAULT_THREAD_STACK 00570 #if SIZEOF_CHARP > 4 00571 /* 00572 MySQL can survive with 32K, but some glibc libraries require > 128K stack 00573 To resolve hostnames. Also recursive stored procedures needs stack. 00574 */ 00575 #define DEFAULT_THREAD_STACK (256*1024L) 00576 #else 00577 #define DEFAULT_THREAD_STACK (192*1024) 00578 #endif 00579 #endif 00580 00581 struct st_my_thread_var 00582 { 00583 int thr_errno; 00584 pthread_cond_t suspend; 00585 pthread_mutex_t mutex; 00586 pthread_mutex_t * volatile current_mutex; 00587 pthread_cond_t * volatile current_cond; 00588 pthread_t pthread_self; 00589 long id; 00590 int cmp_length; 00591 int volatile abort; 00592 my_bool init; 00593 struct st_my_thread_var *next,**prev; 00594 void *opt_info; 00595 #ifndef DBUG_OFF 00596 gptr dbug; 00597 char name[THREAD_NAME_SIZE+1]; 00598 #endif 00599 }; 00600 00601 extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const)); 00602 #define my_thread_var (_my_thread_var()) 00603 #define my_errno my_thread_var->thr_errno 00604 /* 00605 Keep track of shutdown,signal, and main threads so that my_end() will not 00606 report errors with them 00607 */ 00608 extern pthread_t shutdown_th, main_th, signal_th; 00609 00610 /* statistics_xxx functions are for not essential statistic */ 00611 00612 #ifndef thread_safe_increment 00613 #ifdef HAVE_ATOMIC_ADD 00614 #define thread_safe_increment(V,L) atomic_inc((atomic_t*) &V) 00615 #define thread_safe_decrement(V,L) atomic_dec((atomic_t*) &V) 00616 #define thread_safe_add(V,C,L) atomic_add((C),(atomic_t*) &V) 00617 #define thread_safe_sub(V,C,L) atomic_sub((C),(atomic_t*) &V) 00618 #else 00619 #define thread_safe_increment(V,L) \ 00620 (pthread_mutex_lock((L)), (V)++, pthread_mutex_unlock((L))) 00621 #define thread_safe_decrement(V,L) \ 00622 (pthread_mutex_lock((L)), (V)--, pthread_mutex_unlock((L))) 00623 #define thread_safe_add(V,C,L) (pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L))) 00624 #define thread_safe_sub(V,C,L) \ 00625 (pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L))) 00626 #endif /* HAVE_ATOMIC_ADD */ 00627 #ifdef SAFE_STATISTICS 00628 #define statistic_increment(V,L) thread_safe_increment((V),(L)) 00629 #define statistic_decrement(V,L) thread_safe_decrement((V),(L)) 00630 #define statistic_add(V,C,L) thread_safe_add((V),(C),(L)) 00631 #else 00632 #define statistic_decrement(V,L) (V)-- 00633 #define statistic_increment(V,L) (V)++ 00634 #define statistic_add(V,C,L) (V)+=(C) 00635 #endif /* SAFE_STATISTICS */ 00636 #endif /* thread_safe_increment */ 00637 00638 #ifdef __cplusplus 00639 } 00640 #endif 00641 #endif /* _my_ptread_h */
1.4.7

