Added epoll support, should improve performance on systems that support it.

This commit is contained in:
Ryan Williams
2009-12-15 14:15:55 -08:00
parent a2e43d63ba
commit fa12462d89
3 changed files with 49 additions and 11 deletions

View File

@@ -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):

24
eventlet/hubs/epolls.py Normal file
View File

@@ -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

View File

@@ -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