Annotation of win32/sql/mysql/include/my_pthread.h, revision 1.2

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

E-mail: