~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/internal/my_thr_init.cc

  • Committer: Brian Aker
  • Date: 2010-09-20 00:00:20 UTC
  • Revision ID: brian@tangent.org-20100920000020-s6x30brpajr83pkr
Update session/memory to use boost specific.

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
21
21
#include "config.h"
22
22
 
23
23
#include "drizzled/internal/my_sys.h"
 
24
#include "drizzled/internal/my_pthread.h"
24
25
#include "drizzled/internal/thread_var.h"
25
26
#include "drizzled/internal/m_string.h"
26
27
 
38
39
# endif
39
40
#endif
40
41
 
41
 
#include <boost/thread/thread.hpp>
42
 
#include <boost/thread/mutex.hpp>
43
 
#include <boost/thread/tss.hpp>
44
 
 
45
42
namespace drizzled
46
43
{
47
44
namespace internal
48
45
{
49
46
 
50
 
boost::thread_specific_ptr<st_my_thread_var> THR_KEY_mysys;
 
47
pthread_key_t THR_KEY_mysys;
51
48
boost::mutex THR_LOCK_threads;
 
49
pthread_cond_t  THR_COND_threads;
 
50
uint32_t THR_thread_count= 0;
 
51
static uint32_t my_thread_end_wait_time= 5;
52
52
 
53
53
/*
54
54
  initialize thread environment
63
63
 
64
64
bool my_thread_global_init(void)
65
65
{
 
66
  int pth_ret;
 
67
 
 
68
  if ((pth_ret= pthread_key_create(&THR_KEY_mysys, NULL)) != 0)
 
69
  {
 
70
    fprintf(stderr,"Can't initialize threads: error %d\n", pth_ret);
 
71
    return 1;
 
72
  }
 
73
 
 
74
  pthread_cond_init(&THR_COND_threads, NULL);
66
75
  if (my_thread_init())
67
76
  {
68
77
    my_thread_global_end();                     /* Clean up */
74
83
 
75
84
void my_thread_global_end(void)
76
85
{
 
86
  struct timespec abstime;
 
87
  bool all_threads_killed= 1;
 
88
 
 
89
  set_timespec(abstime, my_thread_end_wait_time);
 
90
  {
 
91
    boost::mutex::scoped_lock scopedLock(THR_LOCK_threads);
 
92
    while (THR_thread_count > 0)
 
93
    {
 
94
      int error= pthread_cond_timedwait(&THR_COND_threads, THR_LOCK_threads.native_handle(),
 
95
                                        &abstime);
 
96
      if (error == ETIMEDOUT || error == ETIME)
 
97
      {
 
98
        /*
 
99
          We shouldn't give an error here, because if we don't have
 
100
          pthread_kill(), programs like mysqld can't ensure that all threads
 
101
          are killed when we enter here.
 
102
        */
 
103
        if (THR_thread_count)
 
104
          fprintf(stderr,
 
105
                  "Error in my_thread_global_end(): %d threads didn't exit\n",
 
106
                  THR_thread_count);
 
107
        all_threads_killed= 0;
 
108
        break;
 
109
      }
 
110
    }
 
111
  }
 
112
 
 
113
  pthread_key_delete(THR_KEY_mysys);
 
114
  if (all_threads_killed)
 
115
  {
 
116
    pthread_cond_destroy(&THR_COND_threads);
 
117
  }
77
118
}
78
119
 
79
120
static uint64_t thread_id= 0;
91
132
 
92
133
bool my_thread_init(void)
93
134
{
 
135
  bool error=0;
 
136
  st_my_thread_var *tmp= NULL;
 
137
 
94
138
  // We should mever see my_thread_init()  called twice
95
 
  if (THR_KEY_mysys.get())
 
139
  if (pthread_getspecific(THR_KEY_mysys))
96
140
    return 0;
97
141
 
98
 
  st_my_thread_var *tmp= new st_my_thread_var;
 
142
  tmp= static_cast<st_my_thread_var *>(calloc(1, sizeof(*tmp)));
99
143
  if (tmp == NULL)
100
144
  {
101
 
    return true;
 
145
    return 1;
102
146
  }
103
 
  THR_KEY_mysys.reset(tmp);
 
147
  pthread_setspecific(THR_KEY_mysys,tmp);
 
148
  tmp->pthread_self= pthread_self();
 
149
  pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
 
150
  pthread_cond_init(&tmp->suspend, NULL);
 
151
  tmp->init= 1;
104
152
 
105
153
  boost::mutex::scoped_lock scopedLock(THR_LOCK_threads);
106
154
  tmp->id= ++thread_id;
 
155
  ++THR_thread_count;
107
156
 
108
 
  return false;
 
157
  return error;
109
158
}
110
159
 
111
160
 
123
172
 
124
173
void my_thread_end(void)
125
174
{
 
175
  st_my_thread_var *tmp=
 
176
    static_cast<st_my_thread_var *>(pthread_getspecific(THR_KEY_mysys));
 
177
 
 
178
  if (tmp && tmp->init)
 
179
  {
 
180
#if !defined(__bsdi__) && !defined(__OpenBSD__)
 
181
 /* bsdi and openbsd 3.5 dumps core here */
 
182
    pthread_cond_destroy(&tmp->suspend);
 
183
#endif
 
184
    pthread_mutex_destroy(&tmp->mutex);
 
185
    free(tmp);
 
186
 
 
187
    /*
 
188
      Decrement counter for number of running threads. We are using this
 
189
      in my_thread_global_end() to wait until all threads have called
 
190
      my_thread_end and thus freed all memory they have allocated in
 
191
      my_thread_init()
 
192
    */
 
193
    boost::mutex::scoped_lock scopedLock(THR_LOCK_threads);
 
194
    assert(THR_thread_count != 0);
 
195
    if (--THR_thread_count == 0)
 
196
      pthread_cond_signal(&THR_COND_threads);
 
197
  }
126
198
}
127
199
 
128
200
struct st_my_thread_var *_my_thread_var(void)
129
201
{
130
 
  return THR_KEY_mysys.get();
 
202
  struct st_my_thread_var *tmp= (struct st_my_thread_var*)pthread_getspecific(THR_KEY_mysys);
 
203
  return tmp;
131
204
}
132
205
 
133
206
} /* namespace internal */