~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_thr_init.c

  • Committer: Brian Aker
  • Date: 2008-10-06 06:47:29 UTC
  • Revision ID: brian@tangent.org-20081006064729-2i9mhjkzyvow9xsm
Remove uint.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
  thread variables.
19
19
*/
20
20
 
21
 
#include "mysys/mysys_priv.h"
22
 
#include <mysys/my_pthread.h>
 
21
#include "mysys_priv.h"
23
22
#include <mystrings/m_string.h>
24
 
 
25
 
#include <stdio.h>
26
23
#include <signal.h>
27
24
 
28
 
#if TIME_WITH_SYS_TIME
29
 
# include <sys/time.h>
30
 
# include <time.h>
31
 
#else
32
 
# if HAVE_SYS_TIME_H
33
 
#  include <sys/time.h>
34
 
# else
35
 
#  include <time.h>
36
 
# endif
37
 
#endif
38
 
 
39
25
uint32_t thd_lib_detected= 0;
40
26
 
41
 
pthread_key_t THR_KEY_mysys;
42
 
pthread_mutex_t THR_LOCK_lock;
43
 
pthread_mutex_t THR_LOCK_threads;
 
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 /* USE_TLS */
 
32
pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,
 
33
                THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap,
 
34
                THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time;
44
35
pthread_cond_t  THR_COND_threads;
45
36
uint32_t            THR_thread_count= 0;
46
37
uint32_t                my_thread_end_wait_time= 5;
 
38
#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
 
39
pthread_mutex_t LOCK_localtime_r;
 
40
#endif
 
41
#ifndef HAVE_GETHOSTBYNAME_R
 
42
pthread_mutex_t LOCK_gethostbyname_r;
 
43
#endif
47
44
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
48
45
pthread_mutexattr_t my_fast_mutexattr;
49
46
#endif
51
48
pthread_mutexattr_t my_errorcheck_mutexattr;
52
49
#endif
53
50
 
 
51
#ifdef TARGET_OS_LINUX
 
52
 
 
53
/*
 
54
  Dummy thread spawned in my_thread_global_init() below to avoid
 
55
  race conditions in NPTL pthread_exit code.
 
56
*/
 
57
 
 
58
static pthread_handler_t
 
59
nptl_pthread_exit_hack_handler(void *arg __attribute((unused)))
 
60
{
 
61
  /* Do nothing! */
 
62
  pthread_exit(0);
 
63
  return 0;
 
64
}
 
65
 
 
66
#endif /* TARGET_OS_LINUX */
 
67
 
54
68
 
55
69
static uint32_t get_thread_lib(void);
56
70
 
76
90
    return 1;
77
91
  }
78
92
 
 
93
#ifdef TARGET_OS_LINUX
 
94
  /*
 
95
    BUG#24507: Race conditions inside current NPTL pthread_exit()
 
96
    implementation.
 
97
 
 
98
    To avoid a possible segmentation fault during concurrent
 
99
    executions of pthread_exit(), a dummy thread is spawned which
 
100
    initializes internal variables of pthread lib. See bug description
 
101
    for a full explanation.
 
102
 
 
103
    TODO: Remove this code when fixed versions of glibc6 are in common
 
104
    use.
 
105
  */
 
106
  if (thd_lib_detected == THD_LIB_NPTL)
 
107
  {
 
108
    pthread_t       dummy_thread;
 
109
    pthread_attr_t  dummy_thread_attr;
 
110
 
 
111
    pthread_attr_init(&dummy_thread_attr);
 
112
    pthread_attr_setdetachstate(&dummy_thread_attr, PTHREAD_CREATE_DETACHED);
 
113
 
 
114
    pthread_create(&dummy_thread,&dummy_thread_attr,
 
115
                   nptl_pthread_exit_hack_handler, NULL);
 
116
  }
 
117
#endif /* TARGET_OS_LINUX */
 
118
 
79
119
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
80
120
  /*
81
121
    Set mutex type to "fast" a.k.a "adaptive"
99
139
                            PTHREAD_MUTEX_ERRORCHECK);
100
140
#endif
101
141
 
 
142
  pthread_mutex_init(&THR_LOCK_malloc,MY_MUTEX_INIT_FAST);
 
143
  pthread_mutex_init(&THR_LOCK_open,MY_MUTEX_INIT_FAST);
102
144
  pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST);
 
145
  pthread_mutex_init(&THR_LOCK_isam,MY_MUTEX_INIT_SLOW);
 
146
  pthread_mutex_init(&THR_LOCK_myisam,MY_MUTEX_INIT_SLOW);
 
147
  pthread_mutex_init(&THR_LOCK_heap,MY_MUTEX_INIT_FAST);
 
148
  pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST);
 
149
  pthread_mutex_init(&THR_LOCK_charset,MY_MUTEX_INIT_FAST);
103
150
  pthread_mutex_init(&THR_LOCK_threads,MY_MUTEX_INIT_FAST);
 
151
  pthread_mutex_init(&THR_LOCK_time,MY_MUTEX_INIT_FAST);
104
152
  pthread_cond_init(&THR_COND_threads, NULL);
 
153
#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
 
154
  pthread_mutex_init(&LOCK_localtime_r,MY_MUTEX_INIT_SLOW);
 
155
#endif
 
156
#ifndef HAVE_GETHOSTBYNAME_R
 
157
  pthread_mutex_init(&LOCK_gethostbyname_r,MY_MUTEX_INIT_SLOW);
 
158
#endif
105
159
  if (my_thread_init())
106
160
  {
107
161
    my_thread_global_end();                     /* Clean up */
124
178
                                      &abstime);
125
179
    if (error == ETIMEDOUT || error == ETIME)
126
180
    {
 
181
#ifdef HAVE_PTHREAD_KILL
127
182
      /*
128
183
        We shouldn't give an error here, because if we don't have
129
184
        pthread_kill(), programs like mysqld can't ensure that all threads
133
188
        fprintf(stderr,
134
189
                "Error in my_thread_global_end(): %d threads didn't exit\n",
135
190
                THR_thread_count);
 
191
#endif
136
192
      all_threads_killed= 0;
137
193
      break;
138
194
    }
146
202
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
147
203
  pthread_mutexattr_destroy(&my_errorcheck_mutexattr);
148
204
#endif
 
205
  pthread_mutex_destroy(&THR_LOCK_malloc);
 
206
  pthread_mutex_destroy(&THR_LOCK_open);
149
207
  pthread_mutex_destroy(&THR_LOCK_lock);
 
208
  pthread_mutex_destroy(&THR_LOCK_isam);
 
209
  pthread_mutex_destroy(&THR_LOCK_myisam);
 
210
  pthread_mutex_destroy(&THR_LOCK_heap);
 
211
  pthread_mutex_destroy(&THR_LOCK_net);
 
212
  pthread_mutex_destroy(&THR_LOCK_time);
 
213
  pthread_mutex_destroy(&THR_LOCK_charset);
150
214
  if (all_threads_killed)
151
215
  {
152
216
    pthread_mutex_destroy(&THR_LOCK_threads);
153
217
    pthread_cond_destroy(&THR_COND_threads);
154
218
  }
 
219
#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
 
220
  pthread_mutex_destroy(&LOCK_localtime_r);
 
221
#endif
 
222
#ifndef HAVE_GETHOSTBYNAME_R
 
223
  pthread_mutex_destroy(&LOCK_gethostbyname_r);
 
224
#endif
155
225
}
156
226
 
157
227
static my_thread_id thread_id= 0;
162
232
  SYNOPSIS
163
233
    my_thread_init()
164
234
 
 
235
  NOTES
 
236
    We can't use mutex_locks here if we are using windows as
 
237
    we may have compiled the program with SAFE_MUTEX, in which
 
238
    case the checking of mutex_locks will not work until
 
239
    the pthread_self thread specific variable is initialized.
 
240
 
165
241
  RETURN
166
242
    0  ok
167
243
    1  Fatal error; mysys/dbug functions can't be used
169
245
 
170
246
bool my_thread_init(void)
171
247
{
 
248
  struct st_my_thread_var *tmp;
172
249
  bool error=0;
173
 
  st_my_thread_var *tmp= NULL;
174
250
 
175
251
#ifdef EXTRA_DEBUG_THREADS
176
252
  fprintf(stderr,"my_thread_init(): thread_id: 0x%lx\n",
177
253
          (uint32_t) pthread_self());
178
 
#endif
 
254
#endif  
179
255
 
180
256
  if (pthread_getspecific(THR_KEY_mysys))
181
257
  {
182
258
#ifdef EXTRA_DEBUG_THREADS
183
259
    fprintf(stderr,"my_thread_init() called more than once in thread 0x%lx\n",
184
260
            (long) pthread_self());
185
 
#endif
 
261
#endif    
186
262
    goto end;
187
263
  }
188
 
  tmp= static_cast<st_my_thread_var *>(calloc(1, sizeof(*tmp)));
189
 
  if (tmp == NULL)
 
264
  if (!(tmp= (struct st_my_thread_var *) calloc(1, sizeof(*tmp))))
190
265
  {
191
266
    error= 1;
192
267
    goto end;
221
296
 
222
297
void my_thread_end(void)
223
298
{
224
 
  st_my_thread_var *tmp=
225
 
    static_cast<st_my_thread_var *>(pthread_getspecific(THR_KEY_mysys));
 
299
  struct st_my_thread_var *tmp;
 
300
  tmp= (struct st_my_thread_var *)pthread_getspecific(THR_KEY_mysys);
226
301
 
227
302
#ifdef EXTRA_DEBUG_THREADS
228
303
  fprintf(stderr,"my_thread_end(): tmp: 0x%lx  pthread_self: 0x%lx  thread_id: %ld\n",
229
304
          (long) tmp, (long) pthread_self(), tmp ? (long) tmp->id : 0L);
230
 
#endif
 
305
#endif  
231
306
  if (tmp && tmp->init)
232
307
  {
233
308
#if !defined(__bsdi__) && !defined(__OpenBSD__)
235
310
    pthread_cond_destroy(&tmp->suspend);
236
311
#endif
237
312
    pthread_mutex_destroy(&tmp->mutex);
 
313
#if defined(USE_TLS)
238
314
    free(tmp);
 
315
#else
 
316
    tmp->init= 0;
 
317
#endif
239
318
 
240
319
    /*
241
320
      Decrement counter for number of running threads. We are using this
242
321
      in my_thread_global_end() to wait until all threads have called
243
322
      my_thread_end and thus freed all memory they have allocated in
244
 
      my_thread_init()
 
323
      my_thread_init() 
245
324
    */
246
325
    pthread_mutex_lock(&THR_LOCK_threads);
247
326
    assert(THR_thread_count != 0);
248
327
    if (--THR_thread_count == 0)
249
328
      pthread_cond_signal(&THR_COND_threads);
250
 
    pthread_mutex_unlock(&THR_LOCK_threads);
 
329
   pthread_mutex_unlock(&THR_LOCK_threads);
251
330
  }
 
331
  /* The following free has to be done, even if my_thread_var() is 0 */
 
332
#if defined(USE_TLS)
 
333
  pthread_setspecific(THR_KEY_mysys,0);
 
334
#endif
252
335
}
253
336
 
254
337
struct st_my_thread_var *_my_thread_var(void)
255
338
{
256
339
  struct st_my_thread_var *tmp= (struct st_my_thread_var*)pthread_getspecific(THR_KEY_mysys);
 
340
#if defined(USE_TLS)
 
341
  /* This can only happen in a .DLL */
 
342
  if (!tmp)
 
343
  {
 
344
    my_thread_init();
 
345
    tmp=my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
 
346
  }
 
347
#endif
257
348
  return tmp;
258
349
}
259
350
 
271
362
{
272
363
#ifdef _CS_GNU_LIBPTHREAD_VERSION
273
364
  char buff[64];
274
 
 
 
365
    
275
366
  confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff));
276
367
 
277
368
  if (!strncasecmp(buff, "NPTL", 4))