eventlet/eventlet — pull request #35 by edwardgeorge (2013-06-08 13:13:51+00:00)
Title: Wakeable hubs

Putting this here for discussion as to whether we'd want to include something like this, and whether this is the right solution. This contains a simple change that allows a hub to be woken up during its "wait" phase from another thread so that another thread can insert events into that hub. Sample usage:

# from second thread with reference to another thread's hub
# event is an event that was defined and being waited on in that first thread
hub.schedule_call_global(0, event.send, obj)
hub.wake()

similarly:

# gt is a greenthread that was created in other thread and therefore switch needs to
# be scheduled in other thread's hub,
hub.schedule_call_global(0, gt.switch)
hub.wake()

I've been using a similar pattern where i've needed to communicate cross-threads.

def wrap(func):
hub = hubs.get_hub()
@functools.wraps(func)
def wrapped(*a, **k):
hub.schedule_call_global(0, func, *a, **k)
hub.wake()
return wrapped

threading.Thread(target=somefunc, kwargs={'queue_put': wrap(q.put), })