MongoDB C++ Driver  legacy-1.0.3
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
threadlocal.h
1 #pragma once
2 
3 /* Copyright 2014 MongoDB Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
19 #include <boost/thread/tss.hpp>
21 
22 
23 namespace mongo {
24 
25  /* thread local "value" rather than a pointer
26  good for things which have copy constructors (and the copy constructor is fast enough)
27  e.g.
28  ThreadLocalValue<int> myint;
29  */
30  template<class T>
32  public:
33  ThreadLocalValue( T def = 0 ) : _default( def ) { }
34 
35  T get() const {
36  T * val = _val.get();
37  if ( val )
38  return *val;
39  return _default;
40  }
41 
42  void set( const T& i ) {
43  T *v = _val.get();
44  if( v ) {
45  *v = i;
46  return;
47  }
48  v = new T(i);
49  _val.reset( v );
50  }
51 
52  T& getRef() {
53  T *v = _val.get();
54  if( v ) {
55  return *v;
56  }
57  v = new T(_default);
58  _val.reset( v );
59  return *v;
60  }
61 
62  private:
63  boost::thread_specific_ptr<T> _val;
64  const T _default;
65  };
66 
67  /* TSP
68  These macros use intrinsics which are faster than boost::thread_specific_ptr.
69  However the intrinsics don't free up objects on thread closure. Thus we use
70  a combination here, with the assumption that reset's are infrequent, so that
71  get's are fast.
72  */
73 #if defined(MONGO_HAVE___THREAD) || defined(MONGO_HAVE___DECLSPEC_THREAD)
74 
75  template< class T >
76  struct TSP {
77  boost::thread_specific_ptr<T> tsp;
78  public:
79  T* get() const;
80  void reset(T* v);
81  T* getMake() {
82  T *t = get();
83  if( t == 0 )
84  reset( t = new T() );
85  return t;
86  }
87  };
88 
89 # if defined(MONGO_HAVE___DECLSPEC_THREAD)
90 
91 # define TSP_DECLARE(T,p) extern TSP<T> p;
92 
93 # define TSP_DEFINE(T,p) __declspec( thread ) T* _ ## p; \
94  TSP<T> p; \
95  template<> T* TSP<T>::get() const { return _ ## p; } \
96  void TSP<T>::reset(T* v) { \
97  tsp.reset(v); \
98  _ ## p = v; \
99  }
100 # else
101 
102 # define TSP_DECLARE(T,p) \
103  extern __thread T* _ ## p; \
104  template<> inline T* TSP<T>::get() const { return _ ## p; } \
105  extern TSP<T> p;
106 
107 # define TSP_DEFINE(T,p) \
108  __thread T* _ ## p; \
109  template<> void TSP<T>::reset(T* v) { \
110  tsp.reset(v); \
111  _ ## p = v; \
112  } \
113  TSP<T> p;
114 # endif
115 
116 #elif defined(_POSIX_THREADS) && (_POSIX_THREADS >= 0)
117  template< class T>
118  struct TSP {
119  pthread_key_t _key;
120  public:
121  TSP() {
122  verify( pthread_key_create( &_key, TSP::dodelete ) == 0 );
123  }
124 
125  ~TSP() {
126  pthread_key_delete( _key );
127  }
128 
129  static void dodelete( void* x ) {
130  T* t = reinterpret_cast<T*>(x);
131  delete t;
132  }
133 
134  T* get() const {
135  return reinterpret_cast<T*>( pthread_getspecific( _key ) );
136  }
137 
138  void reset(T* v) {
139  T* old = get();
140  delete old;
141  verify( pthread_setspecific( _key, v ) == 0 );
142  }
143 
144  T* getMake() {
145  T *t = get();
146  if( t == 0 ) {
147  t = new T();
148  reset( t );
149  }
150  return t;
151  }
152  };
153 
154 # define TSP_DECLARE(T,p) extern TSP<T> p;
155 
156 # define TSP_DEFINE(T,p) TSP<T> p;
157 
158 #else
159 
160  template< class T >
161  struct TSP {
162  boost::thread_specific_ptr<T> tsp;
163  public:
164  T* get() const { return tsp.get(); }
165  void reset(T* v) { tsp.reset(v); }
166  T* getMake() {
167  T *t = get();
168  if( t == 0 )
169  reset( t = new T() );
170  return t;
171  }
172  };
173 
174 # define TSP_DECLARE(T,p) extern TSP<T> p;
175 
176 # define TSP_DEFINE(T,p) TSP<T> p;
177 
178 #endif
179 
180 }
the main MongoDB namespace
Definition: bulk_operation_builder.h:24
remove mongo implementation macros after using
macros for mongo internals
Definition: threadlocal.h:31
Definition: threadlocal.h:161