title: Block main thread until python background thread finishes side-task
body: <p>I have a threaded python application with a long-running mainloop in the background thread. This background mainloop is actually a call to <a href="http://pyglet.org/doc/api/pyglet.app-module.html" rel="nofollow">pyglet.app.run()</a>, which drives a GUI window and also can be configured to call other code periodically. I need a <code>do_stuff(duration)</code> function to be called at will from the main thread to trigger an animation in the GUI, wait for the animation to stop, and then return. The actual animation must be done in the background thread because the GUI library can't handle being driven by separate threads.</p>
  
  <p>I believe I need to do something like this:</p>
  
  <pre><code>import threading
  
  class StuffDoer(threading.Thread):
      def __init__(self):
          threading.Thread.__init__(self)
          self.max_n_times = 0
          self.total_n_times = 0
          self.paused_ev = threading.Event()
  
      def run(self):
          # this part is outside of my control
          while True:
              self._do_stuff()
              # do other stuff
  
      def _do_stuff(self):
          # this part is under my control
          if self.paused_ev.is_set():
              if self.max_n_times &gt; self.total_n_times:
                  self.paused_ev.clear()
          else:
              if self.total_n_times &gt;= self.max_n_times:
                  self.paused_ev.set()
          if not self.paused_ev.is_set():
              # do stuff that must execute in the background thread
              self.total_n_times += 1
  
  sd = StuffDoer()
  sd.start()
  
  def do_stuff(n_times):
      sd.max_n_times += n_times
      sd.paused_ev.wait_for_clear()   # wait_for_clear() does not exist
      sd.paused_ev.wait()
      assert (sd.total_n_times == sd.max_n_times)
  </code></pre>
  
  <p>EDIT: use <code>max_n_times</code> instead of <code>stop_time</code> to clarify why <code>Thread.join(duration)</code> won't do the trick.</p>
  
  <p>From the documentation for <a href="http://docs.python.org/library/threading.html#event-objects" rel="nofollow">threading.Event</a>:</p>
  
  <blockquote>
    <p>wait([timeout])</p>
    
    <p>Block until the internal flag is true.
    If the internal flag is true on entry,
    return immediately. Otherwise, block
    until another thread calls set() to
    set the flag to true, or until the
    optional timeout occurs.</p>
  </blockquote>
  
  <p>I've found I can get the behavior I'm looking for if I have a pair of events, <code>paused_ev</code> and <code>not_paused_ev</code>, and use <code>not_paused_ev.wait()</code>. I could almost just use <code>Thread.join(duration)</code>, except it needs to only return precisely when the background thread <em>actually</em> registers that the time is up. Is there some other synchronization object or other strategy I should be using instead?</p>
  
  <p>I'd also be open to arguments that I'm approaching this whole thing the wrong way, provided they're good arguments.</p>