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;