
On Thu, Sep 18, 2003 at 11:46:03AM +0200, Syver Enstad wrote:
Egor Cheshkov <egor@iplus.ru> writes:
If I understand right, I should use deferToThread to shedule long running task from main thread (that running event loop), i need different thing. I need to shedule a method to be run in the main event loop from another thread. It is the thing that callFromThread does, but callFromThread does not return anything. I need to get result from such call. Is it possible?
Can't you pass yourself and have the method that you pass to callFromThread callback on a method on yourself with the results?
But that won't run the callback in the worker thread. Here's the situation in dodgy ascii art: Main Thread (Twisted reactor, etc) | v | \ |\ | ->----------------------callInThread starts v Worker Thread running | worker_function() | | | v | | | / | /. callFromThread------------------------<- . causes other_func() to . run in Main Thread . | . v . | Worker Thread waits | for other_func result | . | . But how does the . Main Thread pass a result . to Worker Thread and . resume its execution? ? There needs to be a wrapper function around callFromThread that blocks the worker thread on a threading.Event or similar, and then causes the Event to be fired when the function finishes, and returns the result. Or, in untested code: ----- import threading, sys from twisted.internet import reactor def blockingCallFromThread(func): e = threading.Event() l = [] def wrapped_func(): try: l.append(func) except: l.append(sys.exc_info()) l.append(0) else: l.append(1) e.set() reactor.callFromThread(wrapped_func) e.wait() result, ok = l if ok: return result else: # Whee! Cross-thread exceptions! raise result[0], result[1], result[2] ---- This is utterly untested. It probably should be tested and added to twisted.internet.util or t.i.threads, though. -Andrew.