title: Threaded timer, interrupting a sleep (stopping it)
body: <p>I'm wanting a reasonably reliable threaded timer, so I've written a timer object that fires a std::function on a thread.  I would like to give this timer the ability to stop before it gets to the next tick; something you can't do with ::sleep (at least I don't think you can).  </p>
  
  <p>So what I've done is put a condition variable on a mutex.  If the condition times out, I fire the event.  If the condition is signalled the thread is exited.  So the Stop method needs to be able to get the thread to stop and/or interrupt its wait, which I think is what it's doing right now.</p>
  
  <p>There are problems with this however.  Sometimes the thread isn't joinable() and sometimes the condition is signalled <em>after</em> its timeout but before it's put into its wait state.</p>
  
  <p>How can I improve this and make it robust?  </p>
  
  <p>The following is a full repo.  The wait is 10 seconds here but the program should terminate immediately as the Foo is created and then immediately destroyed.  It does sometimes but mostly it does not.</p>
  
  <pre><code>#include &lt;atomic&gt;
  #include &lt;thread&gt;
  #include &lt;future&gt;
  #include &lt;sstream&gt;
  #include &lt;chrono&gt;
  #include &lt;iostream&gt;
  
  class Timer
  {
  public:
  
      Timer() {}
  
      ~Timer()
      {           
          Stop();
      }
  
      void Start(std::chrono::milliseconds const &amp; interval, std::function&lt;void(void)&gt; const &amp; callback)
      {   
          Stop();
  
          thread = std::thread([=]()
          {
              for(;;)
              {
                  auto locked = std::unique_lock&lt;std::mutex&gt;(mutex);
                  auto result = terminate.wait_for(locked, interval);
  
                  if (result == std::cv_status::timeout)
                  {
                      callback();
                  }
                  else
                  {
                      return;
                  }
              }
          });
      }
  
      void Stop()
      {       
          terminate.notify_one();
  
          if(thread.joinable())
          {
              thread.join();
          }
      }
  
  private:
  
      std::thread thread;
      std::mutex mutex;
      std::condition_variable terminate;
  };
  
  class Foo
  {
  public: 
  
      Foo()
      {
          timer = std::make_unique&lt;Timer&gt;();
          timer-&gt;Start(std::chrono::milliseconds(10000), std::bind(&amp;Foo::Callback, this));
      }
  
      ~Foo()
      {
  
      }
  
      void Callback()
      {
          static int count = 0;
  
          std::ostringstream o;
  
          std::cout &lt;&lt; count++ &lt;&lt; std::endl;
      }
  
      std::unique_ptr&lt;Timer&gt; timer;
  };
  
  
  int main(void)
  {
      {
          Foo foo;
      }
  
      return 0;
  }
  </code></pre>