home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / mysys / my_thr_init.c < prev    next >
C/C++ Source or Header  |  2000-09-21  |  5KB  |  205 lines

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This library is free software; you can redistribute it and/or
  4.    modify it under the terms of the GNU Library General Public
  5.    License as published by the Free Software Foundation; either
  6.    version 2 of the License, or (at your option) any later version.
  7.    
  8.    This library is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11.    Library General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU Library General Public
  14.    License along with this library; if not, write to the Free
  15.    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  16.    MA 02111-1307, USA */
  17.  
  18. /*
  19. ** Functions to handle initializating and allocationg of all mysys & debug
  20. ** thread variables.
  21. */
  22.  
  23. #include "mysys_priv.h"
  24. #include <m_string.h>
  25.  
  26. #ifdef THREAD
  27. #ifdef USE_TLS
  28. pthread_key(struct st_my_thread_var*, THR_KEY_mysys);
  29. #else
  30. pthread_key(struct st_my_thread_var, THR_KEY_mysys);
  31. #endif
  32. pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache,
  33.             THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap,
  34.             THR_LOCK_net, THR_LOCK_charset; 
  35. #ifndef HAVE_LOCALTIME_R
  36. pthread_mutex_t LOCK_localtime_r;
  37. #endif
  38.  
  39. /* FIXME  Note.  TlsAlloc does not set an auto destructor, so
  40.     the function my_thread_global_free must be called from
  41.     somewhere before final exit of the library */
  42.  
  43. my_bool my_thread_global_init(void)
  44. {
  45.   if (pthread_key_create(&THR_KEY_mysys,free))
  46.   {
  47.     fprintf(stderr,"Can't initialize threads: error %d\n",errno);
  48.     exit(1);
  49.   }
  50.   pthread_mutex_init(&THR_LOCK_malloc,NULL);
  51.   pthread_mutex_init(&THR_LOCK_open,NULL);
  52.   pthread_mutex_init(&THR_LOCK_keycache,NULL);
  53.   pthread_mutex_init(&THR_LOCK_lock,NULL);
  54.   pthread_mutex_init(&THR_LOCK_isam,NULL);
  55.   pthread_mutex_init(&THR_LOCK_myisam,NULL);
  56.   pthread_mutex_init(&THR_LOCK_heap,NULL);
  57.   pthread_mutex_init(&THR_LOCK_net,NULL);
  58.   pthread_mutex_init(&THR_LOCK_charset,NULL);
  59. #ifdef __WIN__
  60.   win_pthread_init();
  61. #endif
  62. #ifndef HAVE_LOCALTIME_R
  63.   pthread_mutex_init(&LOCK_localtime_r,NULL);
  64. #endif
  65.   return my_thread_init();
  66. }
  67.  
  68. void my_thread_global_end(void)
  69. {
  70. #if defined(USE_TLS)
  71.   (void) TlsFree(THR_KEY_mysys);
  72. #endif
  73. }
  74.  
  75. static long thread_id=0;
  76.  
  77. /*
  78.   We can't use mutex_locks here if we are using windows as
  79.   we may have compiled the program with SAFE_MUTEX, in which
  80.   case the checking of mutex_locks will not work until
  81.   the pthread_self thread specific variable is initialized.
  82. */
  83.  
  84. my_bool my_thread_init(void)
  85. {
  86.   struct st_my_thread_var *tmp;
  87. #if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
  88.   pthread_mutex_lock(&THR_LOCK_lock);
  89. #endif
  90. #if !defined(__WIN__) || defined(USE_TLS)
  91.   if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys))
  92.   {
  93.     pthread_mutex_unlock(&THR_LOCK_lock);
  94.     return 0;                        /* Safequard */
  95.   }
  96.     /* We must have many calloc() here because these are freed on
  97.        pthread_exit */
  98.   if (!(tmp=(struct st_my_thread_var *)
  99.     calloc(1,sizeof(struct st_my_thread_var))))
  100.   {
  101.     pthread_mutex_unlock(&THR_LOCK_lock);
  102.     return 1;
  103.   }
  104.   pthread_setspecific(THR_KEY_mysys,tmp);
  105.  
  106. #else
  107.   if (THR_KEY_mysys.id)   /* Already initialized */
  108.   {
  109. #if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
  110.     pthread_mutex_unlock(&THR_LOCK_lock);
  111. #endif
  112.     return 0;
  113.   }
  114.   tmp= &THR_KEY_mysys;
  115. #endif
  116.   tmp->id= ++thread_id;
  117.   pthread_mutex_init(&tmp->mutex,NULL);
  118.   pthread_cond_init(&tmp->suspend, NULL);
  119. #if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
  120.   pthread_mutex_unlock(&THR_LOCK_lock);
  121. #endif
  122.   return 0;
  123. }
  124.  
  125. void my_thread_end(void)
  126. {
  127.   struct st_my_thread_var *tmp=my_thread_var;
  128.   if (tmp)
  129.   {
  130. #if !defined(DBUG_OFF)
  131.     if (tmp->dbug)
  132.     {
  133.       free(tmp->dbug);
  134.       tmp->dbug=0;
  135.     }
  136. #endif
  137. #if !defined(__bsdi__) || defined(HAVE_mit_thread) /* bsdi dumps core here */
  138.     pthread_cond_destroy(&tmp->suspend);
  139. #endif
  140.     pthread_mutex_destroy(&tmp->mutex);
  141. #if !defined(__WIN__) || defined(USE_TLS)
  142.     free(tmp);
  143. #endif
  144.   }
  145. #if !defined(__WIN__) || defined(USE_TLS)
  146.   pthread_setspecific(THR_KEY_mysys,0);
  147. #endif
  148. }
  149.  
  150. struct st_my_thread_var *_my_thread_var(void)
  151. {
  152.   struct st_my_thread_var *tmp=
  153.     my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
  154. #if defined(USE_TLS)
  155.   /* This can only happen in a .DLL */
  156.   if (!tmp)
  157.   {
  158.     my_thread_init();
  159.     tmp=my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
  160.   }
  161. #endif
  162.   return tmp;
  163. }
  164.  
  165. /****************************************************************************
  166. ** Get name of current thread.
  167. ****************************************************************************/
  168.  
  169. #define UNKNOWN_THREAD -1
  170.  
  171. long my_thread_id()
  172. {
  173. #if defined(HAVE_PTHREAD_GETSEQUENCE_NP)
  174.   return pthread_getsequence_np(pthread_self());
  175. #elif (defined(__sun) || defined(__sgi) || defined(__linux__)) && !defined(HAVE_mit_thread)
  176.   return pthread_self();
  177. #else
  178.   return my_thread_var->id;
  179. #endif
  180. }
  181.  
  182. #ifdef DBUG_OFF
  183. char *my_thread_name(void)
  184. {
  185.   return "no_name";
  186. }
  187.  
  188. #else
  189.  
  190. char *my_thread_name(void)
  191. {
  192.   char name_buff[100];
  193.   struct st_my_thread_var *tmp=my_thread_var;
  194.   if (!tmp->name[0])
  195.   {
  196.     long id=my_thread_id();
  197.     sprintf(name_buff,"T@%ld", id);
  198.     strmake(tmp->name,name_buff,THREAD_NAME_SIZE);
  199.   }
  200.   return tmp->name;
  201. }
  202. #endif /* DBUG_OFF */
  203.  
  204. #endif /* THREAD */
  205.