~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to drizzled/internal/my_thr_init.cc

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-10-02 14:17:48 UTC
  • mfrom: (1.1.1 upstream)
  • mto: (2.1.17 sid)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20101002141748-m6vbfbfjhrw1153e
Tags: 2010.09.1802-1
* New upstream release.
* Removed pid-file argument hack.
* Updated GPL-2 address to be new address.
* Directly copy in drizzledump.1 since debian doesn't have sphinx 1.0 yet.
* Link to jquery from libjs-jquery. Add it as a depend.
* Add drizzled.8 symlink to the install files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
#include "drizzled/internal/my_sys.h"
24
24
#include "drizzled/internal/my_pthread.h"
 
25
#include "drizzled/internal/thread_var.h"
25
26
#include "drizzled/internal/m_string.h"
26
27
 
27
28
#include <cstdio>
38
39
# endif
39
40
#endif
40
41
 
 
42
#include <boost/thread/thread.hpp>
 
43
#include <boost/thread/mutex.hpp>
 
44
#include <boost/thread/tss.hpp>
 
45
 
41
46
namespace drizzled
42
47
{
43
48
namespace internal
44
49
{
45
50
 
46
 
uint32_t thd_lib_detected= 0;
47
 
 
48
 
pthread_key_t THR_KEY_mysys;
49
 
pthread_mutex_t THR_LOCK_lock;
50
 
pthread_mutex_t THR_LOCK_threads;
51
 
pthread_cond_t  THR_COND_threads;
52
 
uint32_t            THR_thread_count= 0;
53
 
static uint32_t my_thread_end_wait_time= 5;
54
 
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
55
 
pthread_mutexattr_t my_fast_mutexattr;
56
 
#endif
57
 
 
58
 
static uint32_t get_thread_lib(void);
 
51
boost::thread_specific_ptr<st_my_thread_var> THR_KEY_mysys;
 
52
boost::mutex THR_LOCK_threads;
59
53
 
60
54
/*
61
55
  initialize thread environment
70
64
 
71
65
bool my_thread_global_init(void)
72
66
{
73
 
  int pth_ret;
74
 
  thd_lib_detected= get_thread_lib();
75
 
 
76
 
  if ((pth_ret= pthread_key_create(&THR_KEY_mysys, NULL)) != 0)
77
 
  {
78
 
    fprintf(stderr,"Can't initialize threads: error %d\n", pth_ret);
79
 
    return 1;
80
 
  }
81
 
 
82
 
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
83
 
  /*
84
 
    Set mutex type to "fast" a.k.a "adaptive"
85
 
 
86
 
    In this case the thread may steal the mutex from some other thread
87
 
    that is waiting for the same mutex.  This will save us some
88
 
    context switches but may cause a thread to 'starve forever' while
89
 
    waiting for the mutex (not likely if the code within the mutex is
90
 
    short).
91
 
  */
92
 
  pthread_mutexattr_init(&my_fast_mutexattr);
93
 
  pthread_mutexattr_settype(&my_fast_mutexattr,
94
 
                            PTHREAD_MUTEX_ADAPTIVE_NP);
95
 
#endif
96
 
 
97
 
  pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST);
98
 
  pthread_mutex_init(&THR_LOCK_threads,MY_MUTEX_INIT_FAST);
99
 
  pthread_cond_init(&THR_COND_threads, NULL);
100
67
  if (my_thread_init())
101
68
  {
102
69
    my_thread_global_end();                     /* Clean up */
108
75
 
109
76
void my_thread_global_end(void)
110
77
{
111
 
  struct timespec abstime;
112
 
  bool all_threads_killed= 1;
113
 
 
114
 
  set_timespec(abstime, my_thread_end_wait_time);
115
 
  pthread_mutex_lock(&THR_LOCK_threads);
116
 
  while (THR_thread_count > 0)
117
 
  {
118
 
    int error= pthread_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads,
119
 
                                      &abstime);
120
 
    if (error == ETIMEDOUT || error == ETIME)
121
 
    {
122
 
      /*
123
 
        We shouldn't give an error here, because if we don't have
124
 
        pthread_kill(), programs like mysqld can't ensure that all threads
125
 
        are killed when we enter here.
126
 
      */
127
 
      if (THR_thread_count)
128
 
        fprintf(stderr,
129
 
                "Error in my_thread_global_end(): %d threads didn't exit\n",
130
 
                THR_thread_count);
131
 
      all_threads_killed= 0;
132
 
      break;
133
 
    }
134
 
  }
135
 
  pthread_mutex_unlock(&THR_LOCK_threads);
136
 
 
137
 
  pthread_key_delete(THR_KEY_mysys);
138
 
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
139
 
  pthread_mutexattr_destroy(&my_fast_mutexattr);
140
 
#endif
141
 
  pthread_mutex_destroy(&THR_LOCK_lock);
142
 
  if (all_threads_killed)
143
 
  {
144
 
    pthread_mutex_destroy(&THR_LOCK_threads);
145
 
    pthread_cond_destroy(&THR_COND_threads);
146
 
  }
147
78
}
148
79
 
149
80
static uint64_t thread_id= 0;
161
92
 
162
93
bool my_thread_init(void)
163
94
{
164
 
  bool error=0;
165
 
  st_my_thread_var *tmp= NULL;
166
 
 
167
 
#ifdef EXTRA_DEBUG_THREADS
168
 
  fprintf(stderr,"my_thread_init(): thread_id: 0x%lx\n",
169
 
          (uint32_t) pthread_self());
170
 
#endif
171
 
 
172
 
  if (pthread_getspecific(THR_KEY_mysys))
173
 
  {
174
 
#ifdef EXTRA_DEBUG_THREADS
175
 
    fprintf(stderr,"my_thread_init() called more than once in thread 0x%lx\n",
176
 
            (long) pthread_self());
177
 
#endif
178
 
    goto end;
179
 
  }
180
 
  tmp= static_cast<st_my_thread_var *>(calloc(1, sizeof(*tmp)));
 
95
  // We should mever see my_thread_init()  called twice
 
96
  if (THR_KEY_mysys.get())
 
97
    return 0;
 
98
 
 
99
  st_my_thread_var *tmp= new st_my_thread_var;
181
100
  if (tmp == NULL)
182
101
  {
183
 
    error= 1;
184
 
    goto end;
 
102
    return true;
185
103
  }
186
 
  pthread_setspecific(THR_KEY_mysys,tmp);
187
 
  tmp->pthread_self= pthread_self();
188
 
  pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
189
 
  pthread_cond_init(&tmp->suspend, NULL);
190
 
  tmp->init= 1;
 
104
  THR_KEY_mysys.reset(tmp);
191
105
 
192
 
  pthread_mutex_lock(&THR_LOCK_threads);
 
106
  boost::mutex::scoped_lock scopedLock(THR_LOCK_threads);
193
107
  tmp->id= ++thread_id;
194
 
  ++THR_thread_count;
195
 
  pthread_mutex_unlock(&THR_LOCK_threads);
196
108
 
197
 
end:
198
 
  return error;
 
109
  return false;
199
110
}
200
111
 
201
112
 
213
124
 
214
125
void my_thread_end(void)
215
126
{
216
 
  st_my_thread_var *tmp=
217
 
    static_cast<st_my_thread_var *>(pthread_getspecific(THR_KEY_mysys));
 
127
  st_my_thread_var *tmp= THR_KEY_mysys.get();
218
128
 
219
 
#ifdef EXTRA_DEBUG_THREADS
220
 
  fprintf(stderr,"my_thread_end(): tmp: 0x%lx  pthread_self: 0x%lx  thread_id: %ld\n",
221
 
          (long) tmp, (long) pthread_self(), tmp ? (long) tmp->id : 0L);
222
 
#endif
223
 
  if (tmp && tmp->init)
 
129
  if (tmp)
224
130
  {
225
 
#if !defined(__bsdi__) && !defined(__OpenBSD__)
226
 
 /* bsdi and openbsd 3.5 dumps core here */
227
 
    pthread_cond_destroy(&tmp->suspend);
228
 
#endif
229
 
    pthread_mutex_destroy(&tmp->mutex);
230
 
    free(tmp);
231
 
 
232
 
    /*
233
 
      Decrement counter for number of running threads. We are using this
234
 
      in my_thread_global_end() to wait until all threads have called
235
 
      my_thread_end and thus freed all memory they have allocated in
236
 
      my_thread_init()
237
 
    */
238
 
    pthread_mutex_lock(&THR_LOCK_threads);
239
 
    assert(THR_thread_count != 0);
240
 
    if (--THR_thread_count == 0)
241
 
      pthread_cond_signal(&THR_COND_threads);
242
 
    pthread_mutex_unlock(&THR_LOCK_threads);
 
131
    delete tmp;
 
132
    THR_KEY_mysys.release();
243
133
  }
244
134
}
245
135
 
246
136
struct st_my_thread_var *_my_thread_var(void)
247
137
{
248
 
  struct st_my_thread_var *tmp= (struct st_my_thread_var*)pthread_getspecific(THR_KEY_mysys);
249
 
  return tmp;
250
 
}
251
 
 
252
 
static uint32_t get_thread_lib(void)
253
 
{
254
 
#ifdef _CS_GNU_LIBPTHREAD_VERSION
255
 
  char buff[64];
256
 
 
257
 
  confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff));
258
 
 
259
 
  if (!strncasecmp(buff, "NPTL", 4))
260
 
    return THD_LIB_NPTL;
261
 
  if (!strncasecmp(buff, "linuxthreads", 12))
262
 
    return THD_LIB_LT;
263
 
#endif
264
 
  return THD_LIB_OTHER;
 
138
  return THR_KEY_mysys.get();
265
139
}
266
140
 
267
141
} /* namespace internal */