]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/fiber/fiber.hpp
2e77d69274a02add450ade06c18ce98d9eaf47fb
[ceph.git] / ceph / src / boost / boost / fiber / fiber.hpp
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 #ifndef BOOST_FIBERS_FIBER_H
8 #define BOOST_FIBERS_FIBER_H
9
10 #include <algorithm>
11 #include <exception>
12 #include <memory>
13 #include <utility>
14
15 #include <boost/assert.hpp>
16 #include <boost/config.hpp>
17 #include <boost/intrusive_ptr.hpp>
18 #include <boost/predef.h>
19
20 #include <boost/fiber/detail/config.hpp>
21 #include <boost/fiber/detail/disable_overload.hpp>
22 #include <boost/fiber/context.hpp>
23 #include <boost/fiber/fixedsize_stack.hpp>
24 #include <boost/fiber/policy.hpp>
25 #include <boost/fiber/properties.hpp>
26 #include <boost/fiber/segmented_stack.hpp>
27
28 #ifdef BOOST_HAS_ABI_HEADERS
29 # include BOOST_ABI_PREFIX
30 #endif
31
32 #ifdef _MSC_VER
33 # pragma warning(push)
34 # pragma warning(disable:4251)
35 #endif
36
37 namespace boost {
38 namespace fibers {
39
40 class BOOST_FIBERS_DECL fiber {
41 private:
42 friend class context;
43
44 using ptr_t = intrusive_ptr<context>;
45
46 ptr_t impl_{};
47
48 void start_() noexcept;
49
50 public:
51 using id = context::id;
52
53 fiber() = default;
54
55 template< typename Fn,
56 typename ... Arg,
57 typename = detail::disable_overload< fiber, Fn >,
58 typename = detail::disable_overload< launch, Fn >,
59 typename = detail::disable_overload< std::allocator_arg_t, Fn >
60 >
61 #if BOOST_COMP_GNUC < 50000000
62 explicit fiber( Fn && fn, Arg && ... arg) :
63 #else
64 fiber( Fn && fn, Arg ... arg) :
65 #endif
66 fiber{ launch::post,
67 std::allocator_arg, default_stack(),
68 std::forward< Fn >( fn), std::forward< Arg >( arg) ... } {
69 }
70
71 template< typename Fn,
72 typename ... Arg,
73 typename = detail::disable_overload< fiber, Fn >
74 >
75 #if BOOST_COMP_GNUC < 50000000
76 fiber( launch policy, Fn && fn, Arg && ... arg) :
77 #else
78 fiber( launch policy, Fn && fn, Arg ... arg) :
79 #endif
80 fiber{ policy,
81 std::allocator_arg, default_stack(),
82 std::forward< Fn >( fn), std::forward< Arg >( arg) ... } {
83 }
84
85 template< typename StackAllocator,
86 typename Fn,
87 typename ... Arg
88 >
89 #if BOOST_COMP_GNUC < 50000000
90 fiber( std::allocator_arg_t, StackAllocator && salloc, Fn && fn, Arg && ... arg) :
91 #else
92 fiber( std::allocator_arg_t, StackAllocator && salloc, Fn && fn, Arg ... arg) :
93 #endif
94 fiber{ launch::post,
95 std::allocator_arg, std::forward< StackAllocator >( salloc),
96 std::forward< Fn >( fn), std::forward< Arg >( arg) ... } {
97 }
98
99 template< typename StackAllocator,
100 typename Fn,
101 typename ... Arg
102 >
103 #if BOOST_COMP_GNUC < 50000000
104 fiber( launch policy, std::allocator_arg_t, StackAllocator && salloc, Fn && fn, Arg && ... arg) :
105 #else
106 fiber( launch policy, std::allocator_arg_t, StackAllocator && salloc, Fn && fn, Arg ... arg) :
107 #endif
108 impl_{ make_worker_context( policy, std::forward< StackAllocator >( salloc), std::forward< Fn >( fn), std::forward< Arg >( arg) ... ) } {
109 start_();
110 }
111
112 ~fiber() {
113 if ( joinable() ) {
114 std::terminate();
115 }
116 }
117
118 fiber( fiber const&) = delete;
119 fiber & operator=( fiber const&) = delete;
120
121 fiber( fiber && other) noexcept :
122 impl_{} {
123 swap( other);
124 }
125
126 fiber & operator=( fiber && other) noexcept {
127 if ( joinable() ) {
128 std::terminate();
129 }
130 if ( BOOST_UNLIKELY( this == & other) ) {
131 return * this;
132 }
133 impl_.swap( other.impl_);
134 return * this;
135 }
136
137 void swap( fiber & other) noexcept {
138 impl_.swap( other.impl_);
139 }
140
141 id get_id() const noexcept {
142 return impl_ ? impl_->get_id() : id();
143 }
144
145 bool joinable() const noexcept {
146 return nullptr != impl_;
147 }
148
149 void join();
150
151 void detach();
152
153 template< typename PROPS >
154 PROPS & properties() {
155 auto props = impl_->get_properties();
156 BOOST_ASSERT_MSG( props, "fiber::properties not set");
157 return dynamic_cast< PROPS & >( * props );
158 }
159 };
160
161 inline
162 bool operator<( fiber const& l, fiber const& r) noexcept {
163 return l.get_id() < r.get_id();
164 }
165
166 inline
167 void swap( fiber & l, fiber & r) noexcept {
168 return l.swap( r);
169 }
170
171 }}
172
173 #ifdef _MSC_VER
174 # pragma warning(pop)
175 #endif
176
177 #ifdef BOOST_HAS_ABI_HEADERS
178 # include BOOST_ABI_SUFFIX
179 #endif
180
181 #endif // BOOST_FIBERS_FIBER_H