Eneboo - Documentación para desarrolladores
|
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; version 2 of the License. 00006 00007 This program is distributed in the hope that it will be useful, 00008 but WITHOUT ANY WARRANTY; without even the implied warranty of 00009 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00010 GNU General Public License for more details. 00011 00012 You should have received a copy of the GNU General Public License 00013 along with this program; if not, write to the Free Software 00014 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00015 00016 /* Defines to make different thread packages compatible */ 00017 00018 #ifndef _my_pthread_h 00019 #define _my_pthread_h 00020 00021 #include <errno.h> 00022 #ifndef ETIME 00023 #define ETIME ETIMEDOUT /* For FreeBSD */ 00024 #endif 00025 00026 #ifdef __cplusplus 00027 #define EXTERNC extern "C" 00028 extern "C" { 00029 #else 00030 #define EXTERNC 00031 #endif /* __cplusplus */ 00032 00033 #if defined(__WIN__) || defined(OS2) 00034 00035 #ifdef OS2 00036 typedef ULONG HANDLE; 00037 typedef ULONG DWORD; 00038 typedef int sigset_t; 00039 #endif 00040 00041 #ifdef OS2 00042 typedef HMTX pthread_mutex_t; 00043 #else 00044 typedef CRITICAL_SECTION pthread_mutex_t; 00045 #endif 00046 typedef HANDLE pthread_t; 00047 typedef struct thread_attr { 00048 DWORD dwStackSize ; 00049 DWORD dwCreatingFlag ; 00050 int priority ; 00051 } pthread_attr_t ; 00052 00053 typedef struct { int dummy; } pthread_condattr_t; 00054 00055 /* Implementation of posix conditions */ 00056 00057 typedef struct st_pthread_link { 00058 DWORD thread_id; 00059 struct st_pthread_link *next; 00060 } pthread_link; 00061 00062 typedef struct { 00063 uint32 waiting; 00064 CRITICAL_SECTION lock_waiting; 00065 00066 enum { 00067 SIGNAL= 0, 00068 BROADCAST= 1, 00069 MAX_EVENTS= 2 00070 } EVENTS; 00071 00072 HANDLE events[MAX_EVENTS]; 00073 HANDLE broadcast_block_event; 00074 00075 } pthread_cond_t; 00076 00077 typedef int pthread_mutexattr_t; 00078 #define win_pthread_self my_thread_var->pthread_self 00079 #ifdef OS2 00080 #define pthread_handler_t EXTERNC void * _Optlink 00081 typedef void * (_Optlink *pthread_handler)(void *); 00082 #else 00083 #define pthread_handler_t EXTERNC void * __cdecl 00084 typedef void * (__cdecl *pthread_handler)(void *); 00085 #endif 00086 00087 /* 00088 Struct and macros to be used in combination with the 00089 windows implementation of pthread_cond_timedwait 00090 */ 00091 00092 /* 00093 Declare a union to make sure FILETIME is properly aligned 00094 so it can be used directly as a 64 bit value. The value 00095 stored is in 100ns units. 00096 */ 00097 union ft64 { 00098 FILETIME ft; 00099 __int64 i64; 00100 }; 00101 struct timespec { 00102 union ft64 tv; 00103 /* The max timeout value in millisecond for pthread_cond_timedwait */ 00104 long max_timeout_msec; 00105 }; 00106 #define set_timespec(ABSTIME,SEC) { \ 00107 GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \ 00108 (ABSTIME).tv.i64+= (__int64)(SEC)*10000000; \ 00109 (ABSTIME).max_timeout_msec= (long)((SEC)*1000); \ 00110 } 00111 #define set_timespec_nsec(ABSTIME,NSEC) { \ 00112 GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \ 00113 (ABSTIME).tv.i64+= (__int64)(NSEC)/100; \ 00114 (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \ 00115 } 00116 00117 void win_pthread_init(void); 00118 int win_pthread_setspecific(void *A,void *B,uint length); 00119 int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *); 00120 int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); 00121 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); 00122 int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, 00123 struct timespec *abstime); 00124 int pthread_cond_signal(pthread_cond_t *cond); 00125 int pthread_cond_broadcast(pthread_cond_t *cond); 00126 int pthread_cond_destroy(pthread_cond_t *cond); 00127 int pthread_attr_init(pthread_attr_t *connect_att); 00128 int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack); 00129 int pthread_attr_setprio(pthread_attr_t *connect_att,int priority); 00130 int pthread_attr_destroy(pthread_attr_t *connect_att); 00131 struct tm *localtime_r(const time_t *timep,struct tm *tmp); 00132 struct tm *gmtime_r(const time_t *timep,struct tm *tmp); 00133 00134 00135 void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/ 00136 00137 #ifndef OS2 00138 #define ETIMEDOUT 145 /* Win32 doesn't have this */ 00139 #define getpid() GetCurrentThreadId() 00140 #endif 00141 #define pthread_self() win_pthread_self 00142 #define HAVE_LOCALTIME_R 1 00143 #define _REENTRANT 1 00144 #define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1 00145 00146 #ifdef USE_TLS /* For LIBMYSQL.DLL */ 00147 #undef SAFE_MUTEX /* This will cause conflicts */ 00148 #define pthread_key(T,V) DWORD V 00149 #define pthread_key_create(A,B) ((*A=TlsAlloc())==0xFFFFFFFF) 00150 #define pthread_key_delete(A) TlsFree(A) 00151 #define pthread_getspecific(A) (TlsGetValue(A)) 00152 #define my_pthread_getspecific(T,A) ((T) TlsGetValue(A)) 00153 #define my_pthread_getspecific_ptr(T,V) ((T) TlsGetValue(V)) 00154 #define my_pthread_setspecific_ptr(T,V) (!TlsSetValue((T),(V))) 00155 #define pthread_setspecific(A,B) (!TlsSetValue((A),(B))) 00156 #else 00157 #define pthread_key(T,V) __declspec(thread) T V 00158 #define pthread_key_create(A,B) pthread_dummy(0) 00159 #define pthread_key_delete(A) pthread_dummy(0) 00160 #define pthread_getspecific(A) (&(A)) 00161 #define my_pthread_getspecific(T,A) (&(A)) 00162 #define my_pthread_getspecific_ptr(T,V) (V) 00163 #define my_pthread_setspecific_ptr(T,V) ((T)=(V),0) 00164 #define pthread_setspecific(A,B) win_pthread_setspecific(&(A),(B),sizeof(A)) 00165 #endif /* USE_TLS */ 00166 00167 #define pthread_equal(A,B) ((A) == (B)) 00168 #ifdef OS2 00169 extern int pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *); 00170 extern int pthread_mutex_lock (pthread_mutex_t *); 00171 extern int pthread_mutex_unlock (pthread_mutex_t *); 00172 extern int pthread_mutex_destroy (pthread_mutex_t *); 00173 #define my_pthread_setprio(A,B) DosSetPriority(PRTYS_THREAD,PRTYC_NOCHANGE, B, A) 00174 #define pthread_kill(A,B) raise(B) 00175 #define pthread_exit(A) pthread_dummy() 00176 #else 00177 #define pthread_mutex_init(A,B) (InitializeCriticalSection(A),0) 00178 #define pthread_mutex_lock(A) (EnterCriticalSection(A),0) 00179 #define pthread_mutex_trylock(A) (WaitForSingleObject((A), 0) == WAIT_TIMEOUT) 00180 #define pthread_mutex_unlock(A) LeaveCriticalSection(A) 00181 #define pthread_mutex_destroy(A) DeleteCriticalSection(A) 00182 #define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B)) 00183 #define pthread_kill(A,B) pthread_dummy(ESRCH) 00184 #endif /* OS2 */ 00185 00186 /* Dummy defines for easier code */ 00187 #define pthread_attr_setdetachstate(A,B) pthread_dummy(0) 00188 #define my_pthread_attr_setprio(A,B) pthread_attr_setprio(A,B) 00189 #define pthread_attr_setscope(A,B) 00190 #define pthread_detach_this_thread() 00191 #define pthread_condattr_init(A) 00192 #define pthread_condattr_destroy(A) 00193 00194 #define my_pthread_getprio(thread_id) pthread_dummy(0) 00195 00196 #elif defined(HAVE_UNIXWARE7_THREADS) 00197 00198 #include <thread.h> 00199 #include <synch.h> 00200 00201 #ifndef _REENTRANT 00202 #define _REENTRANT 00203 #endif 00204 00205 #define HAVE_NONPOSIX_SIGWAIT 00206 #define pthread_t thread_t 00207 #define pthread_cond_t cond_t 00208 #define pthread_mutex_t mutex_t 00209 #define pthread_key_t thread_key_t 00210 typedef int pthread_attr_t; /* Needed by Unixware 7.0.0 */ 00211 00212 #define pthread_key_create(A,B) thr_keycreate((A),(B)) 00213 #define pthread_key_delete(A) thr_keydelete(A) 00214 00215 #define pthread_handler_t EXTERNC void * 00216 #define pthread_key(T,V) pthread_key_t V 00217 00218 void * my_pthread_getspecific_imp(pthread_key_t key); 00219 #define my_pthread_getspecific(A,B) ((A) my_pthread_getspecific_imp(B)) 00220 #define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,V) 00221 00222 #define pthread_setspecific(A,B) thr_setspecific(A,B) 00223 #define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,V) 00224 00225 #define pthread_create(A,B,C,D) thr_create(NULL,65536L,(C),(D),THR_DETACHED,(A)) 00226 #define pthread_cond_init(a,b) cond_init((a),USYNC_THREAD,NULL) 00227 #define pthread_cond_destroy(a) cond_destroy(a) 00228 #define pthread_cond_signal(a) cond_signal(a) 00229 #define pthread_cond_wait(a,b) cond_wait((a),(b)) 00230 #define pthread_cond_timedwait(a,b,c) cond_timedwait((a),(b),(c)) 00231 #define pthread_cond_broadcast(a) cond_broadcast(a) 00232 00233 #define pthread_mutex_init(a,b) mutex_init((a),USYNC_THREAD,NULL) 00234 #define pthread_mutex_lock(a) mutex_lock(a) 00235 #define pthread_mutex_unlock(a) mutex_unlock(a) 00236 #define pthread_mutex_destroy(a) mutex_destroy(a) 00237 00238 #define pthread_self() thr_self() 00239 #define pthread_exit(A) thr_exit(A) 00240 #define pthread_equal(A,B) (((A) == (B)) ? 1 : 0) 00241 #define pthread_kill(A,B) thr_kill((A),(B)) 00242 #define HAVE_PTHREAD_KILL 00243 00244 #define pthread_sigmask(A,B,C) thr_sigsetmask((A),(B),(C)) 00245 00246 extern int my_sigwait(const sigset_t *set,int *sig); 00247 00248 #define pthread_detach_this_thread() pthread_dummy(0) 00249 00250 #define pthread_attr_init(A) pthread_dummy(0) 00251 #define pthread_attr_destroy(A) pthread_dummy(0) 00252 #define pthread_attr_setscope(A,B) pthread_dummy(0) 00253 #define pthread_attr_setdetachstate(A,B) pthread_dummy(0) 00254 #define my_pthread_setprio(A,B) pthread_dummy (0) 00255 #define my_pthread_getprio(A) pthread_dummy (0) 00256 #define my_pthread_attr_setprio(A,B) pthread_dummy(0) 00257 00258 #else /* Normal threads */ 00259 00260 #ifdef HAVE_rts_threads 00261 #define sigwait org_sigwait 00262 #include <signal.h> 00263 #undef sigwait 00264 #endif 00265 #include <pthread.h> 00266 #ifndef _REENTRANT 00267 #define _REENTRANT 00268 #endif 00269 #ifdef HAVE_THR_SETCONCURRENCY 00270 #include <thread.h> /* Probably solaris */ 00271 #endif 00272 #ifdef HAVE_SCHED_H 00273 #include <sched.h> 00274 #endif 00275 #ifdef HAVE_SYNCH_H 00276 #include <synch.h> 00277 #endif 00278 #if defined(__EMX__) && (!defined(EMX_PTHREAD_REV) || (EMX_PTHREAD_REV < 2)) 00279 #error Requires at least rev 2 of EMX pthreads library. 00280 #endif 00281 00282 #ifdef __NETWARE__ 00283 void my_pthread_exit(void *status); 00284 #define pthread_exit(A) my_pthread_exit(A) 00285 #endif 00286 00287 extern int my_pthread_getprio(pthread_t thread_id); 00288 00289 #define pthread_key(T,V) pthread_key_t V 00290 #define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,(V)) 00291 #define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,(void*) (V)) 00292 #define pthread_detach_this_thread() 00293 #define pthread_handler_t EXTERNC void * 00294 typedef void *(* pthread_handler)(void *); 00295 00296 /* Test first for RTS or FSU threads */ 00297 00298 #if defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) 00299 #define HAVE_rts_threads 00300 extern int my_pthread_create_detached; 00301 #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) 00302 #define PTHREAD_CREATE_DETACHED &my_pthread_create_detached 00303 #define PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_GLOBAL 00304 #define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_LOCAL 00305 #define USE_ALARM_THREAD 00306 #elif defined(HAVE_mit_thread) 00307 #define USE_ALARM_THREAD 00308 #undef HAVE_LOCALTIME_R 00309 #define HAVE_LOCALTIME_R 00310 #undef HAVE_GMTIME_R 00311 #define HAVE_GMTIME_R 00312 #undef HAVE_PTHREAD_ATTR_SETSCOPE 00313 #define HAVE_PTHREAD_ATTR_SETSCOPE 00314 #undef HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE /* If we are running linux */ 00315 #undef HAVE_RWLOCK_T 00316 #undef HAVE_RWLOCK_INIT 00317 #undef HAVE_PTHREAD_RWLOCK_RDLOCK 00318 #undef HAVE_SNPRINTF 00319 00320 #define my_pthread_attr_setprio(A,B) 00321 #endif /* defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) */ 00322 00323 #if defined(_BSDI_VERSION) && _BSDI_VERSION < 199910 00324 int sigwait(sigset_t *set, int *sig); 00325 #endif 00326 00327 #ifndef HAVE_NONPOSIX_SIGWAIT 00328 #define my_sigwait(A,B) sigwait((A),(B)) 00329 #else 00330 int my_sigwait(const sigset_t *set,int *sig); 00331 #endif 00332 00333 #ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT 00334 #ifndef SAFE_MUTEX 00335 #define pthread_mutex_init(a,b) my_pthread_mutex_init((a),(b)) 00336 extern int my_pthread_mutex_init(pthread_mutex_t *mp, 00337 const pthread_mutexattr_t *attr); 00338 #endif /* SAFE_MUTEX */ 00339 #define pthread_cond_init(a,b) my_pthread_cond_init((a),(b)) 00340 extern int my_pthread_cond_init(pthread_cond_t *mp, 00341 const pthread_condattr_t *attr); 00342 #endif /* HAVE_NONPOSIX_PTHREAD_MUTEX_INIT */ 00343 00344 #if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK) 00345 #define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C)) 00346 #endif 00347 00348 #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) 00349 int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */ 00350 #endif 00351 00352 00353 /* 00354 We define my_sigset() and use that instead of the system sigset() so that 00355 we can favor an implementation based on sigaction(). On some systems, such 00356 as Mac OS X, sigset() results in flags such as SA_RESTART being set, and 00357 we want to make sure that no such flags are set. 00358 */ 00359 #if defined(HAVE_SIGACTION) && !defined(my_sigset) 00360 #define my_sigset(A,B) do { struct sigaction l_s; sigset_t l_set; int l_rc; \ 00361 DBUG_ASSERT((A) != 0); \ 00362 sigemptyset(&l_set); \ 00363 l_s.sa_handler = (B); \ 00364 l_s.sa_mask = l_set; \ 00365 l_s.sa_flags = 0; \ 00366 l_rc= sigaction((A), &l_s, (struct sigaction *) NULL);\ 00367 DBUG_ASSERT(l_rc == 0); \ 00368 } while (0) 00369 #elif defined(HAVE_SIGSET) && !defined(my_sigset) 00370 #define my_sigset(A,B) sigset((A),(B)) 00371 #elif !defined(my_sigset) 00372 #define my_sigset(A,B) signal((A),(B)) 00373 #endif 00374 00375 #ifndef my_pthread_setprio 00376 #if defined(HAVE_PTHREAD_SETPRIO_NP) /* FSU threads */ 00377 #define my_pthread_setprio(A,B) pthread_setprio_np((A),(B)) 00378 #elif defined(HAVE_PTHREAD_SETPRIO) 00379 #define my_pthread_setprio(A,B) pthread_setprio((A),(B)) 00380 #else 00381 extern void my_pthread_setprio(pthread_t thread_id,int prior); 00382 #endif 00383 #endif 00384 00385 #ifndef my_pthread_attr_setprio 00386 #ifdef HAVE_PTHREAD_ATTR_SETPRIO 00387 #define my_pthread_attr_setprio(A,B) pthread_attr_setprio((A),(B)) 00388 #else 00389 extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority); 00390 #endif 00391 #endif 00392 00393 #if !defined(HAVE_PTHREAD_ATTR_SETSCOPE) || defined(HAVE_DEC_3_2_THREADS) 00394 #define pthread_attr_setscope(A,B) 00395 #undef HAVE_GETHOSTBYADDR_R /* No definition */ 00396 #endif 00397 00398 #if defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT) && !defined(SAFE_MUTEX) 00399 extern int my_pthread_cond_timedwait(pthread_cond_t *cond, 00400 pthread_mutex_t *mutex, 00401 struct timespec *abstime); 00402 #define pthread_cond_timedwait(A,B,C) my_pthread_cond_timedwait((A),(B),(C)) 00403 #endif 00404 00405 #if defined(OS2) 00406 #define my_pthread_getspecific(T,A) ((T) &(A)) 00407 #define pthread_setspecific(A,B) win_pthread_setspecific(&(A),(B),sizeof(A)) 00408 #elif !defined( HAVE_NONPOSIX_PTHREAD_GETSPECIFIC) 00409 #define my_pthread_getspecific(A,B) ((A) pthread_getspecific(B)) 00410 #else 00411 #define my_pthread_getspecific(A,B) ((A) my_pthread_getspecific_imp(B)) 00412 void *my_pthread_getspecific_imp(pthread_key_t key); 00413 #endif /* OS2 */ 00414 00415 #ifndef HAVE_LOCALTIME_R 00416 struct tm *localtime_r(const time_t *clock, struct tm *res); 00417 #endif 00418 00419 #ifndef HAVE_GMTIME_R 00420 struct tm *gmtime_r(const time_t *clock, struct tm *res); 00421 #endif 00422 00423 #ifdef HAVE_PTHREAD_CONDATTR_CREATE 00424 /* DCE threads on HPUX 10.20 */ 00425 #define pthread_condattr_init pthread_condattr_create 00426 #define pthread_condattr_destroy pthread_condattr_delete 00427 #endif 00428 00429 /* FSU THREADS */ 00430 #if !defined(HAVE_PTHREAD_KEY_DELETE) && !defined(pthread_key_delete) 00431 #define pthread_key_delete(A) pthread_dummy(0) 00432 #endif 00433 00434 #ifdef HAVE_CTHREADS_WRAPPER /* For MacOSX */ 00435 #define pthread_cond_destroy(A) pthread_dummy(0) 00436 #define pthread_mutex_destroy(A) pthread_dummy(0) 00437 #define pthread_attr_delete(A) pthread_dummy(0) 00438 #define pthread_condattr_delete(A) pthread_dummy(0) 00439 #define pthread_attr_setstacksize(A,B) pthread_dummy(0) 00440 #define pthread_equal(A,B) ((A) == (B)) 00441 #define pthread_cond_timedwait(a,b,c) pthread_cond_wait((a),(b)) 00442 #define pthread_attr_init(A) pthread_attr_create(A) 00443 #define pthread_attr_destroy(A) pthread_attr_delete(A) 00444 #define pthread_attr_setdetachstate(A,B) pthread_dummy(0) 00445 #define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D)) 00446 #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) 00447 #define pthread_kill(A,B) pthread_dummy(ESRCH) 00448 #undef pthread_detach_this_thread 00449 #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); } 00450 #endif 00451 00452 #ifdef HAVE_DARWIN5_THREADS 00453 #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) 00454 #define pthread_kill(A,B) pthread_dummy(ESRCH) 00455 #define pthread_condattr_init(A) pthread_dummy(0) 00456 #define pthread_condattr_destroy(A) pthread_dummy(0) 00457 #undef pthread_detach_this_thread 00458 #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(tmp); } 00459 #endif 00460 00461 #if ((defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT)) || defined(HAVE_DEC_3_2_THREADS)) && !defined(HAVE_CTHREADS_WRAPPER) 00462 /* This is set on AIX_3_2 and Siemens unix (and DEC OSF/1 3.2 too) */ 00463 #define pthread_key_create(A,B) \ 00464 pthread_keycreate(A,(B) ?\ 00465 (pthread_destructor_t) (B) :\ 00466 (pthread_destructor_t) pthread_dummy) 00467 #define pthread_attr_init(A) pthread_attr_create(A) 00468 #define pthread_attr_destroy(A) pthread_attr_delete(A) 00469 #define pthread_attr_setdetachstate(A,B) pthread_dummy(0) 00470 #define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D)) 00471 #ifndef pthread_sigmask 00472 #define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C)) 00473 #endif 00474 #define pthread_kill(A,B) pthread_dummy(ESRCH) 00475 #undef pthread_detach_this_thread 00476 #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); } 00477 #elif !defined(__NETWARE__) /* HAVE_PTHREAD_ATTR_CREATE && !HAVE_SIGWAIT */ 00478 #define HAVE_PTHREAD_KILL 00479 #endif 00480 00481 #endif /* defined(__WIN__) */ 00482 00483 #if defined(HPUX10) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS) 00484 #undef pthread_cond_timedwait 00485 #define pthread_cond_timedwait(a,b,c) my_pthread_cond_timedwait((a),(b),(c)) 00486 int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, 00487 struct timespec *abstime); 00488 #endif 00489 00490 #if defined(HPUX10) 00491 #define pthread_attr_getstacksize(A,B) my_pthread_attr_getstacksize(A,B) 00492 void my_pthread_attr_getstacksize(pthread_attr_t *attrib, size_t *size); 00493 #endif 00494 00495 #if defined(HAVE_POSIX1003_4a_MUTEX) && !defined(DONT_REMAP_PTHREAD_FUNCTIONS) 00496 #undef pthread_mutex_trylock 00497 #define pthread_mutex_trylock(a) my_pthread_mutex_trylock((a)) 00498 int my_pthread_mutex_trylock(pthread_mutex_t *mutex); 00499 #endif 00500 00501 /* 00502 The defines set_timespec and set_timespec_nsec should be used 00503 for calculating an absolute time at which 00504 pthread_cond_timedwait should timeout 00505 */ 00506 #ifdef HAVE_TIMESPEC_TS_SEC 00507 #ifndef set_timespec 00508 #define set_timespec(ABSTIME,SEC) \ 00509 { \ 00510 (ABSTIME).ts_sec=time(0) + (time_t) (SEC); \ 00511 (ABSTIME).ts_nsec=0; \ 00512 } 00513 #endif /* !set_timespec */ 00514 #ifndef set_timespec_nsec 00515 #define set_timespec_nsec(ABSTIME,NSEC) \ 00516 { \ 00517 ulonglong now= my_getsystime() + (NSEC/100); \ 00518 (ABSTIME).ts_sec= (now / ULL(10000000)); \ 00519 (ABSTIME).ts_nsec= (now % ULL(10000000) * 100 + ((NSEC) % 100)); \ 00520 } 00521 #endif /* !set_timespec_nsec */ 00522 #else 00523 #ifndef set_timespec 00524 #define set_timespec(ABSTIME,SEC) \ 00525 {\ 00526 struct timeval tv;\ 00527 gettimeofday(&tv,0);\ 00528 (ABSTIME).tv_sec=tv.tv_sec+(time_t) (SEC);\ 00529 (ABSTIME).tv_nsec=tv.tv_usec*1000;\ 00530 } 00531 #endif /* !set_timespec */ 00532 #ifndef set_timespec_nsec 00533 #define set_timespec_nsec(ABSTIME,NSEC) \ 00534 {\ 00535 ulonglong now= my_getsystime() + (NSEC/100); \ 00536 (ABSTIME).tv_sec= (time_t) (now / ULL(10000000)); \ 00537 (ABSTIME).tv_nsec= (long) (now % ULL(10000000) * 100 + ((NSEC) % 100)); \ 00538 } 00539 #endif /* !set_timespec_nsec */ 00540 #endif /* HAVE_TIMESPEC_TS_SEC */ 00541 00542 /* safe_mutex adds checking to mutex for easier debugging */ 00543 00544 #if defined(__NETWARE__) && !defined(SAFE_MUTEX_DETECT_DESTROY) 00545 #define SAFE_MUTEX_DETECT_DESTROY 00546 #endif 00547 00548 typedef struct st_safe_mutex_t 00549 { 00550 pthread_mutex_t global,mutex; 00551 const char *file; 00552 uint line,count; 00553 pthread_t thread; 00554 #ifdef SAFE_MUTEX_DETECT_DESTROY 00555 struct st_safe_mutex_info_t *info; /* to track destroying of mutexes */ 00556 #endif 00557 } safe_mutex_t; 00558 00559 #ifdef SAFE_MUTEX_DETECT_DESTROY 00560 /* 00561 Used to track the destroying of mutexes. This needs to be a seperate 00562 structure because the safe_mutex_t structure could be freed before 00563 the mutexes are destroyed. 00564 */ 00565 00566 typedef struct st_safe_mutex_info_t 00567 { 00568 struct st_safe_mutex_info_t *next; 00569 struct st_safe_mutex_info_t *prev; 00570 const char *init_file; 00571 uint32 init_line; 00572 } safe_mutex_info_t; 00573 #endif /* SAFE_MUTEX_DETECT_DESTROY */ 00574 00575 int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr, 00576 const char *file, uint line); 00577 int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line); 00578 int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line); 00579 int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line); 00580 int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file, 00581 uint line); 00582 int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, 00583 struct timespec *abstime, const char *file, uint line); 00584 void safe_mutex_global_init(void); 00585 void safe_mutex_end(FILE *file); 00586 00587 /* Wrappers if safe mutex is actually used */ 00588 #ifdef SAFE_MUTEX 00589 #undef pthread_mutex_init 00590 #undef pthread_mutex_lock 00591 #undef pthread_mutex_unlock 00592 #undef pthread_mutex_destroy 00593 #undef pthread_mutex_wait 00594 #undef pthread_mutex_timedwait 00595 #undef pthread_mutex_t 00596 #undef pthread_cond_wait 00597 #undef pthread_cond_timedwait 00598 #undef pthread_mutex_trylock 00599 #define pthread_mutex_init(A,B) safe_mutex_init((A),(B),__FILE__,__LINE__) 00600 #define pthread_mutex_lock(A) safe_mutex_lock((A),__FILE__,__LINE__) 00601 #define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__) 00602 #define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__) 00603 #define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__) 00604 #define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__) 00605 #define pthread_mutex_trylock(A) pthread_mutex_lock(A) 00606 #define pthread_mutex_t safe_mutex_t 00607 #define safe_mutex_assert_owner(mp) \ 00608 DBUG_ASSERT((mp)->count > 0 && \ 00609 pthread_equal(pthread_self(), (mp)->thread)) 00610 #define safe_mutex_assert_not_owner(mp) \ 00611 DBUG_ASSERT(! (mp)->count || \ 00612 ! pthread_equal(pthread_self(), (mp)->thread)) 00613 #else 00614 #define safe_mutex_assert_owner(mp) 00615 #define safe_mutex_assert_not_owner(mp) 00616 #endif /* SAFE_MUTEX */ 00617 00618 /* READ-WRITE thread locking */ 00619 00620 #ifdef HAVE_BROKEN_RWLOCK /* For OpenUnix */ 00621 #undef HAVE_PTHREAD_RWLOCK_RDLOCK 00622 #undef HAVE_RWLOCK_INIT 00623 #undef HAVE_RWLOCK_T 00624 #endif 00625 00626 #if defined(USE_MUTEX_INSTEAD_OF_RW_LOCKS) 00627 /* use these defs for simple mutex locking */ 00628 #define rw_lock_t pthread_mutex_t 00629 #define my_rwlock_init(A,B) pthread_mutex_init((A),(B)) 00630 #define rw_rdlock(A) pthread_mutex_lock((A)) 00631 #define rw_wrlock(A) pthread_mutex_lock((A)) 00632 #define rw_tryrdlock(A) pthread_mutex_trylock((A)) 00633 #define rw_trywrlock(A) pthread_mutex_trylock((A)) 00634 #define rw_unlock(A) pthread_mutex_unlock((A)) 00635 #define rwlock_destroy(A) pthread_mutex_destroy((A)) 00636 #elif defined(HAVE_PTHREAD_RWLOCK_RDLOCK) 00637 #define rw_lock_t pthread_rwlock_t 00638 #define my_rwlock_init(A,B) pthread_rwlock_init((A),(B)) 00639 #define rw_rdlock(A) pthread_rwlock_rdlock(A) 00640 #define rw_wrlock(A) pthread_rwlock_wrlock(A) 00641 #define rw_tryrdlock(A) pthread_rwlock_tryrdlock((A)) 00642 #define rw_trywrlock(A) pthread_rwlock_trywrlock((A)) 00643 #define rw_unlock(A) pthread_rwlock_unlock(A) 00644 #define rwlock_destroy(A) pthread_rwlock_destroy(A) 00645 #elif defined(HAVE_RWLOCK_INIT) 00646 #ifdef HAVE_RWLOCK_T /* For example Solaris 2.6-> */ 00647 #define rw_lock_t rwlock_t 00648 #endif 00649 #define my_rwlock_init(A,B) rwlock_init((A),USYNC_THREAD,0) 00650 #else 00651 /* Use our own version of read/write locks */ 00652 typedef struct _my_rw_lock_t { 00653 pthread_mutex_t lock; /* lock for structure */ 00654 pthread_cond_t readers; /* waiting readers */ 00655 pthread_cond_t writers; /* waiting writers */ 00656 int state; /* -1:writer,0:free,>0:readers */ 00657 int waiters; /* number of waiting writers */ 00658 } my_rw_lock_t; 00659 00660 #define rw_lock_t my_rw_lock_t 00661 #define rw_rdlock(A) my_rw_rdlock((A)) 00662 #define rw_wrlock(A) my_rw_wrlock((A)) 00663 #define rw_tryrdlock(A) my_rw_tryrdlock((A)) 00664 #define rw_trywrlock(A) my_rw_trywrlock((A)) 00665 #define rw_unlock(A) my_rw_unlock((A)) 00666 #define rwlock_destroy(A) my_rwlock_destroy((A)) 00667 00668 extern int my_rwlock_init(my_rw_lock_t *, void *); 00669 extern int my_rwlock_destroy(my_rw_lock_t *); 00670 extern int my_rw_rdlock(my_rw_lock_t *); 00671 extern int my_rw_wrlock(my_rw_lock_t *); 00672 extern int my_rw_unlock(my_rw_lock_t *); 00673 extern int my_rw_tryrdlock(my_rw_lock_t *); 00674 extern int my_rw_trywrlock(my_rw_lock_t *); 00675 #endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */ 00676 00677 #define GETHOSTBYADDR_BUFF_SIZE 2048 00678 00679 #ifndef HAVE_THR_SETCONCURRENCY 00680 #define thr_setconcurrency(A) pthread_dummy(0) 00681 #endif 00682 #if !defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && ! defined(pthread_attr_setstacksize) 00683 #define pthread_attr_setstacksize(A,B) pthread_dummy(0) 00684 #endif 00685 00686 /* Define mutex types, see my_thr_init.c */ 00687 #define MY_MUTEX_INIT_SLOW NULL 00688 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP 00689 extern pthread_mutexattr_t my_fast_mutexattr; 00690 #define MY_MUTEX_INIT_FAST &my_fast_mutexattr 00691 #else 00692 #define MY_MUTEX_INIT_FAST NULL 00693 #endif 00694 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP 00695 extern pthread_mutexattr_t my_errorcheck_mutexattr; 00696 #define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr 00697 #else 00698 #define MY_MUTEX_INIT_ERRCHK NULL 00699 #endif 00700 00701 #ifndef ESRCH 00702 /* Define it to something */ 00703 #define ESRCH 1 00704 #endif 00705 00706 extern my_bool my_thread_global_init(void); 00707 extern void my_thread_global_end(void); 00708 extern my_bool my_thread_init(void); 00709 extern void my_thread_end(void); 00710 extern const char *my_thread_name(void); 00711 extern long my_thread_id(void); 00712 extern int pthread_no_free(void *); 00713 extern int pthread_dummy(int); 00714 00715 /* All thread specific variables are in the following struct */ 00716 00717 #define THREAD_NAME_SIZE 10 00718 #ifndef DEFAULT_THREAD_STACK 00719 #if SIZEOF_CHARP > 4 00720 /* 00721 MySQL can survive with 32K, but some glibc libraries require > 128K stack 00722 To resolve hostnames. Also recursive stored procedures needs stack. 00723 */ 00724 #define DEFAULT_THREAD_STACK (256*1024L) 00725 #else 00726 #define DEFAULT_THREAD_STACK (192*1024) 00727 #endif 00728 #endif 00729 00730 struct st_my_thread_var 00731 { 00732 int thr_errno; 00733 pthread_cond_t suspend; 00734 pthread_mutex_t mutex; 00735 pthread_mutex_t * volatile current_mutex; 00736 pthread_cond_t * volatile current_cond; 00737 pthread_t pthread_self; 00738 long id; 00739 int cmp_length; 00740 int volatile abort; 00741 my_bool init; 00742 struct st_my_thread_var *next,**prev; 00743 void *opt_info; 00744 #ifndef DBUG_OFF 00745 gptr dbug; 00746 char name[THREAD_NAME_SIZE+1]; 00747 #endif 00748 }; 00749 00750 extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const)); 00751 extern uint my_thread_end_wait_time; 00752 #define my_thread_var (_my_thread_var()) 00753 #define my_errno my_thread_var->thr_errno 00754 /* 00755 Keep track of shutdown,signal, and main threads so that my_end() will not 00756 report errors with them 00757 */ 00758 00759 /* Which kind of thread library is in use */ 00760 00761 #define THD_LIB_OTHER 1 00762 #define THD_LIB_NPTL 2 00763 #define THD_LIB_LT 4 00764 00765 extern uint thd_lib_detected; 00766 00767 /* statistics_xxx functions are for not essential statistic */ 00768 00769 #ifndef thread_safe_increment 00770 #ifdef HAVE_ATOMIC_ADD 00771 #define thread_safe_increment(V,L) atomic_inc((atomic_t*) &V) 00772 #define thread_safe_decrement(V,L) atomic_dec((atomic_t*) &V) 00773 #define thread_safe_add(V,C,L) atomic_add((C),(atomic_t*) &V) 00774 #define thread_safe_sub(V,C,L) atomic_sub((C),(atomic_t*) &V) 00775 #else 00776 #define thread_safe_increment(V,L) \ 00777 (pthread_mutex_lock((L)), (V)++, pthread_mutex_unlock((L))) 00778 #define thread_safe_decrement(V,L) \ 00779 (pthread_mutex_lock((L)), (V)--, pthread_mutex_unlock((L))) 00780 #define thread_safe_add(V,C,L) (pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L))) 00781 #define thread_safe_sub(V,C,L) \ 00782 (pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L))) 00783 #endif /* HAVE_ATOMIC_ADD */ 00784 #ifdef SAFE_STATISTICS 00785 #define statistic_increment(V,L) thread_safe_increment((V),(L)) 00786 #define statistic_decrement(V,L) thread_safe_decrement((V),(L)) 00787 #define statistic_add(V,C,L) thread_safe_add((V),(C),(L)) 00788 #else 00789 #define statistic_decrement(V,L) (V)-- 00790 #define statistic_increment(V,L) (V)++ 00791 #define statistic_add(V,C,L) (V)+=(C) 00792 #endif /* SAFE_STATISTICS */ 00793 #endif /* thread_safe_increment */ 00794 00795 #ifdef __cplusplus 00796 } 00797 #endif 00798 #endif /* _my_ptread_h */