threadlocal.h
1 /***************************************************************************
2  Copyright (C) 2002-2015 Kentaro Kitagawa
3  kitagawa@phys.s.u-tokyo.ac.jp
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  You should have received a copy of the GNU Library General
11  Public License and a list of authors along with this program;
12  see the files COPYING and AUTHORS.
13 ***************************************************************************/
14 #ifndef THREADLOCAL_H_
15 #define THREADLOCAL_H_
16 
17 #include "support.h"
18 
19 #if defined __GNUC__ && __GNUC__ >= 4
20 // #define USE_STD_TLS
21 #endif
22 
23 #ifdef USE_QTHREAD
24  #include <QThreadStorage>
25 #endif
26 
27 //! Thread Local Storage template.
28 //! \p T must have constructor T()
29 //! object \p T will be deleted only when the thread is finished.
30 #ifdef USE_STD_TLS
31 template <typename T>
32 class XThreadLocal {
33 public:
34  template <typename ...Arg>
35  XThreadLocal(Arg&& ...arg) : m_var(std::forward<Arg>(arg)...) {}
36  //! \return return thread local object. Create an object if not allocated.
37  T &operator*() const {return m_var;}
38  //! \sa operator T&()
39  T *operator->() const {return &m_var;}
40 private:
41  static T thread_local m_var;
42 };
43 #else
44 template <typename T>
45 class XThreadLocal {
46 public:
47  XThreadLocal();
48  ~XThreadLocal();
49  //! \return return thread local object. Create an object if not allocated.
50  inline T &operator*() const;
51  //! \sa operator T&()
52  inline T *operator->() const;
53 private:
54 #ifdef USE_QTHREAD
55  mutable QThreadStorage<T*> m_tls;
56 #endif
57 #ifdef USE_PTHREAD
58  mutable pthread_key_t m_key;
59  static void delete_tls(void *var);
60 #endif
61 };
62 
63 #ifdef USE_QTHREAD
64  template <typename T>
66  template <typename T>
68  template <typename T>
69  inline T &XThreadLocal<T>::operator*() const {
70  if( !m_tls.hasLocalData())
71  m_tls.setLocalData(new T);
72  return *m_tls.localData();
73  }
74 
75 #else
76  #ifdef USE_PTHREAD
77  template <typename T>
79  int ret = pthread_key_create( &m_key, &XThreadLocal<T>::delete_tls);
80  assert( !ret);
81  }
82  template <typename T>
84  delete static_cast<T *>(pthread_getspecific(m_key));
85  int ret = pthread_key_delete(m_key);
86  assert( !ret);
87  }
88  template <typename T>
89  void
90  XThreadLocal<T>::delete_tls(void *var) {
91  delete static_cast<T *>(var);
92  }
93  template <typename T>
94  inline T &XThreadLocal<T>::operator*() const {
95  void *p = pthread_getspecific(m_key);
96  if(p == NULL) {
97  int ret = pthread_setspecific(m_key, p =
98  #ifdef HAVE_LIBGCCPP
99  new (NoGC) T);
100  #else
101  new T);
102  #endif
103  assert( !ret);
104  }
105  return *static_cast<T*>(p);
106  }
107  #endif //USE_PTHREAD
108 #endif //USE_QTHREAD
109 
110  template <typename T>
111  inline T *XThreadLocal<T>::operator->() const {
112  return &( **this);
113  }
114 
115 #endif /*USE_STD_TLS*/
116 
117 
118 #endif /*THREADLOCAL_H_*/

Generated for KAME4 by  doxygen 1.8.3