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']
9 # FIXME: must also delete `poll`, but it breaks subprocess `communicate()`
10 # https://github.com/eventlet/eventlet/issues/290
11 __deleted__ = ['devpoll', 'epoll', 'kqueue', 'kevent']
15 # The purpose of this function is to exactly replicate
16 # the behavior of the select module when confronted with
17 # abnormal filenos; the details are extensively tested in
18 # the stdlib test/test_select.py.
21 except AttributeError:
22 if not isinstance(obj, six.integer_types):
23 raise TypeError("Expected int or long, got %s" % type(obj))
27 if not isinstance(rv, six.integer_types):
28 raise TypeError("Expected int or long, got %s" % type(rv))
32 def select(read_list, write_list, error_list, timeout=None):
33 # error checking like this is required by the stdlib unit tests
34 if timeout is not None:
36 timeout = float(timeout)
38 raise TypeError("Expected number for timeout")
41 current = getcurrent()
42 assert hub.greenlet is not current, 'do not call blocking functions from the mainloop'
45 ds[get_fileno(r)] = {'read': r}
47 ds.setdefault(get_fileno(w), {})['write'] = w
49 ds.setdefault(get_fileno(e), {})['error'] = e
54 original = ds[get_fileno(d)]['read']
55 current.switch(([original], [], []))
58 original = ds[get_fileno(d)]['write']
59 current.switch(([], [original], []))
61 def on_error(d, _err=None):
62 original = ds[get_fileno(d)]['error']
63 current.switch(([], [], [original]))
66 current.switch(([], [], []))
69 # ensure that BaseHub.run() has a chance to call self.wait()
70 # at least once before timed out. otherwise the following code
71 # can time out erroneously.
73 # s1, s2 = socket.socketpair()
74 # print(select.select([], [s1], [], 0))
75 timers.append(hub.schedule_call_global(0, on_timeout2))
77 if timeout is not None:
78 timers.append(hub.schedule_call_global(timeout, on_timeout))
80 for k, v in six.iteritems(ds):
82 listeners.append(hub.add(hub.READ, k, on_read, on_error, lambda x: None))
84 listeners.append(hub.add(hub.WRITE, k, on_write, on_error, lambda x: None))