title: Execute Twisted reactor.run() in a thread?
body: <p>I'm trying to make a Python library to use the Ubutu One API from Objective-C. Here is my source code:
  <a href="https://github.com/JoseExposito/U1-Finder-Plugin/blob/master/U1FinderLib/U1FinderLib.py" rel="noreferrer">https://github.com/JoseExposito/U1-Finder-Plugin/blob/master/U1FinderLib/U1FinderLib.py</a></p>
  
  <p>I need to make many calls to the API, for this reason I need to have my reactor running once instead of run it and stop it, like in the example of the Ubuntu One documentation:
  <a href="https://one.ubuntu.com/developer/files/store_files/syncdaemontool" rel="noreferrer">https://one.ubuntu.com/developer/files/store_files/syncdaemontool</a></p>
  
  <p>Because it is not possible to run twice the reactor... And I need to execute reactor.run() in a thread because I can not block the application that uses that library!</p>
  
  <p>It is possible to do that? I'm not able to run the reactor in a thread and call the Ubuntu One API synchronous.</p>
  
  <p>EDIT:</p>
  
  <p>I'm using this simple source code to test the idea:</p>
  
  <pre><code>#!/usr/bin/env python
  import objc
  import thread
  import os
  import time
  from   twisted.internet import reactor, defer
  from   ubuntuone.platform.tools import (SyncDaemonTool, is_already_running)
  from   threading import Thread
  NSObject = objc.lookUpClass('NSObject')
  
  ##
  # Variable to get the result of the calls to the Sync Daemon.
  # The result is a JSON string stored in returned_value[0].
  returned_value = ['']
  
  ##
  # Objective-C facade to the methods of the U1FinderLib.
  class U1FinderLib(NSObject):
  
      def init(self):
          self = super(U1FinderLib, self).init()
          self.sync_daemon_tool = SyncDaemonTool(None)
          Thread(target=reactor.run, args=(False,)).start()
          return self
  
      @objc.typedSelector('@@:')
      def volumeList(self):
          print "Begin volumeList"
          reactor.callLater(0, run_command, "volume_list", [], self.sync_daemon_tool)
          print "End volumeList"
          return returned_value[0]
  
  ##
  # Auxiliar functions to call to the sync daemon.
  @defer.inlineCallbacks
  def run_command(action, params, sync_daemon_tool):
      print "run_command"
      running = yield is_already_running()
      print "After is_already_running"
      try:
          if not running:
              returned_value[0] = '{ type:"error" reason:"Sync Daemon is not running" }'
          else:
              print "Before run_action"
              yield run_action(action, params, sync_daemon_tool)
              print "After run_action"
      except Exception, e:
          returned_value[0] = '{ type:"error" reason:"Exception: %s" }' % e
  
  @defer.inlineCallbacks
  def run_action(action, params, sync_daemon_tool):
      if action == "volume_list":
          d = sync_daemon_tool.get_folders()
          returned_value[0] = yield d.addCallback(lambda r: volume_list(r))
  
  # Volume List
  def volume_list(folders):
      volumes_json = '{ type:"volume_list" volumes: { \n\t{ volume:"' + os.path.expanduser('~/Ubuntu One') + '" subscribed:"YES" }'
      for folder in folders:
          volumes_json += ',\n\t{ volume:"' + folder['path'] + '" subscribed:"' + ('YES' if bool(folder['subscribed']) else 'NO') + '" }'
      volumes_json += '\n} }'
      return volumes_json
  
  if __name__ == '__main__':
      py = U1FinderLib.alloc().init()
      print py.volumeList()
      print "EXIT"
  </code></pre>
  
  <p>And this is the output of the program:</p>
  
  <pre><code>Begin volumeList
  End volumeList
  
  EXIT
  </code></pre>
  
  <p>The problem is that the "run_command" function is never called</p>