From fa12462d8926e36b95d2557f88708f6d89132b59 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 15 Dec 2009 14:15:55 -0800 Subject: [PATCH] Added epoll support, should improve performance on systems that support it. --- eventlet/api.py | 18 +++++++++++------- eventlet/hubs/epolls.py | 24 ++++++++++++++++++++++++ eventlet/hubs/poll.py | 18 ++++++++++++++---- 3 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 eventlet/hubs/epolls.py diff --git a/eventlet/api.py b/eventlet/api.py index e88bcf8..0bc45b0 100644 --- a/eventlet/api.py +++ b/eventlet/api.py @@ -365,13 +365,17 @@ def get_default_hub(): from eventlet.hubs import twistedr return twistedr - import select - if hasattr(select, 'poll'): - import eventlet.hubs.poll - return eventlet.hubs.poll - else: - import eventlet.hubs.selects - return eventlet.hubs.selects + try: + import eventlet.hubs.epolls + return eventlet.hubs.epolls + except ImportError: + import select + if hasattr(select, 'poll'): + import eventlet.hubs.poll + return eventlet.hubs.poll + else: + import eventlet.hubs.selects + return eventlet.hubs.selects def use_hub(mod=None): diff --git a/eventlet/hubs/epolls.py b/eventlet/hubs/epolls.py new file mode 100644 index 0000000..57f84d7 --- /dev/null +++ b/eventlet/hubs/epolls.py @@ -0,0 +1,24 @@ +try: + # shoot for epoll module first + from epoll import poll as epoll +except ImportError, e: + # if we can't import that, hope we're on 2.6 + from select import epoll + +import time +from eventlet.hubs.hub import BaseHub +from eventlet.hubs import poll + +# NOTE: we rely on the fact that the epoll flag constants +# are identical in value to the poll constants + +class Hub(poll.Hub): + WAIT_MULTIPLIER = 1.0 # epoll.poll's timeout is measured in seconds + def __init__(self, clock=time.time): + BaseHub.__init__(self, clock) + self.poll = epoll() + try: + # modify is required by select.epoll + self.modify = self.poll.modify + except AttributeError: + self.modify = self.poll.register diff --git a/eventlet/hubs/poll.py b/eventlet/hubs/poll.py index c05a41c..f0a7340 100644 --- a/eventlet/hubs/poll.py +++ b/eventlet/hubs/poll.py @@ -11,9 +11,16 @@ READ_MASK = select.POLLIN | select.POLLPRI WRITE_MASK = select.POLLOUT class Hub(BaseHub): + WAIT_MULTIPLIER=1000.0 # poll.poll's timeout is measured in milliseconds + def __init__(self, clock=time.time): super(Hub, self).__init__(clock) self.poll = select.poll() + # poll.modify is new to 2.6 + try: + self.modify = self.poll.modify + except AttributeError: + self.modify = self.poll.register def add(self, evtype, fileno, cb): oldlisteners = self.listeners[evtype].get(fileno) @@ -21,21 +28,24 @@ class Hub(BaseHub): listener = super(Hub, self).add(evtype, fileno, cb) if not oldlisteners: # Means we've added a new listener - self.register(fileno) + self.register(fileno, new=True) return listener def remove(self, listener): super(Hub, self).remove(listener) self.register(listener.fileno) - def register(self, fileno): + def register(self, fileno, new=False): mask = 0 if self.listeners[READ].get(fileno): mask |= READ_MASK if self.listeners[WRITE].get(fileno): mask |= WRITE_MASK if mask: - self.poll.register(fileno, mask) + if new: + self.poll.register(fileno, mask) + else: + self.modify(fileno, mask) else: try: self.poll.unregister(fileno) @@ -58,7 +68,7 @@ class Hub(BaseHub): sleep(seconds) return try: - presult = self.poll.poll(seconds * 1000.0) + presult = self.poll.poll(seconds * self.WAIT_MULTIPLIER) except select.error, e: if e.args[0] == errno.EINTR: return