summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorJosé Fonseca <jose.r.fonseca@gmail.com>2013-04-23 09:42:48 +0100
committerJosé Fonseca <jfonseca@vmware.com>2013-04-23 14:05:59 +0100
commitf990a51163275f22b77c91d10d1a9193fdaa40e6 (patch)
treeb1fae050cfadefc9b6c69180dc42df4737abd151 /common
parent4bfcd90edeba7775e4572bd6ff7454291603277c (diff)
Revert "Remove os::thread_specific_ptr"
Diffstat (limited to 'common')
-rw-r--r--common/os_thread.hpp81
1 files changed, 80 insertions, 1 deletions
diff --git a/common/os_thread.hpp b/common/os_thread.hpp
index 2c3f7325..5ec7f5dd 100644
--- a/common/os_thread.hpp
+++ b/common/os_thread.hpp
@@ -26,7 +26,7 @@
/*
* OS native thread abstraction.
*
- * Mimics C++11 threads.
+ * Mimics C++11 / boost threads.
*/
#ifndef _OS_THREAD_HPP_
@@ -284,6 +284,85 @@ namespace os {
/**
+ * Same interface as boost::thread_specific_ptr.
+ */
+ template <typename T>
+ class thread_specific_ptr
+ {
+ private:
+#ifdef _WIN32
+ DWORD dwTlsIndex;
+#else
+ pthread_key_t key;
+
+ static void destructor(void *ptr) {
+ delete static_cast<T *>(ptr);
+ }
+#endif
+
+ public:
+ thread_specific_ptr(void) {
+#ifdef _WIN32
+ dwTlsIndex = TlsAlloc();
+#else
+ pthread_key_create(&key, &destructor);
+#endif
+ }
+
+ ~thread_specific_ptr() {
+#ifdef _WIN32
+ TlsFree(dwTlsIndex);
+#else
+ pthread_key_delete(key);
+#endif
+ }
+
+ T* get(void) const {
+ void *ptr;
+#ifdef _WIN32
+ ptr = TlsGetValue(dwTlsIndex);
+#else
+ ptr = pthread_getspecific(key);
+#endif
+ return static_cast<T*>(ptr);
+ }
+
+ T* operator -> (void) const
+ {
+ return get();
+ }
+
+ T& operator * (void) const
+ {
+ return *get();
+ }
+
+ void reset(T* new_value=0) {
+ T * old_value = get();
+ set(new_value);
+ if (old_value) {
+ delete old_value;
+ }
+ }
+
+ T* release (void) {
+ T * old_value = get();
+ set(0);
+ return old_value;
+ }
+
+private:
+ void set(T* new_value) {
+#ifdef _WIN32
+ TlsSetValue(dwTlsIndex, new_value);
+#else
+ pthread_setspecific(key, new_value);
+#endif
+ }
+ };
+
+
+ /**
* Same interface as std::thread
*/
class thread {