[Twisted-Python] callFromThread with return

Andrew Bennetts andrew-twisted at puzzling.org
Thu Sep 18 06:29:04 EDT 2003


On Thu, Sep 18, 2003 at 11:46:03AM +0200, Syver Enstad wrote:
> Egor Cheshkov <egor at 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.





More information about the Twisted-Python mailing list