Realistic 3D camera system
3D camera system components
spawn.hpp
Go to the documentation of this file.
1 //
2 // impl/spawn.hpp
3 // ~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
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)
9 //
10 
11 #ifndef ASIO_IMPL_SPAWN_HPP
12 #define ASIO_IMPL_SPAWN_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include "asio/detail/config.hpp"
19 #include "asio/async_result.hpp"
26 #include "asio/handler_type.hpp"
27 
29 
30 namespace asio {
31 namespace detail {
32 
33  template <typename Handler, typename T>
35  {
36  public:
38  : coro_(ctx.coro_.lock()),
39  ca_(ctx.ca_),
40  handler_(ctx.handler_),
41  ready_(0),
42  ec_(ctx.ec_),
43  value_(0)
44  {
45  }
46 
47  void operator()(T value)
48  {
49  *ec_ = asio::error_code();
50  *value_ = ASIO_MOVE_CAST(T)(value);
51  if (--*ready_ == 0)
52  (*coro_)();
53  }
54 
55  void operator()(asio::error_code ec, T value)
56  {
57  *ec_ = ec;
58  *value_ = ASIO_MOVE_CAST(T)(value);
59  if (--*ready_ == 0)
60  (*coro_)();
61  }
62 
63  //private:
64  shared_ptr<typename basic_yield_context<Handler>::callee_type> coro_;
66  Handler& handler_;
69  T* value_;
70  };
71 
72  template <typename Handler>
73  class coro_handler<Handler, void>
74  {
75  public:
77  : coro_(ctx.coro_.lock()),
78  ca_(ctx.ca_),
79  handler_(ctx.handler_),
80  ready_(0),
81  ec_(ctx.ec_)
82  {
83  }
84 
85  void operator()()
86  {
87  *ec_ = asio::error_code();
88  if (--*ready_ == 0)
89  (*coro_)();
90  }
91 
93  {
94  *ec_ = ec;
95  if (--*ready_ == 0)
96  (*coro_)();
97  }
98 
99  //private:
100  shared_ptr<typename basic_yield_context<Handler>::callee_type> coro_;
102  Handler& handler_;
105  };
106 
107  template <typename Handler, typename T>
108  inline void* asio_handler_allocate(std::size_t size,
109  coro_handler<Handler, T>* this_handler)
110  {
112  size, this_handler->handler_);
113  }
114 
115  template <typename Handler, typename T>
116  inline void asio_handler_deallocate(void* pointer, std::size_t size,
117  coro_handler<Handler, T>* this_handler)
118  {
120  pointer, size, this_handler->handler_);
121  }
122 
123  template <typename Handler, typename T>
125  {
126  return true;
127  }
128 
129  template <typename Function, typename Handler, typename T>
130  inline void asio_handler_invoke(Function& function,
131  coro_handler<Handler, T>* this_handler)
132  {
134  function, this_handler->handler_);
135  }
136 
137  template <typename Function, typename Handler, typename T>
138  inline void asio_handler_invoke(const Function& function,
139  coro_handler<Handler, T>* this_handler)
140  {
142  function, this_handler->handler_);
143  }
144 
145 } // namespace detail
146 
147 #if !defined(GENERATING_DOCUMENTATION)
148 
149 template <typename Handler, typename ReturnType>
150 struct handler_type<basic_yield_context<Handler>, ReturnType()>
151 {
153 };
154 
155 template <typename Handler, typename ReturnType, typename Arg1>
156 struct handler_type<basic_yield_context<Handler>, ReturnType(Arg1)>
157 {
159 };
160 
161 template <typename Handler, typename ReturnType>
163  ReturnType(asio::error_code)>
164 {
166 };
167 
168 template <typename Handler, typename ReturnType, typename Arg2>
170  ReturnType(asio::error_code, Arg2)>
171 {
173 };
174 
175 template <typename Handler, typename T>
176 class async_result<detail::coro_handler<Handler, T> >
177 {
178 public:
179  typedef T type;
180 
182  : handler_(h),
183  ca_(h.ca_),
184  ready_(2)
185  {
186  h.ready_ = &ready_;
187  out_ec_ = h.ec_;
188  if (!out_ec_) h.ec_ = &ec_;
189  h.value_ = &value_;
190  }
191 
192  type get()
193  {
194  handler_.coro_.reset(); // Must not hold shared_ptr to coro while suspended.
195  if (--ready_ != 0)
196  ca_();
197  if (!out_ec_ && ec_) throw asio::system_error(ec_);
198  return ASIO_MOVE_CAST(type)(value_);
199  }
200 
201 private:
205  asio::error_code* out_ec_;
207  type value_;
208 };
209 
210 template <typename Handler>
211 class async_result<detail::coro_handler<Handler, void> >
212 {
213 public:
214  typedef void type;
215 
217  : handler_(h),
218  ca_(h.ca_),
219  ready_(2)
220  {
221  h.ready_ = &ready_;
222  out_ec_ = h.ec_;
223  if (!out_ec_) h.ec_ = &ec_;
224  }
225 
226  void get()
227  {
228  handler_.coro_.reset(); // Must not hold shared_ptr to coro while suspended.
229  if (--ready_ != 0)
230  ca_();
231  if (!out_ec_ && ec_) throw asio::system_error(ec_);
232  }
233 
234 private:
238  asio::error_code* out_ec_;
240 };
241 
242 namespace detail {
243 
244  template <typename Handler, typename Function>
245  struct spawn_data : private noncopyable
246  {
247  spawn_data(ASIO_MOVE_ARG(Handler) handler,
248  bool call_handler, ASIO_MOVE_ARG(Function) function)
249  : handler_(ASIO_MOVE_CAST(Handler)(handler)),
250  call_handler_(call_handler),
251  function_(ASIO_MOVE_CAST(Function)(function))
252  {
253  }
254 
255  weak_ptr<typename basic_yield_context<Handler>::callee_type> coro_;
256  Handler handler_;
258  Function function_;
259  };
260 
261  template <typename Handler, typename Function>
263  {
265  {
266  shared_ptr<spawn_data<Handler, Function> > data(data_);
267 #if !defined(BOOST_COROUTINES_UNIDIRECT) && !defined(BOOST_COROUTINES_V2)
268  ca(); // Yield until coroutine pointer has been initialised.
269 #endif // !defined(BOOST_COROUTINES_UNIDIRECT) && !defined(BOOST_COROUTINES_V2)
271  data->coro_, ca, data->handler_);
272  (data->function_)(yield);
273  if (data->call_handler_)
274  (data->handler_)();
275  }
276 
277  shared_ptr<spawn_data<Handler, Function> > data_;
278  };
279 
280  template <typename Handler, typename Function>
282  {
283  void operator()()
284  {
285  typedef typename basic_yield_context<Handler>::callee_type callee_type;
286  coro_entry_point<Handler, Function> entry_point = { data_ };
287  shared_ptr<callee_type> coro(new callee_type(entry_point, attributes_));
288  data_->coro_ = coro;
289  (*coro)();
290  }
291 
292  shared_ptr<spawn_data<Handler, Function> > data_;
293  boost::coroutines::attributes attributes_;
294  };
295 
296  inline void default_spawn_handler() {}
297 
298 } // namespace detail
299 
300 template <typename Handler, typename Function>
301 void spawn(ASIO_MOVE_ARG(Handler) handler,
302  ASIO_MOVE_ARG(Function) function,
303  const boost::coroutines::attributes& attributes)
304 {
306  helper.data_.reset(
308  ASIO_MOVE_CAST(Handler)(handler), true,
309  ASIO_MOVE_CAST(Function)(function)));
310  helper.attributes_ = attributes;
311  asio_handler_invoke_helpers::invoke(helper, helper.data_->handler_);
312 }
313 
314 template <typename Handler, typename Function>
316  ASIO_MOVE_ARG(Function) function,
317  const boost::coroutines::attributes& attributes)
318 {
319  Handler handler(ctx.handler_); // Explicit copy that might be moved from.
321  helper.data_.reset(
323  ASIO_MOVE_CAST(Handler)(handler), false,
324  ASIO_MOVE_CAST(Function)(function)));
325  helper.attributes_ = attributes;
326  asio_handler_invoke_helpers::invoke(helper, helper.data_->handler_);
327 }
328 
329 template <typename Function>
331  ASIO_MOVE_ARG(Function) function,
332  const boost::coroutines::attributes& attributes)
333 {
335  ASIO_MOVE_CAST(Function)(function), attributes);
336 }
337 
338 template <typename Function>
340  ASIO_MOVE_ARG(Function) function,
341  const boost::coroutines::attributes& attributes)
342 {
344  ASIO_MOVE_CAST(Function)(function), attributes);
345 }
346 
347 #endif // !defined(GENERATING_DOCUMENTATION)
348 
349 } // namespace asio
350 
352 
353 #endif // ASIO_IMPL_SPAWN_HPP
shared_ptr< typename basic_yield_context< Handler >::callee_type > coro_
Definition: spawn.hpp:100
void default_spawn_handler()
Definition: spawn.hpp:296
void asio_handler_deallocate(void *pointer, std::size_t size, binder1< Handler, Arg1 > *this_handler)
boost::coroutines::attributes attributes_
Definition: spawn.hpp:293
Provides core I/O functionality.
Definition: io_service.hpp:184
async_result(detail::coro_handler< Handler, T > &h)
Definition: spawn.hpp:181
shared_ptr< typename basic_yield_context< Handler >::callee_type > coro_
Definition: spawn.hpp:64
void operator()(T value)
Definition: spawn.hpp:47
void * asio_handler_allocate(std::size_t size, binder1< Handler, Arg1 > *this_handler)
async_result(detail::coro_handler< Handler, void > &h)
Definition: spawn.hpp:216
void operator()(typename basic_yield_context< Handler >::caller_type &ca)
Definition: spawn.hpp:264
An interface for customising the behaviour of an initiating function.
Provides serialised handler execution.
Definition: strand.hpp:85
coro_handler(basic_yield_context< Handler > ctx)
Definition: spawn.hpp:76
shared_ptr< spawn_data< Handler, Function > > data_
Definition: spawn.hpp:292
void invoke(Function &function, Context &context)
atomic_count * ready_
Definition: spawn.hpp:67
shared_ptr< spawn_data< Handler, Function > > data_
Definition: spawn.hpp:277
asio::error_code * ec_
Definition: spawn.hpp:68
boost::coroutines::coroutine< void()> callee_type
The coroutine callee type, used by the implementation.
Definition: spawn.hpp:63
void operator()(asio::error_code ec, T value)
Definition: spawn.hpp:55
Context object the represents the currently executing coroutine.
Definition: spawn.hpp:48
void asio_handler_invoke(Function &function, binder1< Handler, Arg1 > *this_handler)
asio::basic_streambuf< Allocator > CompletionCondition ASIO_MOVE_ARG(ReadHandler) handler)
Definition: read.hpp:704
Class to represent an error code value.
Definition: error_code.hpp:80
void deallocate(void *p, std::size_t s, Handler &h)
spawn_data(ASIO_MOVE_ARG(Handler) handler, bool call_handler, ASIO_MOVE_ARG(Function) function)
Definition: spawn.hpp:247
coro_handler(basic_yield_context< Handler > ctx)
Definition: spawn.hpp:37
void spawn(ASIO_MOVE_ARG(Handler) handler, ASIO_MOVE_ARG(Function) function, const boost::coroutines::attributes &attributes)
Definition: spawn.hpp:301
basic_yield_context< Handler >::caller_type & ca_
Definition: spawn.hpp:101
weak_ptr< typename basic_yield_context< Handler >::callee_type > coro_
Definition: spawn.hpp:255
#define yield
Definition: yield.hpp:18
detail::wrapped_handler< strand, Handler, detail::is_continuation_if_running > wrap(Handler handler)
Definition: strand.hpp:222
void * allocate(std::size_t s, Handler &h)
void operator()(asio::error_code ec)
Definition: spawn.hpp:92
#define ASIO_MOVE_CAST(type)
Definition: config.hpp:138
bool asio_handler_is_continuation(binder1< Handler, Arg1 > *this_handler)
Default handler type traits provided for all handlers.
Definition: spawn.hpp:262
boost::coroutines::coroutine< void()>::caller_type caller_type
The coroutine caller type, used by the implementation.
Definition: spawn.hpp:78
basic_yield_context< Handler >::caller_type & ca_
Definition: spawn.hpp:65