Commit 2cbbf4cb authored by Denis Bilenko's avatar Denis Bilenko

select: include all the descriptors that ready in the result, rather than one

use Event instead of switch()
parent a2f21f09
# Copyright (c) 2009-2010 Denis Bilenko. See LICENSE for details. # Copyright (c) 2009-2010 Denis Bilenko. See LICENSE for details.
from gevent import core from gevent import core
from gevent.hub import get_hub, getcurrent
from gevent.timeout import Timeout from gevent.timeout import Timeout
from gevent.event import Event
__all__ = ['error', 'select'] __all__ = ['error', 'select']
...@@ -21,14 +21,21 @@ def get_fileno(obj): ...@@ -21,14 +21,21 @@ def get_fileno(obj):
return fileno_f() return fileno_f()
def _select_callback(ev, evtype): class SelectResult(object):
current, fd = ev.arg
def __init__(self):
self.read = []
self.write = []
self.event = Event()
def update(self, event, evtype):
if evtype & core.EV_READ: if evtype & core.EV_READ:
current.switch(([fd], [], [])) self.read.append(event.arg)
core.timer(0, self.event.set)
elif evtype & core.EV_WRITE: elif evtype & core.EV_WRITE:
current.switch(([], [fd], [])) self.write.append(event.arg)
else: core.timer(0, self.event.set)
current.switch(([], [], [])) # using core.timer(0, ...) to let other active events call update() before Event.wait() returns
def select(rlist, wlist, xlist, timeout=None): def select(rlist, wlist, xlist, timeout=None):
...@@ -36,27 +43,19 @@ def select(rlist, wlist, xlist, timeout=None): ...@@ -36,27 +43,19 @@ def select(rlist, wlist, xlist, timeout=None):
Note: *xlist* is ignored. Note: *xlist* is ignored.
""" """
hub = get_hub()
current = getcurrent()
assert hub is not current, 'do not call blocking functions from the mainloop'
allevents = [] allevents = []
timeout = Timeout.start_new(timeout) timeout = Timeout.start_new(timeout)
result = SelectResult()
try: try:
try: try:
for readfd in rlist: for readfd in rlist:
allevents.append(core.read_event(get_fileno(readfd), _select_callback, arg=(current, readfd))) allevents.append(core.read_event(get_fileno(readfd), result.update, arg=readfd))
for writefd in wlist: for writefd in wlist:
allevents.append(core.write_event(get_fileno(writefd), _select_callback, arg=(current, writefd))) allevents.append(core.write_event(get_fileno(writefd), result.update, arg=writefd))
except IOError, ex: except IOError, ex:
raise error(*ex.args) raise error(*ex.args)
try: result.event.wait(timeout=timeout)
result = hub.switch() return result.read, result.write, []
except Timeout, ex:
if ex is not timeout:
raise
return [], [], []
assert hasattr(result, '__len__') and len(result)==3, "Invalid switch into select: %r" % (result, )
return result
finally: finally:
for evt in allevents: for evt in allevents:
evt.cancel() evt.cancel()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment