Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

113 строки
3.5KB

  1. import os
  2. import sys
  3. from eventlet import patcher, support
  4. from eventlet.hubs import hub
  5. import six
  6. select = patcher.original('select')
  7. time = patcher.original('time')
  8. def is_available():
  9. return hasattr(select, 'kqueue')
  10. class Hub(hub.BaseHub):
  11. MAX_EVENTS = 100
  12. def __init__(self, clock=None):
  13. self.FILTERS = {
  14. hub.READ: select.KQ_FILTER_READ,
  15. hub.WRITE: select.KQ_FILTER_WRITE,
  16. }
  17. super(Hub, self).__init__(clock)
  18. self._events = {}
  19. self._init_kqueue()
  20. def _init_kqueue(self):
  21. self.kqueue = select.kqueue()
  22. self._pid = os.getpid()
  23. def _reinit_kqueue(self):
  24. self.kqueue.close()
  25. self._init_kqueue()
  26. events = [e for i in six.itervalues(self._events)
  27. for e in six.itervalues(i)]
  28. self.kqueue.control(events, 0, 0)
  29. def _control(self, events, max_events, timeout):
  30. try:
  31. return self.kqueue.control(events, max_events, timeout)
  32. except (OSError, IOError):
  33. # have we forked?
  34. if os.getpid() != self._pid:
  35. self._reinit_kqueue()
  36. return self.kqueue.control(events, max_events, timeout)
  37. raise
  38. def add(self, evtype, fileno, cb, tb, mac):
  39. listener = super(Hub, self).add(evtype, fileno, cb, tb, mac)
  40. events = self._events.setdefault(fileno, {})
  41. if evtype not in events:
  42. try:
  43. event = select.kevent(fileno, self.FILTERS.get(evtype), select.KQ_EV_ADD)
  44. self._control([event], 0, 0)
  45. events[evtype] = event
  46. except ValueError:
  47. super(Hub, self).remove(listener)
  48. raise
  49. return listener
  50. def _delete_events(self, events):
  51. del_events = [
  52. select.kevent(e.ident, e.filter, select.KQ_EV_DELETE)
  53. for e in events
  54. ]
  55. self._control(del_events, 0, 0)
  56. def remove(self, listener):
  57. super(Hub, self).remove(listener)
  58. evtype = listener.evtype
  59. fileno = listener.fileno
  60. if not self.listeners[evtype].get(fileno):
  61. event = self._events[fileno].pop(evtype, None)
  62. if event is None:
  63. return
  64. try:
  65. self._delete_events((event,))
  66. except OSError:
  67. pass
  68. def remove_descriptor(self, fileno):
  69. super(Hub, self).remove_descriptor(fileno)
  70. try:
  71. events = self._events.pop(fileno).values()
  72. self._delete_events(events)
  73. except KeyError:
  74. pass
  75. except OSError:
  76. pass
  77. def wait(self, seconds=None):
  78. readers = self.listeners[self.READ]
  79. writers = self.listeners[self.WRITE]
  80. if not readers and not writers:
  81. if seconds:
  82. time.sleep(seconds)
  83. return
  84. result = self._control([], self.MAX_EVENTS, seconds)
  85. SYSTEM_EXCEPTIONS = self.SYSTEM_EXCEPTIONS
  86. for event in result:
  87. fileno = event.ident
  88. evfilt = event.filter
  89. try:
  90. if evfilt == select.KQ_FILTER_READ:
  91. readers.get(fileno, hub.noop).cb(fileno)
  92. if evfilt == select.KQ_FILTER_WRITE:
  93. writers.get(fileno, hub.noop).cb(fileno)
  94. except SYSTEM_EXCEPTIONS:
  95. raise
  96. except:
  97. self.squelch_exception(fileno, sys.exc_info())
  98. support.clear_sys_exc_info()