title: Multi-threaded asyncio in Python
body: <p>I'm currently doing my first steps with asyncio in Python 3.5 and there is one problem that's bugging me. Obviously I haven't fully understood coroutines...</p>
  
  <p>Here is a simplified version of what I'm doing.</p>
  
  <p>In my class I have an open() method that creates a new thread. Within that thread I create a new event loop and a socket connection to some host. Then I let the loop run forever.</p>
  
  
  
  <pre class="lang-py prettyprint-override"><code>def open(self):
      # create thread
      self.thread = threading.Thread(target=self._thread)
      self.thread.start()
      # wait for connection
      while self.protocol is None:
          time.sleep(0.1)
  
  def _thread(self):
      # create loop, connection and run forever
      self.loop = asyncio.new_event_loop()
      coro = self.loop.create_connection(lambda: MyProtocol(self.loop),
                                         'somehost.com', 1234)
      self.loop.run_until_complete(coro)
      self.loop.run_forever()
  </code></pre>
  
  <p>Stopping the connection is now quite simple, I just stop the loop from the main thread:</p>
  
  <pre class="lang-py prettyprint-override"><code>loop.call_soon_threadsafe(loop.stop)
  </code></pre>
  
  <p>Unfortunately I need to do some cleanup, especially I need to empty a queue before disconnecting from the server. So I tried something like this stop() method in MyProtocol:</p>
  
  <pre class="lang-py prettyprint-override"><code>class MyProtocol(asyncio.Protocol):
      def __init__(self, loop):
          self._loop = loop
          self._queue = []
  
      async def stop(self):
          # wait for all queues to empty
          while self._queue:
              await asyncio.sleep(0.1)
          # disconnect
          self.close()
          self._loop.stop()
  </code></pre>
  
  <p>The queue gets emptied from within the protocol's data_received() method, so I just want to wait for that to happen using the while loop with the asyncio.sleep() call. Afterwards I close the connection and stop the loop.</p>
  
  <p>But how do I call this method from the main thread and wait for it?
  I tried the following, but none of them seem to work (protocol is the currently used instance of MyProtocol):</p>
  
  <pre class="lang-py prettyprint-override"><code>loop.call_soon_threadsafe(protocol.stop)
  loop.call_soon_threadsafe(functools.partial(asyncio.ensure_future, protocol.stop(), loop=loop))
  asyncio.ensure_future(protocol.stop(), loop=loop)
  </code></pre>
  
  <p>Can anyone please help me here? Thanks!</p>