Advertisement
Guest User

callIOnMainthread Helpers

a guest
May 6th, 2013
652
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.29 KB | None | 0 0
  1. from threading import currentThread
  2. from twisted.internet import reactor, defer
  3. from twisted.python import failure
  4. import Queue
  5.  
  6. def blockingCallOnMainThread(func, *args, **kwargs):
  7.     """
  8.       Modified version of twisted.internet.threads.blockingCallFromThread
  9.       which waits 30s for results and otherwise assumes the system to be shut down.
  10.       This is an ugly workaround for a twisted-internal deadlock.
  11.       Please keep the look intact in case someone comes up with a way
  12.       to reliably detect from the outside if twisted is currently shutting
  13.       down.
  14.     """
  15.     def blockingCallFromThread(f, *a, **kw):
  16.         queue = Queue.Queue()
  17.         def _callFromThread():
  18.             result = defer.maybeDeferred(f, *a, **kw)
  19.             result.addBoth(queue.put)
  20.         reactor.callFromThread(_callFromThread)
  21.  
  22.         result = None
  23.         while True:
  24.             try:
  25.                 result = queue.get(True, 30)
  26.             except Queue.Empty as qe:
  27.                 if True: #not reactor.running: # reactor.running is only False AFTER shutdown, we are during.
  28.                     raise ValueError("Reactor no longer active, aborting.")
  29.             else:
  30.                 break
  31.  
  32.         if isinstance(result, failure.Failure):
  33.             result.raiseException()
  34.         return result
  35.  
  36.     if currentThread().getName() == 'MainThread':
  37.         return func(*args, **kwargs)
  38.     else:
  39.         return blockingCallFromThread(func, *args, **kwargs)
  40.  
  41. def callOnMainThread(func, *args, **kwargs):
  42.     """
  43.       Ensures that a method is being called on the main-thread.
  44.       No return value here!
  45.     """
  46.     if currentThread().getName() == 'MainThread':
  47.         #call on next mainloop interation
  48.         reactor.callLater(0, func, *args, **kwargs)
  49.     else:
  50.         #call on mainthread
  51.         reactor.callFromThread(func, *args, **kwargs)
  52.  
  53.  
  54. def test():
  55.     def mainThreadFunc():
  56.         printWithThread("mainThreadFunc()")
  57.  
  58.     def getString():
  59.         printWithThread("getString()")
  60.         return "getString() retval"
  61.  
  62.     def threadedFunc():
  63.         printWithThread("threadedFunc()")
  64.         callOnMainThread(mainThreadFunc)
  65.         printWithThread( blockingCallOnMainThread(getString) )
  66.         return "threadedFunc() retVal"
  67.  
  68.     def printWithThread(res):
  69.         print "%s :: {%s}" %(res, currentThread().getName())
  70.  
  71.     from twisted.internet import threads
  72.     for i in range(0,3):
  73.         d = threads.deferToThread(threadedFunc)
  74.         d.addCallback(printWithThread)
  75.  
  76. if __name__ == "__main__":
  77.     test()
  78.     reactor.callLater(5, reactor.stop)
  79.     reactor.run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement