summaryrefslogtreecommitdiff
path: root/src/mongo/util/concurrency/threadlocal.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/util/concurrency/threadlocal.h')
-rw-r--r--src/mongo/util/concurrency/threadlocal.h290
1 files changed, 152 insertions, 138 deletions
diff --git a/src/mongo/util/concurrency/threadlocal.h b/src/mongo/util/concurrency/threadlocal.h
index 4530ab9aa6d..a73088e846e 100644
--- a/src/mongo/util/concurrency/threadlocal.h
+++ b/src/mongo/util/concurrency/threadlocal.h
@@ -32,163 +32,177 @@
#include "mongo/config.h"
-namespace mongo {
-
- using boost::thread_specific_ptr;
-
- /* thread local "value" rather than a pointer
- good for things which have copy constructors (and the copy constructor is fast enough)
- e.g.
- ThreadLocalValue<int> myint;
- */
- template<class T>
- class ThreadLocalValue {
- public:
- ThreadLocalValue( T def = 0 ) : _default( def ) { }
-
- T get() const {
- T * val = _val.get();
- if ( val )
- return *val;
- return _default;
- }
+namespace mongo {
+
+using boost::thread_specific_ptr;
- void set( const T& i ) {
- T *v = _val.get();
- if( v ) {
- *v = i;
- return;
- }
- v = new T(i);
- _val.reset( v );
+/* thread local "value" rather than a pointer
+ good for things which have copy constructors (and the copy constructor is fast enough)
+ e.g.
+ ThreadLocalValue<int> myint;
+*/
+template <class T>
+class ThreadLocalValue {
+public:
+ ThreadLocalValue(T def = 0) : _default(def) {}
+
+ T get() const {
+ T* val = _val.get();
+ if (val)
+ return *val;
+ return _default;
+ }
+
+ void set(const T& i) {
+ T* v = _val.get();
+ if (v) {
+ *v = i;
+ return;
}
+ v = new T(i);
+ _val.reset(v);
+ }
- T& getRef() {
- T *v = _val.get();
- if( v ) {
- return *v;
- }
- v = new T(_default);
- _val.reset( v );
+ T& getRef() {
+ T* v = _val.get();
+ if (v) {
return *v;
}
-
- private:
- boost::thread_specific_ptr<T> _val;
- const T _default;
- };
-
- /* TSP
- These macros use intrinsics which are faster than boost::thread_specific_ptr.
- However the intrinsics don't free up objects on thread closure. Thus we use
- a combination here, with the assumption that reset's are infrequent, so that
- get's are fast.
- */
+ v = new T(_default);
+ _val.reset(v);
+ return *v;
+ }
+
+private:
+ boost::thread_specific_ptr<T> _val;
+ const T _default;
+};
+
+/* TSP
+ These macros use intrinsics which are faster than boost::thread_specific_ptr.
+ However the intrinsics don't free up objects on thread closure. Thus we use
+ a combination here, with the assumption that reset's are infrequent, so that
+ get's are fast.
+*/
#if defined(MONGO_CONFIG_HAVE___THREAD) || defined(MONGO_CONFIG_HAVE___DECLSPEC_THREAD)
-
- template< class T >
- struct TSP {
- boost::thread_specific_ptr<T> tsp;
- public:
- T* get() const;
- void reset(T* v);
- T* getMake() {
- T *t = get();
- if( t == 0 )
- reset( t = new T() );
- return t;
- }
- };
-# if defined(MONGO_CONFIG_HAVE___DECLSPEC_THREAD)
-
-# define TSP_DECLARE(T,p) extern TSP<T> p;
+template <class T>
+struct TSP {
+ boost::thread_specific_ptr<T> tsp;
+
+public:
+ T* get() const;
+ void reset(T* v);
+ T* getMake() {
+ T* t = get();
+ if (t == 0)
+ reset(t = new T());
+ return t;
+ }
+};
+
+#if defined(MONGO_CONFIG_HAVE___DECLSPEC_THREAD)
+
+#define TSP_DECLARE(T, p) extern TSP<T> p;
+
+#define TSP_DEFINE(T, p) \
+ __declspec(thread) T* _##p; \
+ TSP<T> p; \
+ template <> \
+ T* TSP<T>::get() const { \
+ return _##p; \
+ } \
+ void TSP<T>::reset(T* v) { \
+ tsp.reset(v); \
+ _##p = v; \
+ }
+#else
-# define TSP_DEFINE(T,p) __declspec( thread ) T* _ ## p; \
- TSP<T> p; \
- template<> T* TSP<T>::get() const { return _ ## p; } \
- void TSP<T>::reset(T* v) { \
- tsp.reset(v); \
- _ ## p = v; \
- }
-# else
-
-# define TSP_DECLARE(T,p) \
- extern __thread T* _ ## p; \
- template<> inline T* TSP<T>::get() const { return _ ## p; } \
+#define TSP_DECLARE(T, p) \
+ extern __thread T* _##p; \
+ template <> \
+ inline T* TSP<T>::get() const { \
+ return _##p; \
+ } \
extern TSP<T> p;
-# define TSP_DEFINE(T,p) \
- __thread T* _ ## p; \
- template<> void TSP<T>::reset(T* v) { \
- tsp.reset(v); \
- _ ## p = v; \
- } \
+#define TSP_DEFINE(T, p) \
+ __thread T* _##p; \
+ template <> \
+ void TSP<T>::reset(T* v) { \
+ tsp.reset(v); \
+ _##p = v; \
+ } \
TSP<T> p;
-# endif
+#endif
#elif defined(_POSIX_THREADS) && (_POSIX_THREADS >= 0)
- template< class T>
- struct TSP {
- pthread_key_t _key;
- public:
- TSP() {
- verify( pthread_key_create( &_key, TSP::dodelete ) == 0 );
+template <class T>
+struct TSP {
+ pthread_key_t _key;
+
+public:
+ TSP() {
+ verify(pthread_key_create(&_key, TSP::dodelete) == 0);
+ }
+
+ ~TSP() {
+ pthread_key_delete(_key);
+ }
+
+ static void dodelete(void* x) {
+ T* t = reinterpret_cast<T*>(x);
+ delete t;
+ }
+
+ T* get() const {
+ return reinterpret_cast<T*>(pthread_getspecific(_key));
+ }
+
+ void reset(T* v) {
+ T* old = get();
+ delete old;
+ verify(pthread_setspecific(_key, v) == 0);
+ }
+
+ T* getMake() {
+ T* t = get();
+ if (t == 0) {
+ t = new T();
+ reset(t);
}
+ return t;
+ }
+};
- ~TSP() {
- pthread_key_delete( _key );
- }
+#define TSP_DECLARE(T, p) extern TSP<T> p;
- static void dodelete( void* x ) {
- T* t = reinterpret_cast<T*>(x);
- delete t;
- }
-
- T* get() const {
- return reinterpret_cast<T*>( pthread_getspecific( _key ) );
- }
-
- void reset(T* v) {
- T* old = get();
- delete old;
- verify( pthread_setspecific( _key, v ) == 0 );
- }
-
- T* getMake() {
- T *t = get();
- if( t == 0 ) {
- t = new T();
- reset( t );
- }
- return t;
- }
- };
-
-# define TSP_DECLARE(T,p) extern TSP<T> p;
-
-# define TSP_DEFINE(T,p) TSP<T> p;
+#define TSP_DEFINE(T, p) TSP<T> p;
#else
- template< class T >
- struct TSP {
- thread_specific_ptr<T> tsp;
- public:
- T* get() const { return tsp.get(); }
- void reset(T* v) { tsp.reset(v); }
- T* getMake() {
- T *t = get();
- if( t == 0 )
- reset( t = new T() );
- return t;
- }
- };
-
-# define TSP_DECLARE(T,p) extern TSP<T> p;
-
-# define TSP_DEFINE(T,p) TSP<T> p;
+template <class T>
+struct TSP {
+ thread_specific_ptr<T> tsp;
+
+public:
+ T* get() const {
+ return tsp.get();
+ }
+ void reset(T* v) {
+ tsp.reset(v);
+ }
+ T* getMake() {
+ T* t = get();
+ if (t == 0)
+ reset(t = new T());
+ return t;
+ }
+};
+
+#define TSP_DECLARE(T, p) extern TSP<T> p;
+
+#define TSP_DEFINE(T, p) TSP<T> p;
#endif
-
}