~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_thr_init.cc

  • Committer: Brian Aker
  • Date: 2009-05-26 20:45:27 UTC
  • mto: This revision was merged to the branch mainline in revision 1040.
  • Revision ID: brian@gaz-20090526204527-27uxzwkkitgoxjaz
Bits of dead code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/*
17
17
  Functions to handle initializating and allocationg of all mysys & debug
18
18
  thread variables.
19
19
*/
20
20
 
21
 
#include "config.h"
22
 
 
23
 
#include "drizzled/internal/my_sys.h"
24
 
#include "drizzled/internal/thread_var.h"
25
 
#include "drizzled/internal/m_string.h"
26
 
 
27
 
#include <cstdio>
 
21
#include "mysys/mysys_priv.h"
 
22
#include <mysys/my_pthread.h>
 
23
#include <mystrings/m_string.h>
 
24
 
 
25
#include <stdio.h>
28
26
#include <signal.h>
29
27
 
30
28
#if TIME_WITH_SYS_TIME
38
36
# endif
39
37
#endif
40
38
 
41
 
#include <boost/thread/thread.hpp>
42
 
#include <boost/thread/mutex.hpp>
43
 
#include <boost/thread/tss.hpp>
44
 
 
45
 
namespace drizzled
46
 
{
47
 
namespace internal
48
 
{
49
 
 
50
 
boost::thread_specific_ptr<st_my_thread_var> THR_KEY_mysys;
51
 
boost::mutex THR_LOCK_threads;
 
39
uint32_t thd_lib_detected= 0;
 
40
 
 
41
pthread_key_t THR_KEY_mysys;
 
42
pthread_mutex_t THR_LOCK_lock;
 
43
pthread_mutex_t THR_LOCK_threads;
 
44
pthread_cond_t  THR_COND_threads;
 
45
uint32_t            THR_thread_count= 0;
 
46
uint32_t                my_thread_end_wait_time= 5;
 
47
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
 
48
pthread_mutexattr_t my_fast_mutexattr;
 
49
#endif
 
50
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
 
51
pthread_mutexattr_t my_errorcheck_mutexattr;
 
52
#endif
 
53
 
 
54
#ifdef TARGET_OS_LINUX
 
55
 
 
56
/*
 
57
  Dummy thread spawned in my_thread_global_init() below to avoid
 
58
  race conditions in NPTL pthread_exit code.
 
59
*/
 
60
 
 
61
extern "C"
 
62
void *
 
63
nptl_pthread_exit_hack_handler(void *arg __attribute((unused)))
 
64
{
 
65
  /* Do nothing! */
 
66
  pthread_exit(0);
 
67
  return 0;
 
68
}
 
69
 
 
70
#endif /* TARGET_OS_LINUX */
 
71
 
 
72
 
 
73
static uint32_t get_thread_lib(void);
52
74
 
53
75
/*
54
76
  initialize thread environment
63
85
 
64
86
bool my_thread_global_init(void)
65
87
{
 
88
  int pth_ret;
 
89
  thd_lib_detected= get_thread_lib();
 
90
 
 
91
  if ((pth_ret= pthread_key_create(&THR_KEY_mysys, NULL)) != 0)
 
92
  {
 
93
    fprintf(stderr,"Can't initialize threads: error %d\n", pth_ret);
 
94
    return 1;
 
95
  }
 
96
 
 
97
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
 
98
  /*
 
99
    Set mutex type to "fast" a.k.a "adaptive"
 
100
 
 
101
    In this case the thread may steal the mutex from some other thread
 
102
    that is waiting for the same mutex.  This will save us some
 
103
    context switches but may cause a thread to 'starve forever' while
 
104
    waiting for the mutex (not likely if the code within the mutex is
 
105
    short).
 
106
  */
 
107
  pthread_mutexattr_init(&my_fast_mutexattr);
 
108
  pthread_mutexattr_settype(&my_fast_mutexattr,
 
109
                            PTHREAD_MUTEX_ADAPTIVE_NP);
 
110
#endif
 
111
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
 
112
  /*
 
113
    Set mutex type to "errorcheck"
 
114
  */
 
115
  pthread_mutexattr_init(&my_errorcheck_mutexattr);
 
116
  pthread_mutexattr_settype(&my_errorcheck_mutexattr,
 
117
                            PTHREAD_MUTEX_ERRORCHECK);
 
118
#endif
 
119
 
 
120
  pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST);
 
121
  pthread_mutex_init(&THR_LOCK_threads,MY_MUTEX_INIT_FAST);
 
122
  pthread_cond_init(&THR_COND_threads, NULL);
66
123
  if (my_thread_init())
67
124
  {
68
125
    my_thread_global_end();                     /* Clean up */
74
131
 
75
132
void my_thread_global_end(void)
76
133
{
 
134
  struct timespec abstime;
 
135
  bool all_threads_killed= 1;
 
136
 
 
137
  set_timespec(abstime, my_thread_end_wait_time);
 
138
  pthread_mutex_lock(&THR_LOCK_threads);
 
139
  while (THR_thread_count > 0)
 
140
  {
 
141
    int error= pthread_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads,
 
142
                                      &abstime);
 
143
    if (error == ETIMEDOUT || error == ETIME)
 
144
    {
 
145
      /*
 
146
        We shouldn't give an error here, because if we don't have
 
147
        pthread_kill(), programs like mysqld can't ensure that all threads
 
148
        are killed when we enter here.
 
149
      */
 
150
      if (THR_thread_count)
 
151
        fprintf(stderr,
 
152
                "Error in my_thread_global_end(): %d threads didn't exit\n",
 
153
                THR_thread_count);
 
154
      all_threads_killed= 0;
 
155
      break;
 
156
    }
 
157
  }
 
158
  pthread_mutex_unlock(&THR_LOCK_threads);
 
159
 
 
160
  pthread_key_delete(THR_KEY_mysys);
 
161
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
 
162
  pthread_mutexattr_destroy(&my_fast_mutexattr);
 
163
#endif
 
164
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
 
165
  pthread_mutexattr_destroy(&my_errorcheck_mutexattr);
 
166
#endif
 
167
  pthread_mutex_destroy(&THR_LOCK_lock);
 
168
  if (all_threads_killed)
 
169
  {
 
170
    pthread_mutex_destroy(&THR_LOCK_threads);
 
171
    pthread_cond_destroy(&THR_COND_threads);
 
172
  }
77
173
}
78
174
 
79
 
static uint64_t thread_id= 0;
 
175
static my_thread_id thread_id= 0;
80
176
 
81
177
/*
82
178
  Allocate thread specific memory for the thread, used by mysys
91
187
 
92
188
bool my_thread_init(void)
93
189
{
94
 
  // We should mever see my_thread_init()  called twice
95
 
  if (THR_KEY_mysys.get())
96
 
    return 0;
97
 
 
98
 
  st_my_thread_var *tmp= new st_my_thread_var;
99
 
  if (tmp == NULL)
100
 
  {
101
 
    return true;
102
 
  }
103
 
  THR_KEY_mysys.reset(tmp);
104
 
 
105
 
  boost::mutex::scoped_lock scopedLock(THR_LOCK_threads);
 
190
  struct st_my_thread_var *tmp;
 
191
  bool error=0;
 
192
 
 
193
#ifdef EXTRA_DEBUG_THREADS
 
194
  fprintf(stderr,"my_thread_init(): thread_id: 0x%lx\n",
 
195
          (uint32_t) pthread_self());
 
196
#endif
 
197
 
 
198
  if (pthread_getspecific(THR_KEY_mysys))
 
199
  {
 
200
#ifdef EXTRA_DEBUG_THREADS
 
201
    fprintf(stderr,"my_thread_init() called more than once in thread 0x%lx\n",
 
202
            (long) pthread_self());
 
203
#endif
 
204
    goto end;
 
205
  }
 
206
  if (!(tmp= (struct st_my_thread_var *) calloc(1, sizeof(*tmp))))
 
207
  {
 
208
    error= 1;
 
209
    goto end;
 
210
  }
 
211
  pthread_setspecific(THR_KEY_mysys,tmp);
 
212
  tmp->pthread_self= pthread_self();
 
213
  pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
 
214
  pthread_cond_init(&tmp->suspend, NULL);
 
215
  tmp->init= 1;
 
216
 
 
217
  pthread_mutex_lock(&THR_LOCK_threads);
106
218
  tmp->id= ++thread_id;
 
219
  ++THR_thread_count;
 
220
  pthread_mutex_unlock(&THR_LOCK_threads);
107
221
 
108
 
  return false;
 
222
end:
 
223
  return error;
109
224
}
110
225
 
111
226
 
117
232
 
118
233
  NOTE
119
234
    This may be called multiple times for a thread.
120
 
    This happens for example when one calls 'server_init()'
121
 
    server_end() and then ends with a end().
 
235
    This happens for example when one calls 'mysql_server_init()'
 
236
    mysql_server_end() and then ends with a mysql_end().
122
237
*/
123
238
 
124
239
void my_thread_end(void)
125
240
{
 
241
  struct st_my_thread_var *tmp;
 
242
  tmp= (struct st_my_thread_var *)pthread_getspecific(THR_KEY_mysys);
 
243
 
 
244
#ifdef EXTRA_DEBUG_THREADS
 
245
  fprintf(stderr,"my_thread_end(): tmp: 0x%lx  pthread_self: 0x%lx  thread_id: %ld\n",
 
246
          (long) tmp, (long) pthread_self(), tmp ? (long) tmp->id : 0L);
 
247
#endif
 
248
  if (tmp && tmp->init)
 
249
  {
 
250
#if !defined(__bsdi__) && !defined(__OpenBSD__)
 
251
 /* bsdi and openbsd 3.5 dumps core here */
 
252
    pthread_cond_destroy(&tmp->suspend);
 
253
#endif
 
254
    pthread_mutex_destroy(&tmp->mutex);
 
255
    tmp->init= 0;
 
256
 
 
257
    /*
 
258
      Decrement counter for number of running threads. We are using this
 
259
      in my_thread_global_end() to wait until all threads have called
 
260
      my_thread_end and thus freed all memory they have allocated in
 
261
      my_thread_init()
 
262
    */
 
263
    pthread_mutex_lock(&THR_LOCK_threads);
 
264
    assert(THR_thread_count != 0);
 
265
    if (--THR_thread_count == 0)
 
266
      pthread_cond_signal(&THR_COND_threads);
 
267
   pthread_mutex_unlock(&THR_LOCK_threads);
 
268
  }
126
269
}
127
270
 
128
271
struct st_my_thread_var *_my_thread_var(void)
129
272
{
130
 
  return THR_KEY_mysys.get();
131
 
}
132
 
 
133
 
} /* namespace internal */
134
 
} /* namespace drizzled */
 
273
  struct st_my_thread_var *tmp= (struct st_my_thread_var*)pthread_getspecific(THR_KEY_mysys);
 
274
  return tmp;
 
275
}
 
276
 
 
277
 
 
278
/****************************************************************************
 
279
  Get name of current thread.
 
280
****************************************************************************/
 
281
 
 
282
my_thread_id my_thread_dbug_id()
 
283
{
 
284
  return my_thread_var->id;
 
285
}
 
286
 
 
287
static uint32_t get_thread_lib(void)
 
288
{
 
289
#ifdef _CS_GNU_LIBPTHREAD_VERSION
 
290
  char buff[64];
 
291
 
 
292
  confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff));
 
293
 
 
294
  if (!strncasecmp(buff, "NPTL", 4))
 
295
    return THD_LIB_NPTL;
 
296
  if (!strncasecmp(buff, "linuxthreads", 12))
 
297
    return THD_LIB_LT;
 
298
#endif
 
299
  return THD_LIB_OTHER;
 
300
}