future continues ...
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@112284 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/thread b/include/thread
index fffd2df..123c472 100644
--- a/include/thread
+++ b/include/thread
@@ -103,6 +103,68 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _Tp>
+class __thread_specific_ptr
+{
+ pthread_key_t __key_;
+
+ __thread_specific_ptr(const __thread_specific_ptr&);
+ __thread_specific_ptr& operator=(const __thread_specific_ptr&);
+
+ static void __at_thread_exit(void*);
+public:
+ typedef _Tp* pointer;
+
+ __thread_specific_ptr();
+ ~__thread_specific_ptr();
+
+ pointer get() const {return static_cast<_Tp*>(pthread_getspecific(__key_));}
+ pointer operator*() const {return *get();}
+ pointer operator->() const {return get();}
+ pointer release();
+ void reset(pointer __p = nullptr);
+};
+
+template <class _Tp>
+void
+__thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
+{
+ delete static_cast<pointer>(__p);
+}
+
+template <class _Tp>
+__thread_specific_ptr<_Tp>::__thread_specific_ptr()
+{
+ int __ec = pthread_key_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
+ if (__ec)
+ throw system_error(error_code(__ec, system_category()),
+ "__thread_specific_ptr construction failed");
+}
+
+template <class _Tp>
+__thread_specific_ptr<_Tp>::~__thread_specific_ptr()
+{
+ pthread_key_delete(__key_);
+}
+
+template <class _Tp>
+typename __thread_specific_ptr<_Tp>::pointer
+__thread_specific_ptr<_Tp>::release()
+{
+ pointer __p = get();
+ pthread_setspecific(__key_, 0);
+ return __p;
+}
+
+template <class _Tp>
+void
+__thread_specific_ptr<_Tp>::reset(pointer __p)
+{
+ pointer __p_old = get();
+ pthread_setspecific(__key_, __p);
+ delete __p_old;
+}
+
class thread;
class __thread_id;
@@ -219,10 +281,30 @@
static unsigned hardware_concurrency();
};
+class __assoc_sub_state;
+
+class __thread_struct_imp;
+
+class __thread_struct
+{
+ __thread_struct_imp* __p_;
+
+ __thread_struct(const __thread_struct&);
+ __thread_struct& operator=(const __thread_struct&);
+public:
+ __thread_struct();
+ ~__thread_struct();
+
+ void __make_ready_at_thread_exit(__assoc_sub_state*);
+};
+
+extern __thread_specific_ptr<__thread_struct> __thread_local_data;
+
template <class _F>
void*
__thread_proxy(void* __vp)
{
+ __thread_local_data.reset(new __thread_struct);
std::unique_ptr<_F> __p(static_cast<_F*>(__vp));
(*__p)();
return nullptr;