diff 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
line wrap: on
line diff
--- a/DEPENDENCIES/generic/include/boost/asio/impl/spawn.hpp	Fri Sep 04 12:01:02 2015 +0100
+++ b/DEPENDENCIES/generic/include/boost/asio/impl/spawn.hpp	Mon Sep 07 11:12:49 2015 +0100
@@ -2,7 +2,7 @@
 // impl/spawn.hpp
 // ~~~~~~~~~~~~~~
 //
-// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
 // Distributed under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -17,6 +17,7 @@
 
 #include <boost/asio/detail/config.hpp>
 #include <boost/asio/async_result.hpp>
+#include <boost/asio/detail/atomic_count.hpp>
 #include <boost/asio/detail/handler_alloc_helpers.hpp>
 #include <boost/asio/detail/handler_cont_helpers.hpp>
 #include <boost/asio/detail/handler_invoke_helpers.hpp>
@@ -38,6 +39,7 @@
       : coro_(ctx.coro_.lock()),
         ca_(ctx.ca_),
         handler_(ctx.handler_),
+        ready_(0),
         ec_(ctx.ec_),
         value_(0)
     {
@@ -46,21 +48,24 @@
     void operator()(T value)
     {
       *ec_ = boost::system::error_code();
-      *value_ = value;
-      (*coro_)();
+      *value_ = BOOST_ASIO_MOVE_CAST(T)(value);
+      if (--*ready_ == 0)
+        (*coro_)();
     }
 
     void operator()(boost::system::error_code ec, T value)
     {
       *ec_ = ec;
-      *value_ = value;
-      (*coro_)();
+      *value_ = BOOST_ASIO_MOVE_CAST(T)(value);
+      if (--*ready_ == 0)
+        (*coro_)();
     }
 
   //private:
     shared_ptr<typename basic_yield_context<Handler>::callee_type> coro_;
     typename basic_yield_context<Handler>::caller_type& ca_;
     Handler& handler_;
+    atomic_count* ready_;
     boost::system::error_code* ec_;
     T* value_;
   };
@@ -73,6 +78,7 @@
       : coro_(ctx.coro_.lock()),
         ca_(ctx.ca_),
         handler_(ctx.handler_),
+        ready_(0),
         ec_(ctx.ec_)
     {
     }
@@ -80,19 +86,22 @@
     void operator()()
     {
       *ec_ = boost::system::error_code();
-      (*coro_)();
+      if (--*ready_ == 0)
+        (*coro_)();
     }
 
     void operator()(boost::system::error_code ec)
     {
       *ec_ = ec;
-      (*coro_)();
+      if (--*ready_ == 0)
+        (*coro_)();
     }
 
   //private:
     shared_ptr<typename basic_yield_context<Handler>::callee_type> coro_;
     typename basic_yield_context<Handler>::caller_type& ca_;
     Handler& handler_;
+    atomic_count* ready_;
     boost::system::error_code* ec_;
   };
 
@@ -171,8 +180,11 @@
   typedef T type;
 
   explicit async_result(detail::coro_handler<Handler, T>& h)
-    : ca_(h.ca_)
+    : handler_(h),
+      ca_(h.ca_),
+      ready_(2)
   {
+    h.ready_ = &ready_;
     out_ec_ = h.ec_;
     if (!out_ec_) h.ec_ = &ec_;
     h.value_ = &value_;
@@ -180,13 +192,17 @@
 
   type get()
   {
-    ca_();
+    handler_.coro_.reset(); // Must not hold shared_ptr to coro while suspended.
+    if (--ready_ != 0)
+      ca_();
     if (!out_ec_ && ec_) throw boost::system::system_error(ec_);
-    return value_;
+    return BOOST_ASIO_MOVE_CAST(type)(value_);
   }
 
 private:
+  detail::coro_handler<Handler, T>& handler_;
   typename basic_yield_context<Handler>::caller_type& ca_;
+  detail::atomic_count ready_;
   boost::system::error_code* out_ec_;
   boost::system::error_code ec_;
   type value_;
@@ -199,20 +215,27 @@
   typedef void type;
 
   explicit async_result(detail::coro_handler<Handler, void>& h)
-    : ca_(h.ca_)
+    : handler_(h),
+      ca_(h.ca_),
+      ready_(2)
   {
+    h.ready_ = &ready_;
     out_ec_ = h.ec_;
     if (!out_ec_) h.ec_ = &ec_;
   }
 
   void get()
   {
-    ca_();
+    handler_.coro_.reset(); // Must not hold shared_ptr to coro while suspended.
+    if (--ready_ != 0)
+      ca_();
     if (!out_ec_ && ec_) throw boost::system::system_error(ec_);
   }
 
 private:
+  detail::coro_handler<Handler, void>& handler_;
   typename basic_yield_context<Handler>::caller_type& ca_;
+  detail::atomic_count ready_;
   boost::system::error_code* out_ec_;
   boost::system::error_code ec_;
 };
@@ -242,7 +265,9 @@
     void operator()(typename basic_yield_context<Handler>::caller_type& ca)
     {
       shared_ptr<spawn_data<Handler, Function> > data(data_);
+#if !defined(BOOST_COROUTINES_UNIDIRECT) && !defined(BOOST_COROUTINES_V2)
       ca(); // Yield until coroutine pointer has been initialised.
+#endif // !defined(BOOST_COROUTINES_UNIDIRECT) && !defined(BOOST_COROUTINES_V2)
       const basic_yield_context<Handler> yield(
           data->coro_, ca, data->handler_);
       (data->function_)(yield);