title: Implementing example from coroutines TS 2017
body: <p>In the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4680.pdf" rel="nofollow noreferrer">C++ coroutines TS (2017)</a>, there is an example of an awaitable object.</p>
  
  <pre><code> template &lt;class Rep, class Period&gt;
   auto operator co_await(std::chrono::duration&lt;Rep, Period&gt; d) {
      struct awaiter {
          std::chrono::system_clock::duration duration;
          ...
          awaiter(std::chrono::system_clock::duration d) : duration(d){}
          bool await_ready() const { return duration.count() &lt;= 0; }
          void await_resume() {}
          void await_suspend(std::experimental::coroutine_handle&lt;&gt; h){...}
      };
  
      return awaiter{d};
    }
  
    using namespace std::chrono;
    my_future&lt;int&gt; h();
    my_future&lt;void&gt; g() {
        std::cout &lt;&lt; "just about go to sleep...\n";
        co_await 10ms;
        std::cout &lt;&lt; "resumed\n";
        co_await h();
    }
  </code></pre>
  
  <p>Like a typical StackOverflow Question, it will not compile. After cursing quietly for a while, I decided to turn it into a [MCVE] -- for learning.  The code below compiles and runs on VC++17 with /await enabled. I think it probably does approximately what the TS authors intended. Alas, it employs a detached thread. It is not easy to see how that thread could be harvested via <code>join</code> or <code>future::get</code> or <code>signal_all_at_thread_exit()</code> or ... </p>
  
  <p>For example, join cannot be added to a destructor for <code>awaiter</code>. In the spawned thread, <code>h.resume()</code> causes the awaiter object to be moved into the spawned thread and its (default) constructor called there. So the destructor is called in a different thread than the constructor.</p>
  
  <p><strong>The question</strong>, aside from "Is this what the TS intended?", is <strong>"Can this be improved, in a reasonably economical way, to tend to the dangling thread?"</strong> (And if so how?)</p>
  
  <pre><code>#include &lt;experimental/coroutine&gt;
  #include &lt;future&gt;
  #include &lt;thread&gt;
  
  namespace xtd = std::experimental;
  
  template &lt;class Rep, class Period&gt;
  auto operator co_await(std::chrono::duration&lt;Rep, Period&gt; dur) {
  
      struct awaiter {
          using clock = std::chrono::high_resolution_clock;
          clock::time_point resume_time;
  
          awaiter(clock::duration dur) : resume_time(clock::now()+dur) {}
  
          bool await_ready() { return resume_time &lt;= clock::now(); }
  
          void await_suspend(xtd::coroutine_handle&lt;&gt; h) {
              std::thread([=]() {
                  std::this_thread::sleep_until(resume_time); 
                  h.resume(); // destructs the obj, which has been std::move()'d
              }).detach(); // Detach scares me.
          }
          void await_resume() {}
      };
  
      return awaiter{ dur };
  }
  
  using namespace std::chrono;
  
  std::future&lt;int&gt; g() {
      co_await 4000ms;
      co_return 86;
  }
  
  
  template&lt;typename R&gt;
    bool is_ready(std::future&lt;R&gt; const&amp; f)
    { return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready; }
  
  int main() {
      using std::cout;
      auto gg = g();
      cout &lt;&lt; "Doing stuff in main, while coroutine is suspended...\n";
      std::this_thread::sleep_for(1000ms);
      if (!is_ready(gg)) {
          cout &lt;&lt; "La lala, lala, lala...\n";
          std::this_thread::sleep_for(1500ms);
      }
  
      cout &lt;&lt; "Whew! Done. Getting co_return now...\n";
      auto ret = gg.get();
      cout &lt;&lt; "coroutine resumed and co_returned " &lt;&lt; ret &lt;&lt; '\n';
      system("pause");
      return ret;
  }
  </code></pre>