Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

87 wiersze
2.7KB

  1. import eventlet
  2. from eventlet.hubs import get_hub
  3. import six
  4. __select = eventlet.patcher.original('select')
  5. error = __select.error
  6. __patched__ = ['select']
  7. __deleted__ = ['devpoll', 'poll', 'epoll', 'kqueue', 'kevent']
  8. def get_fileno(obj):
  9. # The purpose of this function is to exactly replicate
  10. # the behavior of the select module when confronted with
  11. # abnormal filenos; the details are extensively tested in
  12. # the stdlib test/test_select.py.
  13. try:
  14. f = obj.fileno
  15. except AttributeError:
  16. if not isinstance(obj, six.integer_types):
  17. raise TypeError("Expected int or long, got %s" % type(obj))
  18. return obj
  19. else:
  20. rv = f()
  21. if not isinstance(rv, six.integer_types):
  22. raise TypeError("Expected int or long, got %s" % type(rv))
  23. return rv
  24. def select(read_list, write_list, error_list, timeout=None):
  25. # error checking like this is required by the stdlib unit tests
  26. if timeout is not None:
  27. try:
  28. timeout = float(timeout)
  29. except ValueError:
  30. raise TypeError("Expected number for timeout")
  31. hub = get_hub()
  32. timers = []
  33. current = eventlet.getcurrent()
  34. assert hub.greenlet is not current, 'do not call blocking functions from the mainloop'
  35. ds = {}
  36. for r in read_list:
  37. ds[get_fileno(r)] = {'read': r}
  38. for w in write_list:
  39. ds.setdefault(get_fileno(w), {})['write'] = w
  40. for e in error_list:
  41. ds.setdefault(get_fileno(e), {})['error'] = e
  42. listeners = []
  43. def on_read(d):
  44. original = ds[get_fileno(d)]['read']
  45. current.switch(([original], [], []))
  46. def on_write(d):
  47. original = ds[get_fileno(d)]['write']
  48. current.switch(([], [original], []))
  49. def on_timeout2():
  50. current.switch(([], [], []))
  51. def on_timeout():
  52. # ensure that BaseHub.run() has a chance to call self.wait()
  53. # at least once before timed out. otherwise the following code
  54. # can time out erroneously.
  55. #
  56. # s1, s2 = socket.socketpair()
  57. # print(select.select([], [s1], [], 0))
  58. timers.append(hub.schedule_call_global(0, on_timeout2))
  59. if timeout is not None:
  60. timers.append(hub.schedule_call_global(timeout, on_timeout))
  61. try:
  62. for k, v in six.iteritems(ds):
  63. if v.get('read'):
  64. listeners.append(hub.add(hub.READ, k, on_read, current.throw, lambda: None))
  65. if v.get('write'):
  66. listeners.append(hub.add(hub.WRITE, k, on_write, current.throw, lambda: None))
  67. try:
  68. return hub.switch()
  69. finally:
  70. for l in listeners:
  71. hub.remove(l)
  72. finally:
  73. for t in timers:
  74. t.cancel()