CppCMS
thread.h
1 //
2 // Copyright (C) 2009-2012 Artyom Beilis (Tonkikh)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 #ifndef BOOSTER_UTIL_THREAD_H
9 #define BOOSTER_UTIL_THREAD_H
10 
11 #include <booster/hold_ptr.h>
12 #include <booster/noncopyable.h>
13 #include <booster/refcounted.h>
14 #include <booster/intrusive_ptr.h>
15 #include <booster/function.h>
16 #include <booster/config.h>
17 
18 namespace booster {
19 
20  extern "C" void *booster_thread_func(void *);
21 
25  class BOOSTER_API thread : public noncopyable {
26  public:
30  thread(function<void()> const &cb);
31  ~thread();
32 
36  void join();
37 
41  void detach();
42 
46  static unsigned hardware_concurrency();
47  private:
48  friend void *booster_thread_func(void *);
49  struct data;
51  };
52 
53 
54  class condition_variable;
55 
59  class BOOSTER_API mutex : public noncopyable {
60  public:
61  mutex();
62  ~mutex();
69  void lock();
75  void unlock();
76  friend class condition_variable;
77  private:
78  struct data;
80  };
81 
106  class BOOSTER_API recursive_mutex : public noncopyable {
107  public:
108  recursive_mutex();
109  ~recursive_mutex();
113  void lock();
117  void unlock();
118  private:
119  struct data;
120  hold_ptr<data> d;
121  };
122 
129  class BOOSTER_API recursive_shared_mutex : public noncopyable {
130  public:
138  void lock() { unique_lock(); }
144  void unique_lock();
151  void shared_lock();
155  void unlock();
156  private:
157  struct data;
158  hold_ptr<data> d;
159  };
166  class BOOSTER_API shared_mutex : public noncopyable {
167  public:
168  shared_mutex();
169  ~shared_mutex();
173  void lock() { unique_lock(); }
177  void unique_lock();
183  void shared_lock();
187  void unlock();
188  private:
189  struct data;
190  hold_ptr<data> d;
191  };
192 
193  template<typename Mutex>
194  class unique_lock;
195 
201  class BOOSTER_API condition_variable {
202  public:
205 
214  void wait(unique_lock<mutex> &m);
215 
220  void notify_one();
225  void notify_all();
226  private:
227  struct data;
228  hold_ptr<data> d;
229  };
230 
232  namespace details {
233  struct tls_object;
234 
235  class key : public refcounted {
236  public:
237  key(void (*d)(void *)) :
238  dtor_(d)
239  {
240  }
241  virtual ~key()
242  {
243  }
244  void *get();
245  void set(void *);
246 
247  void destroy(void *p)
248  {
249  dtor_(p);
250  }
251  virtual tls_object *get_object() = 0;
252  private:
253  void (*dtor_)(void *);
254  };
255 
256  BOOSTER_API intrusive_ptr<key> make_key(void (*dtor)(void *));
257 
258  struct tls_object {
259  tls_object(intrusive_ptr<key> p) :
260  the_key(p),
261  obj(0)
262  {
263  }
264  ~tls_object()
265  {
266  the_key->destroy(obj);
267  obj = 0;
268  }
269  intrusive_ptr<key> the_key;
270  void *obj;
271  };
272 
273  inline void key::set(void *p)
274  {
275  get_object()->obj = p;
276  }
277  inline void *key::get()
278  {
279  return get_object()->obj;
280  }
281 
282  } // details
283 
285 
309  template<typename T>
311  public:
315  thread_specific_ptr() : key_(details::make_key(destructor))
316  {
317  }
318 
323  {
324  }
328  T *get() const
329  {
330  return static_cast<T*>(key_->get());
331  }
335  T* operator->() const
336  {
337  return get();
338  }
342  T& operator*() const
343  {
344  return *get();
345  }
351  void reset(T *new_val = 0)
352  {
353  T *p = get();
354  if(p)
355  destructor(p);
356  key_->set(static_cast<void *>(new_val));
357  }
363  T *release()
364  {
365  T *p = get();
366  key_->set(0);
367  return p;
368  }
369  private:
370  static void destructor(void *ptr)
371  {
372  delete static_cast<T*>(ptr);
373  }
375  };
376 
377 
383  template<typename Mutex>
384  class unique_lock : public noncopyable {
385  public:
387  unique_lock(Mutex &m) : m_(&m)
388  {
389  m_->lock();
390  }
393  {
394  m_->unlock();
395  }
397  Mutex *mutex() const
398  {
399  return m_;
400  }
401  private:
402  Mutex *m_;
403  };
404 
410  template<typename Mutex>
411  class shared_lock : public noncopyable {
412  public:
414  shared_lock(Mutex &m) : m_(&m)
415  {
416  m_->shared_lock();
417  }
420  {
421  m_->unlock();
422  }
424  Mutex *mutex() const
425  {
426  return m_;
427  }
428  private:
429  Mutex *m_;
430  };
431 #ifdef BOOSTER_POSIX
432  class BOOSTER_API fork_shared_mutex : public noncopyable {
438  public:
442  fork_shared_mutex();
443  ~fork_shared_mutex();
444 
448  bool try_lock() { return try_unique_lock(); }
452  bool try_unique_lock();
456  bool try_shared_lock();
457 
461  void lock() { return unique_lock(); }
465  void unique_lock();
469  void shared_lock();
470 
474  void unlock();
475  private:
476  struct data;
477  hold_ptr<data> d;
478  };
479 #endif
480 
481 }//booster
482 
483 
484 #endif
T * operator->() const
Definition: thread.h:335
Mutex object.
Definition: thread.h:59
void lock()
Definition: thread.h:173
thread_specific_ptr()
Definition: thread.h:315
Recursive mutex object.
Definition: thread.h:106
Thread specific pointer.
Definition: thread.h:310
Recursuve Shared mutex or a.k.a. Read-Write Lock that can be recursively locked by readers...
Definition: thread.h:129
~thread_specific_ptr()
Definition: thread.h:322
unique_lock(Mutex &m)
Acquire the lock.
Definition: thread.h:387
a Unique lock guard.
Definition: thread.h:194
void lock()
Definition: thread.h:138
This class is used as base class for reference counted objects that use intrusive_ptr. Deriving from this class allows simple way to manage reference counting for single object.
Definition: refcounted.h:25
Mutex * mutex() const
Get the reference to the mutex object.
Definition: thread.h:397
shared_lock(Mutex &m)
Acquire the lock.
Definition: thread.h:414
T & operator*() const
Definition: thread.h:342
~shared_lock()
Release the lock.
Definition: thread.h:419
~unique_lock()
Release the lock.
Definition: thread.h:392
Shared mutex or a.k.a. Read-Write Lock.
Definition: thread.h:166
a Shared lock guard.
Definition: thread.h:411
This is conditional variable object.
Definition: thread.h:201
intrusive_ptr is the class taken as-is from boost.
Definition: intrusive_ptr.h:42
the class that allows to start an execution thread
Definition: thread.h:25
void reset(T *new_val=0)
Definition: thread.h:351
Mutex * mutex() const
Get the reference to the mutex object.
Definition: thread.h:424
Booster library namespace. The library that implements Boost Like API in ABI backward compatible way...
Definition: application.h:23
This class makes impossible to copy any class derived from this one.
Definition: noncopyable.h:15
T * release()
Definition: thread.h:363