ossrv_pub/boost_apis/boost/thread/tss.hpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright (C) 2001-2003 William E. Kempf
       
     2 // Copyright (C) 2006 Roland Schwarz
       
     3 //
       
     4 //  Distributed under the Boost Software License, Version 1.0. (See accompanying 
       
     5 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       
     6 
       
     7 #ifndef BOOST_TSS_WEK070601_HPP
       
     8 #define BOOST_TSS_WEK070601_HPP
       
     9 
       
    10 #include <boost/thread/detail/config.hpp>
       
    11 
       
    12 #include <boost/utility.hpp>
       
    13 #include <boost/function.hpp>
       
    14 #include <boost/thread/exceptions.hpp>
       
    15 
       
    16 #if defined(BOOST_HAS_PTHREADS)
       
    17 #   include <pthread.h>
       
    18 #elif defined(BOOST_HAS_MPTASKS)
       
    19 #   include <Multiprocessing.h>
       
    20 #endif
       
    21 
       
    22 namespace boost {
       
    23 
       
    24 // disable warnings about non dll import
       
    25 // see: http://www.boost.org/more/separate_compilation.html#dlls
       
    26 #ifdef BOOST_MSVC
       
    27 #   pragma warning(push)
       
    28 #   pragma warning(disable: 4251 4231 4660 4275)
       
    29 #endif
       
    30 
       
    31 namespace detail {
       
    32 
       
    33 class BOOST_THREAD_DECL tss : private noncopyable
       
    34 {
       
    35 public:
       
    36     tss(boost::function1<void, void*>* pcleanup) {
       
    37         if (pcleanup == 0) throw boost::thread_resource_error();
       
    38         try
       
    39         {
       
    40             init(pcleanup);
       
    41         }
       
    42         catch (...)
       
    43         {
       
    44             delete pcleanup;
       
    45             throw boost::thread_resource_error();
       
    46         }
       
    47     }
       
    48 
       
    49     ~tss();
       
    50     void* get() const;
       
    51     void set(void* value);
       
    52     void cleanup(void* p);
       
    53 
       
    54 private:
       
    55     unsigned int m_slot; //This is a "pseudo-slot", not a native slot
       
    56 
       
    57     void init(boost::function1<void, void*>* pcleanup);
       
    58 };
       
    59 
       
    60 #if defined(BOOST_HAS_MPTASKS)
       
    61 void thread_cleanup();
       
    62 #endif
       
    63 
       
    64 template <typename T>
       
    65 struct tss_adapter
       
    66 {
       
    67     template <typename F>
       
    68     tss_adapter(const F& cleanup) : m_cleanup(cleanup) { }
       
    69     void operator()(void* p) { m_cleanup(static_cast<T*>(p)); }
       
    70     boost::function1<void, T*> m_cleanup;
       
    71 };
       
    72 
       
    73 } // namespace detail
       
    74 
       
    75 template <typename T>
       
    76 class thread_specific_ptr : private noncopyable
       
    77 {
       
    78 public:
       
    79     thread_specific_ptr()
       
    80         : m_tss(new boost::function1<void, void*>(
       
    81                     boost::detail::tss_adapter<T>(
       
    82                         &thread_specific_ptr<T>::cleanup)))
       
    83     {
       
    84     }
       
    85     thread_specific_ptr(void (*clean)(T*))
       
    86         : m_tss(new boost::function1<void, void*>(
       
    87                     boost::detail::tss_adapter<T>(clean)))
       
    88     {
       
    89     }
       
    90     ~thread_specific_ptr() { reset(); }
       
    91 
       
    92     T* get() const { return static_cast<T*>(m_tss.get()); }
       
    93     T* operator->() const { return get(); }
       
    94     T& operator*() const { return *get(); }
       
    95     T* release() { T* temp = get(); if (temp) m_tss.set(0); return temp; }
       
    96     void reset(T* p=0)
       
    97     {
       
    98         T* cur = get();
       
    99         if (cur == p) return;
       
   100         m_tss.set(p);
       
   101         if (cur) m_tss.cleanup(cur);
       
   102     }
       
   103 
       
   104 private:
       
   105     static void cleanup(T* p) { delete p; }
       
   106     detail::tss m_tss;
       
   107 };
       
   108 
       
   109 #ifdef BOOST_MSVC
       
   110 #   pragma warning(pop)
       
   111 #endif
       
   112 
       
   113 } // namespace boost
       
   114 
       
   115 #endif //BOOST_TSS_WEK070601_HPP
       
   116 
       
   117 // Change Log:
       
   118 //   6 Jun 01  
       
   119 //      WEKEMPF Initial version.
       
   120 //  30 May 02  WEKEMPF 
       
   121 //      Added interface to set specific cleanup handlers.
       
   122 //      Removed TLS slot limits from most implementations.
       
   123 //  22 Mar 04 GlassfordM for WEKEMPF
       
   124 //      Fixed: thread_specific_ptr::reset() doesn't check error returned
       
   125 //          by tss::set(); tss::set() now throws if it fails.
       
   126 //      Fixed: calling thread_specific_ptr::reset() or 
       
   127 //          thread_specific_ptr::release() causes double-delete: once on
       
   128 //          reset()/release() and once on ~thread_specific_ptr().