comparison DEPENDENCIES/generic/include/boost/asio/impl/spawn.hpp @ 101:c530137014c0

Update Boost headers (1.58.0)
author Chris Cannam
date Mon, 07 Sep 2015 11:12:49 +0100
parents 2665513ce2d3
children
comparison
equal deleted inserted replaced
100:793467b5e61c 101:c530137014c0
1 // 1 //
2 // impl/spawn.hpp 2 // impl/spawn.hpp
3 // ~~~~~~~~~~~~~~ 3 // ~~~~~~~~~~~~~~
4 // 4 //
5 // Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) 5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 // 6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying 7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 // 9 //
10 10
15 # pragma once 15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 17
18 #include <boost/asio/detail/config.hpp> 18 #include <boost/asio/detail/config.hpp>
19 #include <boost/asio/async_result.hpp> 19 #include <boost/asio/async_result.hpp>
20 #include <boost/asio/detail/atomic_count.hpp>
20 #include <boost/asio/detail/handler_alloc_helpers.hpp> 21 #include <boost/asio/detail/handler_alloc_helpers.hpp>
21 #include <boost/asio/detail/handler_cont_helpers.hpp> 22 #include <boost/asio/detail/handler_cont_helpers.hpp>
22 #include <boost/asio/detail/handler_invoke_helpers.hpp> 23 #include <boost/asio/detail/handler_invoke_helpers.hpp>
23 #include <boost/asio/detail/noncopyable.hpp> 24 #include <boost/asio/detail/noncopyable.hpp>
24 #include <boost/asio/detail/shared_ptr.hpp> 25 #include <boost/asio/detail/shared_ptr.hpp>
36 public: 37 public:
37 coro_handler(basic_yield_context<Handler> ctx) 38 coro_handler(basic_yield_context<Handler> ctx)
38 : coro_(ctx.coro_.lock()), 39 : coro_(ctx.coro_.lock()),
39 ca_(ctx.ca_), 40 ca_(ctx.ca_),
40 handler_(ctx.handler_), 41 handler_(ctx.handler_),
42 ready_(0),
41 ec_(ctx.ec_), 43 ec_(ctx.ec_),
42 value_(0) 44 value_(0)
43 { 45 {
44 } 46 }
45 47
46 void operator()(T value) 48 void operator()(T value)
47 { 49 {
48 *ec_ = boost::system::error_code(); 50 *ec_ = boost::system::error_code();
49 *value_ = value; 51 *value_ = BOOST_ASIO_MOVE_CAST(T)(value);
50 (*coro_)(); 52 if (--*ready_ == 0)
53 (*coro_)();
51 } 54 }
52 55
53 void operator()(boost::system::error_code ec, T value) 56 void operator()(boost::system::error_code ec, T value)
54 { 57 {
55 *ec_ = ec; 58 *ec_ = ec;
56 *value_ = value; 59 *value_ = BOOST_ASIO_MOVE_CAST(T)(value);
57 (*coro_)(); 60 if (--*ready_ == 0)
61 (*coro_)();
58 } 62 }
59 63
60 //private: 64 //private:
61 shared_ptr<typename basic_yield_context<Handler>::callee_type> coro_; 65 shared_ptr<typename basic_yield_context<Handler>::callee_type> coro_;
62 typename basic_yield_context<Handler>::caller_type& ca_; 66 typename basic_yield_context<Handler>::caller_type& ca_;
63 Handler& handler_; 67 Handler& handler_;
68 atomic_count* ready_;
64 boost::system::error_code* ec_; 69 boost::system::error_code* ec_;
65 T* value_; 70 T* value_;
66 }; 71 };
67 72
68 template <typename Handler> 73 template <typename Handler>
71 public: 76 public:
72 coro_handler(basic_yield_context<Handler> ctx) 77 coro_handler(basic_yield_context<Handler> ctx)
73 : coro_(ctx.coro_.lock()), 78 : coro_(ctx.coro_.lock()),
74 ca_(ctx.ca_), 79 ca_(ctx.ca_),
75 handler_(ctx.handler_), 80 handler_(ctx.handler_),
81 ready_(0),
76 ec_(ctx.ec_) 82 ec_(ctx.ec_)
77 { 83 {
78 } 84 }
79 85
80 void operator()() 86 void operator()()
81 { 87 {
82 *ec_ = boost::system::error_code(); 88 *ec_ = boost::system::error_code();
83 (*coro_)(); 89 if (--*ready_ == 0)
90 (*coro_)();
84 } 91 }
85 92
86 void operator()(boost::system::error_code ec) 93 void operator()(boost::system::error_code ec)
87 { 94 {
88 *ec_ = ec; 95 *ec_ = ec;
89 (*coro_)(); 96 if (--*ready_ == 0)
97 (*coro_)();
90 } 98 }
91 99
92 //private: 100 //private:
93 shared_ptr<typename basic_yield_context<Handler>::callee_type> coro_; 101 shared_ptr<typename basic_yield_context<Handler>::callee_type> coro_;
94 typename basic_yield_context<Handler>::caller_type& ca_; 102 typename basic_yield_context<Handler>::caller_type& ca_;
95 Handler& handler_; 103 Handler& handler_;
104 atomic_count* ready_;
96 boost::system::error_code* ec_; 105 boost::system::error_code* ec_;
97 }; 106 };
98 107
99 template <typename Handler, typename T> 108 template <typename Handler, typename T>
100 inline void* asio_handler_allocate(std::size_t size, 109 inline void* asio_handler_allocate(std::size_t size,
169 { 178 {
170 public: 179 public:
171 typedef T type; 180 typedef T type;
172 181
173 explicit async_result(detail::coro_handler<Handler, T>& h) 182 explicit async_result(detail::coro_handler<Handler, T>& h)
174 : ca_(h.ca_) 183 : handler_(h),
175 { 184 ca_(h.ca_),
185 ready_(2)
186 {
187 h.ready_ = &ready_;
176 out_ec_ = h.ec_; 188 out_ec_ = h.ec_;
177 if (!out_ec_) h.ec_ = &ec_; 189 if (!out_ec_) h.ec_ = &ec_;
178 h.value_ = &value_; 190 h.value_ = &value_;
179 } 191 }
180 192
181 type get() 193 type get()
182 { 194 {
183 ca_(); 195 handler_.coro_.reset(); // Must not hold shared_ptr to coro while suspended.
196 if (--ready_ != 0)
197 ca_();
184 if (!out_ec_ && ec_) throw boost::system::system_error(ec_); 198 if (!out_ec_ && ec_) throw boost::system::system_error(ec_);
185 return value_; 199 return BOOST_ASIO_MOVE_CAST(type)(value_);
186 } 200 }
187 201
188 private: 202 private:
203 detail::coro_handler<Handler, T>& handler_;
189 typename basic_yield_context<Handler>::caller_type& ca_; 204 typename basic_yield_context<Handler>::caller_type& ca_;
205 detail::atomic_count ready_;
190 boost::system::error_code* out_ec_; 206 boost::system::error_code* out_ec_;
191 boost::system::error_code ec_; 207 boost::system::error_code ec_;
192 type value_; 208 type value_;
193 }; 209 };
194 210
197 { 213 {
198 public: 214 public:
199 typedef void type; 215 typedef void type;
200 216
201 explicit async_result(detail::coro_handler<Handler, void>& h) 217 explicit async_result(detail::coro_handler<Handler, void>& h)
202 : ca_(h.ca_) 218 : handler_(h),
203 { 219 ca_(h.ca_),
220 ready_(2)
221 {
222 h.ready_ = &ready_;
204 out_ec_ = h.ec_; 223 out_ec_ = h.ec_;
205 if (!out_ec_) h.ec_ = &ec_; 224 if (!out_ec_) h.ec_ = &ec_;
206 } 225 }
207 226
208 void get() 227 void get()
209 { 228 {
210 ca_(); 229 handler_.coro_.reset(); // Must not hold shared_ptr to coro while suspended.
230 if (--ready_ != 0)
231 ca_();
211 if (!out_ec_ && ec_) throw boost::system::system_error(ec_); 232 if (!out_ec_ && ec_) throw boost::system::system_error(ec_);
212 } 233 }
213 234
214 private: 235 private:
236 detail::coro_handler<Handler, void>& handler_;
215 typename basic_yield_context<Handler>::caller_type& ca_; 237 typename basic_yield_context<Handler>::caller_type& ca_;
238 detail::atomic_count ready_;
216 boost::system::error_code* out_ec_; 239 boost::system::error_code* out_ec_;
217 boost::system::error_code ec_; 240 boost::system::error_code ec_;
218 }; 241 };
219 242
220 namespace detail { 243 namespace detail {
240 struct coro_entry_point 263 struct coro_entry_point
241 { 264 {
242 void operator()(typename basic_yield_context<Handler>::caller_type& ca) 265 void operator()(typename basic_yield_context<Handler>::caller_type& ca)
243 { 266 {
244 shared_ptr<spawn_data<Handler, Function> > data(data_); 267 shared_ptr<spawn_data<Handler, Function> > data(data_);
268 #if !defined(BOOST_COROUTINES_UNIDIRECT) && !defined(BOOST_COROUTINES_V2)
245 ca(); // Yield until coroutine pointer has been initialised. 269 ca(); // Yield until coroutine pointer has been initialised.
270 #endif // !defined(BOOST_COROUTINES_UNIDIRECT) && !defined(BOOST_COROUTINES_V2)
246 const basic_yield_context<Handler> yield( 271 const basic_yield_context<Handler> yield(
247 data->coro_, ca, data->handler_); 272 data->coro_, ca, data->handler_);
248 (data->function_)(yield); 273 (data->function_)(yield);
249 if (data->call_handler_) 274 if (data->call_handler_)
250 (data->handler_)(); 275 (data->handler_)();