1[/ 2 (C) Copyright 2007-8 Anthony Williams. 3 (C) Copyright 2013 Oliver Kowalke. 4 Distributed under the Boost Software License, Version 1.0. 5 (See accompanying file LICENSE_1_0.txt or copy at 6 http://www.boost.org/LICENSE_1_0.txt). 7] 8 9[section:fls Fiber local storage] 10 11[heading Synopsis] 12 13Fiber local storage allows a separate instance of a given data item for 14each fiber. 15 16[heading Cleanup at fiber exit] 17 18When a fiber exits, the objects associated with each __fsp__ instance are 19destroyed. By default, the object pointed to by a pointer `p` is destroyed by 20invoking `delete p`, but this can be overridden for a specific instance of 21__fsp__ by providing a cleanup routine `func` to the constructor. In this case, the 22object is destroyed by invoking `func(p)`. The cleanup functions are called in an unspecified 23order. 24 25[class_heading fiber_specific_ptr] 26 27 #include <boost/fiber/fss.hpp> 28 29 namespace boost { 30 namespace fibers { 31 32 template< typename T > 33 class fiber_specific_ptr { 34 public: 35 typedef T element_type; 36 37 fiber_specific_ptr(); 38 39 explicit fiber_specific_ptr( void(*fn)(T*) ); 40 41 ~fiber_specific_ptr(); 42 43 fiber_specific_ptr( fiber_specific_ptr const&) = delete; 44 fiber_specific_ptr & operator=( fiber_specific_ptr const&) = delete; 45 46 T * get() const noexcept; 47 48 T * operator->() const noexcept; 49 50 T & operator*() const noexcept; 51 52 T * release(); 53 54 void reset( T *); 55 }; 56 57 }} 58 59[heading Constructor] 60 61 fiber_specific_ptr(); 62 explicit fiber_specific_ptr( void(*fn)(T*) ); 63 64[variablelist 65[[Requires:] [`delete this->get()` is well-formed; `fn(this->get())` does not 66throw]] 67[[Effects:] [Construct a __fsp__ object for storing a pointer to an object of 68type `T` specific to each fiber. When `reset()` is called, or the 69fiber exits, __fsp__ calls `fn(this->get())`. If the no-arguments constructor 70is used, the default `delete`-based cleanup function 71will be used to destroy the fiber-local objects.]] 72[[Throws:] [__fiber_error__ if an error occurs.]] 73] 74 75[heading Destructor] 76 77 ~fiber_specific_ptr(); 78 79[variablelist 80[[Requires:] [All the fiber specific instances associated to this __fsp__ 81(except maybe the one associated to this fiber) must be nullptr.]] 82[[Effects:] [Calls `this->reset()` to clean up the associated value for the 83current fiber, and destroys `*this`.]] 84[[Remarks:] [The requirement is an implementation restriction. If the 85destructor promised to delete instances for all fibers, the implementation 86would be forced to maintain a list of all the fibers having an associated 87specific ptr, which is against the goal of fiber specific data. In general, a 88__fsp__ should outlive the fibers that use it.]] 89] 90[note Care needs to be taken to ensure that any fibers still running after an 91instance of __fsp__ has been destroyed do not call any member functions on that 92instance.] 93 94[member_heading fiber_specific_ptr..get] 95 96 T * get() const noexcept; 97 98[variablelist 99[[Returns:] [The pointer associated with the current fiber.]] 100[[Throws:] [Nothing.]] 101] 102[note The initial value associated with an instance of __fsp__ is `nullptr` for 103each fiber.] 104 105[operator_heading fiber_specific_ptr..operator_arrow..operator->] 106 107 T * operator->() const noexcept; 108 109[variablelist 110[[Requires:] [`this->get()` is not `nullptr`.]] 111[[Returns:] [`this->get()`]] 112[[Throws:] [Nothing.]] 113] 114 115[operator_heading fiber_specific_ptr..operator_star..operator*] 116 117 T & operator*() const noexcept; 118 119[variablelist 120[[Requires:] [`this->get()` is not `nullptr`.]] 121[[Returns:] [`*(this->get())`]] 122[[Throws:] [Nothing.]] 123] 124 125[member_heading fiber_specific_ptr..release] 126 127 T * release(); 128 129[variablelist 130[[Effects:] [Return `this->get()` and store `nullptr` as the pointer associated 131with the current fiber without invoking the cleanup function.]] 132[[Postcondition:] [`this->get()==nullptr`]] 133[[Throws:] [Nothing.]] 134] 135 136[member_heading fiber_specific_ptr..reset] 137 138 void reset( T * new_value); 139 140[variablelist 141[[Effects:] [If `this->get()!=new_value` and `this->get()` is not `nullptr`, 142invoke `delete this->get()` or `fn(this->get())` as appropriate. Store 143`new_value` as the pointer associated with the current fiber.]] 144[[Postcondition:] [`this->get()==new_value`]] 145[[Throws:] [Exception raised during cleanup of previous value.]] 146] 147 148[endsect] 149