Commit 7489d361 authored by Denis Bilenko's avatar Denis Bilenko

select: in case an event creation fails, cancel all the allocated events so far

- signal error via select.error exception that is imported from stdlib's select
parent 5a33c943
......@@ -4,7 +4,11 @@ from gevent import core
from gevent.hub import get_hub, getcurrent
from gevent.timeout import Timeout
__all__ = ['select']
__all__ = ['error', 'select']
__select__ = __import__('select')
error = __select__.error
def get_fileno(obj):
try:
......@@ -17,6 +21,16 @@ def get_fileno(obj):
return fileno_f()
def _select_callback(ev, evtype):
current, fd = ev.arg
if evtype & core.EV_READ:
current.switch(([fd], [], []))
elif evtype & core.EV_WRITE:
current.switch(([], [fd], []))
else:
current.switch(([], [], []))
def select(rlist, wlist, xlist, timeout=None):
"""An implementation of :meth:`select.select` that blocks only the current greenlet.
......@@ -26,22 +40,15 @@ def select(rlist, wlist, xlist, timeout=None):
current = getcurrent()
assert hub is not current, 'do not call blocking functions from the mainloop'
allevents = []
def callback(ev, evtype):
if evtype & core.EV_READ:
current.switch(([ev.arg], [], []))
elif evtype & core.EV_WRITE:
current.switch(([], [ev.arg], []))
else:
current.switch(([], [], []))
for readfd in rlist:
allevents.append(core.read_event(get_fileno(readfd), callback, arg=readfd))
for writefd in wlist:
allevents.append(core.write_event(get_fileno(writefd), callback, arg=writefd))
timeout = Timeout.start_new(timeout)
try:
try:
for readfd in rlist:
allevents.append(core.read_event(get_fileno(readfd), _select_callback, arg=(current, readfd)))
for writefd in wlist:
allevents.append(core.write_event(get_fileno(writefd), _select_callback, arg=(current, writefd)))
except IOError, ex:
raise error(*ex.args)
try:
result = hub.switch()
except Timeout, ex:
......
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