1 __select = __import__('select')
3 from eventlet.greenthread import getcurrent
4 from eventlet.hubs import get_hub
5 from eventlet.support import six
8 __patched__ = ['select']
12 # The purpose of this function is to exactly replicate
13 # the behavior of the select module when confronted with
14 # abnormal filenos; the details are extensively tested in
15 # the stdlib test/test_select.py.
18 except AttributeError:
19 if not isinstance(obj, six.integer_types):
20 raise TypeError("Expected int or long, got " + type(obj))
24 if not isinstance(rv, six.integer_types):
25 raise TypeError("Expected int or long, got " + type(rv))
29 def select(read_list, write_list, error_list, timeout=None):
30 # error checking like this is required by the stdlib unit tests
31 if timeout is not None:
33 timeout = float(timeout)
35 raise TypeError("Expected number for timeout")
38 current = getcurrent()
39 assert hub.greenlet is not current, 'do not call blocking functions from the mainloop'
42 ds[get_fileno(r)] = {'read': r}
44 ds.setdefault(get_fileno(w), {})['write'] = w
46 ds.setdefault(get_fileno(e), {})['error'] = e
51 original = ds[get_fileno(d)]['read']
52 current.switch(([original], [], []))
55 original = ds[get_fileno(d)]['write']
56 current.switch(([], [original], []))
58 def on_error(d, _err=None):
59 original = ds[get_fileno(d)]['error']
60 current.switch(([], [], [original]))
63 current.switch(([], [], []))
66 # ensure that BaseHub.run() has a chance to call self.wait()
67 # at least once before timed out. otherwise the following code
68 # can time out erroneously.
70 # s1, s2 = socket.socketpair()
71 # print(select.select([], [s1], [], 0))
72 timers.append(hub.schedule_call_global(0, on_timeout2))
74 if timeout is not None:
75 timers.append(hub.schedule_call_global(timeout, on_timeout))
77 for k, v in six.iteritems(ds):
79 listeners.append(hub.add(hub.READ, k, on_read, on_error, lambda x: None))
81 listeners.append(hub.add(hub.WRITE, k, on_write, on_error, lambda x: None))