Add async_result support to go().
diff --git a/asio/include/asio/detail/variadic_templates.hpp b/asio/include/asio/detail/variadic_templates.hpp
index a8ac797..2c1f533 100644
--- a/asio/include/asio/detail/variadic_templates.hpp
+++ b/asio/include/asio/detail/variadic_templates.hpp
@@ -48,6 +48,20 @@
 # define ASIO_VARIADIC_PARAMS_4 T1 x1, T2 x2, T3 x3, T4 x4
 # define ASIO_VARIADIC_PARAMS_5 T1 x1, T2 x2, T3 x3, T4 x4, T5 x5
 
+# define ASIO_VARIADIC_CONSTREF_PARAMS(n) \
+  ASIO_VARIADIC_CONSTREF_PARAMS_##n
+
+# define ASIO_VARIADIC_CONSTREF_PARAMS_1 \
+  const T1& x1
+# define ASIO_VARIADIC_CONSTREF_PARAMS_2 \
+  const T1& x1, const T2& x2
+# define ASIO_VARIADIC_CONSTREF_PARAMS_3 \
+  const T1& x1, const T2& x2, const T3& x3
+# define ASIO_VARIADIC_CONSTREF_PARAMS_4 \
+  const T1& x1, const T2& x2, const T3& x3, const T4& x4
+# define ASIO_VARIADIC_CONSTREF_PARAMS_5 \
+  const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5
+
 # define ASIO_VARIADIC_ARGS(n) ASIO_VARIADIC_ARGS_##n
 
 # define ASIO_VARIADIC_ARGS_1 x1
diff --git a/asio/include/asio/go.hpp b/asio/include/asio/go.hpp
index ce4a2f7..1346964 100644
--- a/asio/include/asio/go.hpp
+++ b/asio/include/asio/go.hpp
@@ -17,16 +17,33 @@
 
 #include "asio/detail/config.hpp"
 #include "asio/coroutine.hpp"
+#include "asio/detail/variadic_templates.hpp"
 #include "asio/detail/wrapped_handler.hpp"
 #include "asio/io_service.hpp"
 #include "asio/strand.hpp"
 
+#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)
+
+# include "asio/detail/variadic_templates.hpp"
+
+// A macro that should expand to:
+//   template <typename T1, ..., typename Tn>
+//   void complete(const T1& x1, ..., const Tn& xn);
+// This macro should only persist within this file.
+
+# define ASIO_PRIVATE_COMPLETE_DECL(n) \
+  template <ASIO_VARIADIC_TPARAMS(n)> \
+  void complete(ASIO_VARIADIC_CONSTREF_PARAMS(n)); \
+  /**/
+
+#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)
+
 #include "asio/detail/push_options.hpp"
 
 namespace asio {
 namespace detail {
   
-template <typename Handler> class stackless_impl_base;
+template <typename Handler, typename Signature> class stackless_impl_base;
 
 } // namespace detail
 
@@ -47,11 +64,11 @@
  *   }
  * } @endcode
  *
- * The initiating function (async_read_some in the above example) suspends the
- * current coroutine. The coroutine is resumed when the asynchronous operation
- * completes.
+ * The initiating function (@c async_read_some in the above example) suspends
+ * the current coroutine. The coroutine is resumed when the asynchronous
+ * operation completes.
  */
-template <typename Handler>
+template <typename Handler, typename Signature = void ()>
 class basic_stackless_context
 {
 public:
@@ -84,10 +101,31 @@
     return tmp;
   }
 
+  /// Invoke the completion handler with the specified arguments.
+  /**
+   * This function is used to invoke the coroutine's associated completion
+   * handler. It should be called at most once, immediately prior to the
+   * termination of the coroutine. Additional calls will be ignored.
+   *
+   * For completion handlers with the signature <tt>void()</tt>, and if @c
+   * complete() is not explicitly called, the completion handler will be
+   * automatically invoked after coroutine termination.
+   */
+#if defined(GENERATING_DOCUMENTATION) \
+  || defined(ASIO_HAS_VARIADIC_TEMPLATES)
+  template <typename... T>
+  void complete(T&&... args);
+#else // defined(GENERATING_DOCUMENTATION)
+      //   || defined(ASIO_HAS_VARIADIC_TEMPLATES)
+  void complete();
+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_COMPLETE_DECL)
+#endif // defined(GENERATING_DOCUMENTATION)
+       //   || defined(ASIO_HAS_VARIADIC_TEMPLATES)
+
 #if defined(GENERATING_DOCUMENTATION)
 private:
 #endif // defined(GENERATING_DOCUMENTATION)
-  detail::stackless_impl_base<Handler>** impl_;
+  detail::stackless_impl_base<Handler, Signature>** impl_;
   asio::error_code* ec_;
 };
 
@@ -97,7 +135,7 @@
 #else // defined(GENERATING_DOCUMENTATION)
 typedef basic_stackless_context<
   detail::wrapped_handler<
-    io_service::strand, void(*)(),
+    io_service::strand, void (*)(),
     detail::is_continuation_if_running> > stackless_context;
 #endif // defined(GENERATING_DOCUMENTATION)
 
@@ -143,21 +181,40 @@
  */
 /*@{*/
 
-/// Start a new stackless coroutine, calling the specified handler when it
-/// completes.
+/// Start a new stackless coroutine with an associated completion handler.
 /**
  * This function is used to launch a new coroutine.
  *
- * @param handler A handler to be called when the coroutine exits. More
+ * @param handler The handler associated with the coroutine. The handler may be
+ * explicitly called via the context's @c complete() function, but will be
+ * invoked automatically after coroutine termination if not called first. More
  * importantly, the handler provides an execution context (via the the handler
  * invocation hook) for the coroutine. The handler must have the signature:
  * @code void handler(); @endcode
  *
  * @param function The coroutine function. The function must have the signature:
- * @code void function(basic_stackless_context<Handler> yield); @endcode
+ * @code void function(basic_stackless_context<Handler> c); @endcode
  */
 template <typename Handler, typename Function>
-void go(ASIO_MOVE_ARG(Handler) handler,
+ASIO_INITFN_RESULT_TYPE(Handler, void ())
+go(ASIO_MOVE_ARG(Handler) handler,
+    ASIO_MOVE_ARG(Function) function);
+
+/// Start a new stackless coroutine with an associated completion handler.
+/**
+ * This function is used to launch a new coroutine.
+ *
+ * @param handler The handler associated with the coroutine. The handler may be
+ * explicitly called via the context's @c complete() function. Furthermore, the
+ * handler provides an execution context (via the the handler invocation hook)
+ * for the coroutine.
+ *
+ * @param function The coroutine function. The function must have the signature:
+ * @code void function(basic_stackless_context<Handler, Signature> c); @endcode
+ */
+template <typename Signature, typename Handler, typename Function>
+ASIO_INITFN_RESULT_TYPE(Handler, Signature)
+go(ASIO_MOVE_ARG(Handler) handler,
     ASIO_MOVE_ARG(Function) function);
 
 /// Start a new stackless coroutine, inheriting the execution context of another.
@@ -212,6 +269,10 @@
 
 #include "asio/detail/pop_options.hpp"
 
+#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)
+# undef ASIO_PRIVATE_COMPLETE_DECL
+#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)
+
 #include "asio/impl/go.hpp"
 
 #endif // ASIO_GO_HPP
diff --git a/asio/include/asio/impl/go.hpp b/asio/include/asio/impl/go.hpp
index 45ac9b9..824922e 100644
--- a/asio/include/asio/impl/go.hpp
+++ b/asio/include/asio/impl/go.hpp
@@ -29,20 +29,21 @@
 namespace asio {
 namespace detail {
 
-  template <typename Handler>
+  template <typename Handler, typename Signature>
   class stackless_impl_base
   {
   protected:
     template <typename Handler1>
     explicit stackless_impl_base(ASIO_MOVE_ARG(Handler1) handler,
-        void (*resume_fn)(const basic_stackless_context<Handler>&),
+        void (*resume_fn)(const basic_stackless_context<Handler, Signature>&),
         void (*destroy_fn)(stackless_impl_base*))
       : handler_(ASIO_MOVE_CAST(Handler1)(handler)),
         ref_count_(1),
         result_ec_(&throw_ec_),
         result_value_(0),
         resume_(resume_fn),
-        destroy_(destroy_fn)
+        destroy_(destroy_fn),
+        completed_(false)
     {
     }
 
@@ -53,37 +54,40 @@
     static void resume(stackless_impl_base*& impl);
 
   //private:
-    Handler handler_;
+    typename handler_type<Handler, Signature>::type handler_;
     asio::detail::atomic_count ref_count_;
     asio::coroutine coroutine_;
     asio::error_code throw_ec_;
     asio::error_code* result_ec_;
     void* result_value_;
-    void (*resume_)(const basic_stackless_context<Handler>&);
+    void (*resume_)(const basic_stackless_context<Handler, Signature>&);
     void (*destroy_)(stackless_impl_base*);
+    bool completed_;
   };
 
-  template <typename Handler>
-  stackless_impl_base<Handler>* stackless_impl_base<Handler>::add_ref(
-      stackless_impl_base<Handler>* impl)
+  template <typename Handler, typename Signature>
+  stackless_impl_base<Handler, Signature>*
+  stackless_impl_base<Handler, Signature>::add_ref(
+      stackless_impl_base<Handler, Signature>* impl)
   {
     if (impl)
       ++impl->ref_count_;
     return impl;
   }
 
-  template <typename Handler>
-  inline stackless_impl_base<Handler>* stackless_impl_base<Handler>::move_ref(
-      stackless_impl_base<Handler>*& impl)
+  template <typename Handler, typename Signature>
+  inline stackless_impl_base<Handler, Signature>*
+  stackless_impl_base<Handler, Signature>::move_ref(
+      stackless_impl_base<Handler, Signature>*& impl)
   {
     stackless_impl_base* tmp = impl;
     impl = 0;
     return tmp;
   }
 
-  template <typename Handler>
-  void stackless_impl_base<Handler>::release_ref(
-      stackless_impl_base<Handler>* impl)
+  template <typename Handler, typename Signature>
+  void stackless_impl_base<Handler, Signature>::release_ref(
+      stackless_impl_base<Handler, Signature>* impl)
   {
     if (impl)
     {
@@ -92,26 +96,45 @@
     }
   }
 
-  template <typename Handler>
-  void stackless_impl_base<Handler>::resume(
-      stackless_impl_base<Handler>*& impl)
+  template <typename Signature>
+  struct call_completed_handler
+  {
+    template <typename Handler>
+    static void call(Handler&) {}
+  };
+
+  template <>
+  struct call_completed_handler<void ()>
+  {
+    template <typename Handler>
+    static void call(Handler& h) { h(); }
+  };
+
+  template <typename Handler, typename Signature>
+  void stackless_impl_base<Handler, Signature>::resume(
+      stackless_impl_base<Handler, Signature>*& impl)
   {
     impl->result_value_ = 0;
-    const basic_stackless_context<Handler> ctx = { &impl, &impl->throw_ec_ };
+    basic_stackless_context<Handler, Signature> ctx
+      = { &impl, &impl->throw_ec_ };
     impl->resume_(ctx);
-    if (impl && impl->coroutine_.is_complete())
-      impl->handler_();
+
+    if (impl && impl->coroutine_.is_complete() && !impl->completed_)
+    {
+      impl->completed_ = true;
+      call_completed_handler<Signature>::call(impl->handler_);
+    }
   }
 
-  template <typename Handler, typename Function>
+  template <typename Handler, typename Signature, typename Function>
   class stackless_impl :
-    public stackless_impl_base<Handler>
+    public stackless_impl_base<Handler, Signature>
   {
   public:
     template <typename Handler1, typename Function1>
     stackless_impl(ASIO_MOVE_ARG(Handler1) handler,
         ASIO_MOVE_ARG(Function1) function)
-      : stackless_impl_base<Handler>(
+      : stackless_impl_base<Handler, Signature>(
           ASIO_MOVE_CAST(Handler1)(handler),
           &stackless_impl::do_resume,
           &stackless_impl::do_destroy),
@@ -120,13 +143,14 @@
     }
 
   private:
-    static void do_resume(const basic_stackless_context<Handler>& ctx)
+    static void do_resume(
+        const basic_stackless_context<Handler, Signature>& ctx)
     {
-      stackless_impl_base<Handler>* base = *ctx.impl_;
+      stackless_impl_base<Handler, Signature>* base = *ctx.impl_;
       static_cast<stackless_impl*>(base)->function_(ctx);
     }
 
-    static void do_destroy(stackless_impl_base<Handler>* impl)
+    static void do_destroy(stackless_impl_base<Handler, Signature>* impl)
     {
       delete static_cast<stackless_impl*>(impl);
     }
@@ -134,31 +158,31 @@
     Function function_;
   };
 
-  template <typename Handler, typename T>
+  template <typename Handler, typename Signature, typename T>
   class stackless_handler
   {
   public:
-    stackless_handler(const basic_stackless_context<Handler>& ctx)
-      : impl_(stackless_impl_base<Handler>::move_ref(*ctx.impl_))
+    stackless_handler(const basic_stackless_context<Handler, Signature>& ctx)
+      : impl_(stackless_impl_base<Handler, Signature>::move_ref(*ctx.impl_))
     {
       impl_->result_ec_ = ctx.ec_;
     }
 
     stackless_handler(const stackless_handler& other)
-      : impl_(stackless_impl_base<Handler>::add_ref(other.impl_))
+      : impl_(stackless_impl_base<Handler, Signature>::add_ref(other.impl_))
     {
     }
 
 #if defined(ASIO_HAS_MOVE)
     stackless_handler(stackless_handler&& other)
-      : impl_(stackless_impl_base<Handler>::move_ref(other.impl_))
+      : impl_(stackless_impl_base<Handler, Signature>::move_ref(other.impl_))
     {
     }
 #endif // defined(ASIO_HAS_MOVE)
 
     ~stackless_handler()
     {
-      stackless_impl_base<Handler>::release_ref(impl_);
+      stackless_impl_base<Handler, Signature>::release_ref(impl_);
     }
 
     void operator()(T value)
@@ -166,7 +190,7 @@
       *impl_->result_ec_ = asio::error_code();
       if (impl_->result_value_)
         *static_cast<T*>(impl_->result_value_) = value;
-      stackless_impl_base<Handler>::resume(impl_);
+      stackless_impl_base<Handler, Signature>::resume(impl_);
     }
 
     void operator()(asio::error_code ec, T value)
@@ -174,130 +198,139 @@
       *impl_->result_ec_ = ec;
       if (impl_->result_value_)
         *static_cast<T*>(impl_->result_value_) = value;
-      stackless_impl_base<Handler>::resume(impl_);
+      stackless_impl_base<Handler, Signature>::resume(impl_);
     }
 
   //private:
-    stackless_impl_base<Handler>* impl_;
+    stackless_impl_base<Handler, Signature>* impl_;
+
+  private:
+    stackless_handler& operator=(const stackless_handler&);
   };
 
-  template <typename Handler>
-  class stackless_handler<Handler, void>
+  template <typename Handler, typename Signature>
+  class stackless_handler<Handler, Signature, void>
   {
   public:
-    stackless_handler(const basic_stackless_context<Handler>& ctx)
-      : impl_(stackless_impl_base<Handler>::move_ref(*ctx.impl_))
+    stackless_handler(const basic_stackless_context<Handler, Signature>& ctx)
+      : impl_(stackless_impl_base<Handler, Signature>::move_ref(*ctx.impl_))
     {
       impl_->result_ec_ = ctx.ec_;
     }
 
     stackless_handler(const stackless_handler& other)
-      : impl_(stackless_impl_base<Handler>::add_ref(other.impl_))
+      : impl_(stackless_impl_base<Handler, Signature>::add_ref(other.impl_))
     {
     }
 
 #if defined(ASIO_HAS_MOVE)
     stackless_handler(stackless_handler&& other)
-      : impl_(stackless_impl_base<Handler>::move_ref(other.impl_))
+      : impl_(stackless_impl_base<Handler, Signature>::move_ref(other.impl_))
     {
     }
 #endif // defined(ASIO_HAS_MOVE)
 
     ~stackless_handler()
     {
-      stackless_impl_base<Handler>::release_ref(impl_);
+      stackless_impl_base<Handler, Signature>::release_ref(impl_);
     }
 
     void operator()()
     {
       *impl_->result_ec_ = asio::error_code();
-      stackless_impl_base<Handler>::resume(impl_);
+      stackless_impl_base<Handler, Signature>::resume(impl_);
     }
 
     void operator()(asio::error_code ec)
     {
       *impl_->result_ec_ = ec;
-      stackless_impl_base<Handler>::resume(impl_);
+      stackless_impl_base<Handler, Signature>::resume(impl_);
     }
 
   //private:
-    stackless_impl_base<Handler>* impl_;
+    stackless_impl_base<Handler, Signature>* impl_;
+
+  private:
+    stackless_handler& operator=(const stackless_handler&);
   };
 
-  template <typename Handler, typename T>
+  template <typename Handler, typename Signature, typename T>
   inline void* asio_handler_allocate(std::size_t size,
-      stackless_handler<Handler, T>* this_handler)
+      stackless_handler<Handler, Signature, T>* this_handler)
   {
     return asio_handler_alloc_helpers::allocate(
         size, this_handler->impl_->handler_);
   }
 
-  template <typename Handler, typename T>
+  template <typename Handler, typename Signature, typename T>
   inline void asio_handler_deallocate(void* pointer, std::size_t size,
-      stackless_handler<Handler, T>* this_handler)
+      stackless_handler<Handler, Signature, T>* this_handler)
   {
     asio_handler_alloc_helpers::deallocate(
         pointer, size, this_handler->impl_->handler_);
   }
 
-  template <typename Handler, typename T>
+  template <typename Handler, typename Signature, typename T>
   inline bool asio_handler_is_continuation(
-      stackless_handler<Handler, T>*)
+      stackless_handler<Handler, Signature, T>*)
   {
     return true;
   }
 
-  template <typename Function, typename Handler, typename T>
+  template <typename Function, typename Handler, typename Signature, typename T>
   inline void asio_handler_invoke(Function& function,
-      stackless_handler<Handler, T>* this_handler)
+      stackless_handler<Handler, Signature, T>* this_handler)
   {
     asio_handler_invoke_helpers::invoke(
         function, this_handler->impl_->handler_);
   }
 
-  template <typename Function, typename Handler, typename T>
+  template <typename Function, typename Handler, typename Signature, typename T>
   inline void asio_handler_invoke(const Function& function,
-      stackless_handler<Handler, T>* this_handler)
+      stackless_handler<Handler, Signature, T>* this_handler)
   {
     asio_handler_invoke_helpers::invoke(
         function, this_handler->impl_->handler_);
   }
 
-  template <typename Handler, typename Function>
+  template <typename Handler, typename Signature, typename Function>
   struct go_helper
   {
     template <typename Handler1, typename Function1>
     go_helper(ASIO_MOVE_ARG(Handler1) handler,
         ASIO_MOVE_ARG(Function1) function)
-      : impl_(new stackless_impl<Handler, Function>(
+      : impl_(new stackless_impl<Handler, Signature, Function>(
             ASIO_MOVE_CAST(Handler1)(handler),
             ASIO_MOVE_CAST(Function1)(function)))
     {
     }
 
     go_helper(const go_helper& other)
-      : impl_(stackless_impl_base<Handler>::add_ref(other.impl_))
+      : impl_(stackless_impl_base<Handler, Signature>::add_ref(other.impl_))
     {
     }
 
 #if defined(ASIO_HAS_MOVE)
     go_helper(go_helper&& other)
-      : impl_(stackless_impl_base<Handler>::move_ref(other.impl_))
+      : impl_(stackless_impl_base<Handler, Signature>::move_ref(other.impl_))
     {
     }
 #endif // defined(ASIO_HAS_MOVE)
 
     ~go_helper()
     {
-      stackless_impl_base<Handler>::release_ref(impl_);
+      stackless_impl_base<Handler, Signature>::release_ref(impl_);
     }
 
     void operator()()
     {
-      stackless_impl_base<Handler>::resume(impl_);
+      stackless_impl_base<Handler, Signature>::resume(impl_);
     }
 
-    stackless_impl_base<Handler>* impl_;
+    stackless_impl_base<Handler, Signature>* impl_;
+
+  private:
+    go_helper& operator=(const go_helper&);
   };
 
   inline void default_go_handler() {}
@@ -306,39 +339,42 @@
 
 #if !defined(GENERATING_DOCUMENTATION)
 
-template <typename Handler, typename ReturnType>
-struct handler_type<basic_stackless_context<Handler>, ReturnType()>
+template <typename Handler, typename Signature, typename ReturnType>
+struct handler_type<basic_stackless_context<Handler, Signature>, ReturnType()>
 {
-  typedef detail::stackless_handler<Handler, void> type;
+  typedef detail::stackless_handler<Handler, Signature, void> type;
 };
 
-template <typename Handler, typename ReturnType, typename Arg1>
-struct handler_type<basic_stackless_context<Handler>, ReturnType(Arg1)>
+template <typename Handler, typename Signature,
+    typename ReturnType, typename Arg1>
+struct handler_type<basic_stackless_context<Handler, Signature>,
+    ReturnType(Arg1)>
 {
-  typedef detail::stackless_handler<Handler, Arg1> type;
+  typedef detail::stackless_handler<Handler, Signature, Arg1> type;
 };
 
-template <typename Handler, typename ReturnType>
-struct handler_type<basic_stackless_context<Handler>,
+template <typename Handler, typename Signature, typename ReturnType>
+struct handler_type<basic_stackless_context<Handler, Signature>,
     ReturnType(asio::error_code)>
 {
-  typedef detail::stackless_handler<Handler, void> type;
+  typedef detail::stackless_handler<Handler, Signature, void> type;
 };
 
-template <typename Handler, typename ReturnType, typename Arg2>
-struct handler_type<basic_stackless_context<Handler>,
+template <typename Handler, typename Signature,
+    typename ReturnType, typename Arg2>
+struct handler_type<basic_stackless_context<Handler, Signature>,
     ReturnType(asio::error_code, Arg2)>
 {
-  typedef detail::stackless_handler<Handler, Arg2> type;
+  typedef detail::stackless_handler<Handler, Signature, Arg2> type;
 };
 
-template <typename Handler, typename T>
-class async_result<detail::stackless_handler<Handler, T> >
+template <typename Handler, typename Signature, typename T>
+class async_result<detail::stackless_handler<Handler, Signature, T> >
 {
 public:
   typedef awaitable<T> type;
 
-  explicit async_result(detail::stackless_handler<Handler, T>&)
+  explicit async_result(detail::stackless_handler<Handler, Signature, T>&)
   {
   }
 
@@ -348,65 +384,161 @@
   }
 };
 
-template <typename Handler>
+template <typename Handler, typename Signature>
 inline coroutine& get_coroutine(
-    basic_stackless_context<Handler>& c)
+    basic_stackless_context<Handler, Signature>& c)
 {
   return (*c.impl_)->coroutine_;
 }
 
-template <typename Handler>
+template <typename Handler, typename Signature>
 inline coroutine& get_coroutine(
-    basic_stackless_context<Handler>* c)
+    basic_stackless_context<Handler, Signature>* c)
 {
   return (*c->impl_)->coroutine_;
 }
 
-template <typename Handler>
+template <typename Handler, typename Signature>
 inline const asio::error_code* get_coroutine_error(
-    basic_stackless_context<Handler>& c)
+    basic_stackless_context<Handler, Signature>& c)
 {
   return &(*c.impl_)->throw_ec_;
 }
 
-template <typename Handler>
+template <typename Handler, typename Signature>
 inline const asio::error_code* get_coroutine_error(
-    basic_stackless_context<Handler>* c)
+    basic_stackless_context<Handler, Signature>* c)
 {
   return &(*c->impl_)->throw_ec_;
 }
 
-template <typename Handler>
+template <typename Handler, typename Signature>
 inline void** get_coroutine_async_result(
-    basic_stackless_context<Handler>& c)
+    basic_stackless_context<Handler, Signature>& c)
 {
   return &(*c.impl_)->result_value_;
 }
 
-template <typename Handler>
+template <typename Handler, typename Signature>
 inline void** get_coroutine_async_result(
-    basic_stackless_context<Handler>* c)
+    basic_stackless_context<Handler, Signature>* c)
 {
   return &(*c->impl_)->result_value_;
 }
 
+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)
+
+template <typename Handler, typename Signature>
+template <typename... T>
+void basic_stackless_context<Handler, Signature>::complete(T&&... args)
+{
+  if (!(*impl_)->completed_)
+  {
+    (*impl_)->completed_ = true;
+    (*impl_)->handler_(static_cast<T&&>(args)...);
+  }
+}
+
+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
+
+template <typename Handler, typename Signature>
+void basic_stackless_context<Handler, Signature>::complete()
+{
+  if (!(*impl_)->completed_)
+  {
+    (*impl_)->completed_ = true;
+    (*impl_)->handler_();
+  }
+}
+
+// A macro that should expand to:
+//   template <typename Handler, typename Signature>
+//   template <typename T1, ..., typename Tn>
+//   void basic_stackless_context<Handler, Signature>::complete(
+//       const T1& x1, ..., const Tn& xn)
+//   {
+//     if (!(*impl_)->completed_)
+//     {
+//       (*impl_)->completed_ = true;
+//       (*impl_)->handler_(x1, ..., xn);
+//     }
+//   }
+// This macro should only persist within this file.
+
+# define ASIO_PRIVATE_COMPLETE_DEF(n) \
+  template <typename Handler, typename Signature> \
+  template <ASIO_VARIADIC_TPARAMS(n)> \
+  void basic_stackless_context<Handler, Signature>::complete( \
+      ASIO_VARIADIC_CONSTREF_PARAMS(n)) \
+  { \
+    if (!(*impl_)->completed_) \
+    { \
+      (*impl_)->completed_ = true; \
+      (*impl_)->handler_(ASIO_VARIADIC_ARGS(n)); \
+    } \
+  } \
+  /**/
+
+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_COMPLETE_DEF)
+
+# undef ASIO_PRIVATE_COMPLETE_DEF
+
+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
+
 template <typename Handler, typename Function>
-void go(ASIO_MOVE_ARG(Handler) handler,
+ASIO_INITFN_RESULT_TYPE(Handler, void ())
+go(ASIO_MOVE_ARG(Handler) handler,
     ASIO_MOVE_ARG(Function) function)
 {
-  typedef typename handler_type<Handler, void()>::type
-      real_handler_type;
+  typedef typename remove_const<
+    typename remove_reference<Handler>::type>::type
+      passed_handler_type;
+
+  typedef typename handler_type<
+    Handler, void ()>::type real_handler_type;
 
   typedef typename remove_const<
     typename remove_reference<Function>::type>::type
       function_type;
 
-  detail::go_helper<real_handler_type, function_type> helper(
+  detail::go_helper<passed_handler_type, void (), function_type> helper(
       ASIO_MOVE_CAST(Handler)(handler),
       ASIO_MOVE_CAST(Function)(function));
 
+  async_result<real_handler_type> result(helper.impl_->handler_);
+
   asio_handler_invoke_helpers::invoke(
       helper, helper.impl_->handler_);
+
+  return result.get();
+}
+
+template <typename Signature, typename Handler, typename Function>
+ASIO_INITFN_RESULT_TYPE(Handler, Signature)
+go(ASIO_MOVE_ARG(Handler) handler,
+    ASIO_MOVE_ARG(Function) function)
+{
+  typedef typename remove_const<
+    typename remove_reference<Handler>::type>::type
+      passed_handler_type;
+
+  typedef typename handler_type<
+    Handler, Signature>::type real_handler_type;
+
+  typedef typename remove_const<
+    typename remove_reference<Function>::type>::type
+      function_type;
+
+  detail::go_helper<passed_handler_type, Signature, function_type> helper(
+      ASIO_MOVE_CAST(Handler)(handler),
+      ASIO_MOVE_CAST(Function)(function));
+
+  async_result<real_handler_type> result(helper.impl_->handler_);
+
+  asio_handler_invoke_helpers::invoke(
+      helper, helper.impl_->handler_);
+
+  return result.get();
 }
 
 template <typename Handler, typename Function>