• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 //          Copyright Oliver Kowalke 2013.
3 // Distributed under the Boost Software License, Version 1.0.
4 //    (See accompanying file LICENSE_1_0.txt or copy at
5 //          http://www.boost.org/LICENSE_1_0.txt)
6 //
7 //          based on tss.hpp from boost.thread
8 
9 #ifndef BOOST_FIBERS_FSS_H
10 #define BOOST_FIBERS_FSS_H
11 
12 #include <boost/config.hpp>
13 
14 #include <boost/fiber/context.hpp>
15 #include <boost/fiber/detail/fss.hpp>
16 
17 #ifdef BOOST_HAS_ABI_HEADERS
18 #  include BOOST_ABI_PREFIX
19 #endif
20 
21 namespace boost {
22 namespace fibers {
23 
24 template< typename T >
25 class fiber_specific_ptr {
26 private:
27     struct default_cleanup_function : public detail::fss_cleanup_function {
operator ()boost::fibers::fiber_specific_ptr::default_cleanup_function28         void operator()( void * data) noexcept override {
29             delete static_cast< T * >( data);
30         }
31     };
32 
33     struct custom_cleanup_function : public detail::fss_cleanup_function {
34         void (*fn)(T*);
35 
custom_cleanup_functionboost::fibers::fiber_specific_ptr::custom_cleanup_function36         explicit custom_cleanup_function( void(*fn_)(T*) ) noexcept :
37             fn{ fn_ } {
38         }
39 
operator ()boost::fibers::fiber_specific_ptr::custom_cleanup_function40         void operator()( void * data) override {
41             if ( BOOST_LIKELY( nullptr != fn) ) {
42                 fn( static_cast< T * >( data) );
43             }
44         }
45     };
46 
47     detail::fss_cleanup_function::ptr_t cleanup_fn_;
48 
49 public:
50     using element_type = T;
51 
fiber_specific_ptr()52     fiber_specific_ptr() :
53         cleanup_fn_{ new default_cleanup_function() } {
54     }
55 
fiber_specific_ptr(void (* fn)(T *))56     explicit fiber_specific_ptr( void(*fn)(T*) ) :
57         cleanup_fn_{ new custom_cleanup_function( fn) } {
58     }
59 
~fiber_specific_ptr()60     ~fiber_specific_ptr() {
61         context * active_ctx = context::active();
62         if ( nullptr != active_ctx) {
63             active_ctx->set_fss_data(
64                 this, cleanup_fn_, nullptr, true);
65         }
66     }
67 
68     fiber_specific_ptr( fiber_specific_ptr const&) = delete;
69     fiber_specific_ptr & operator=( fiber_specific_ptr const&) = delete;
70 
get() const71     T * get() const noexcept {
72         BOOST_ASSERT( context::active() );
73         void * vp = context::active()->get_fss_data( this);
74         return static_cast< T * >( vp);
75     }
76 
operator ->() const77     T * operator->() const noexcept {
78         return get();
79     }
80 
operator *() const81     T & operator*() const noexcept {
82         return * get();
83     }
84 
release()85     T * release() {
86         T * tmp = get();
87         context::active()->set_fss_data(
88             this, cleanup_fn_, nullptr, false);
89         return tmp;
90     }
91 
reset(T * t)92     void reset( T * t) {
93         T * c = get();
94         if ( BOOST_LIKELY( c != t) ) {
95             context::active()->set_fss_data(
96                 this, cleanup_fn_, t, true);
97         }
98     }
99 };
100 
101 }}
102 
103 #ifdef BOOST_HAS_ABI_HEADERS
104 #  include BOOST_ABI_SUFFIX
105 #endif
106 
107 #endif //  BOOST_FIBERS_FSS_H
108