Eneboo - Documentación para desarrolladores
src/libmysql_std/include/my_pthread.h
Ir a la documentación de este archivo.
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 */
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Propiedades Amigas 'defines'