diff --git a/eventlet/api.py b/eventlet/api.py index 607cfdd..4ded121 100644 --- a/eventlet/api.py +++ b/eventlet/api.py @@ -189,33 +189,30 @@ def exc_after(seconds, exc): def get_default_hub(): ## TODO some sort of plugin system? try: - import eventlet.nginxhub + import eventlet.hubs.nginx + return eventlet.hubs.nginx + except ImportError: + pass + + try: + import eventlet.hubs.libevent + return eventlet.hubs.libevent except ImportError: pass - else: - return eventlet.nginxhub try: - import eventlet.libeventhub + import eventlet.hubs.kqueue + return eventlet.hubs.kqueue except ImportError: pass - else: - return eventlet.libeventhub - - try: - import eventlet.kqueuehub - except ImportError: - pass - else: - return eventlet.kqueuehub import select if hasattr(select, 'poll'): - import eventlet.pollhub - return eventlet.pollhub + import eventlet.hubs.poll + return eventlet.hubs.poll else: - import eventlet.selecthub - return eventlet.selecthub + import eventlet.hubs.select + return eventlet.hubs.select def use_hub(mod=None): diff --git a/eventlet/hubs/__init__.py b/eventlet/hubs/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/eventlet/hub.py b/eventlet/hubs/hub.py similarity index 100% rename from eventlet/hub.py rename to eventlet/hubs/hub.py diff --git a/eventlet/libeventhub.py b/eventlet/hubs/libevent.py similarity index 98% rename from eventlet/libeventhub.py rename to eventlet/hubs/libevent.py index d05a19a..cdbec69 100644 --- a/eventlet/libeventhub.py +++ b/eventlet/hubs/libevent.py @@ -1,5 +1,5 @@ """\ -@file libeventhub.py +@file libevent.py Copyright (c) 2007, Linden Research, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy @@ -30,7 +30,7 @@ import time from eventlet import greenlib from eventlet.timer import Timer -from eventlet import hub +from eventlet.hubs import hub import greenlet diff --git a/eventlet/nginxhub.py b/eventlet/hubs/nginx.py similarity index 96% rename from eventlet/nginxhub.py rename to eventlet/hubs/nginx.py index 137a994..b23dc04 100644 --- a/eventlet/nginxhub.py +++ b/eventlet/hubs/nginx.py @@ -1,5 +1,5 @@ """\ -@file nginxhub.py +@file nginx.py @author Donovan Preston Copyright (c) 2008, Linden Research, Inc. @@ -24,14 +24,14 @@ THE SOFTWARE. """ from eventlet import greenlib -from eventlet import hub +from eventlet.hubs import hub WSGI_POLLIN = 0x01 WSGI_POLLOUT = 0x04 -class Hub(hub.Hub): +class Hub(hub.BaseHub): def add_descriptor(self, fileno, read=None, write=None, exc=None): super(Hub, self).add_descriptor(fileno, read, write, exc) diff --git a/eventlet/pollhub.py b/eventlet/hubs/poll.py similarity index 98% rename from eventlet/pollhub.py rename to eventlet/hubs/poll.py index 790dd3b..065f31b 100644 --- a/eventlet/pollhub.py +++ b/eventlet/hubs/poll.py @@ -1,5 +1,5 @@ """\ -@file pollhub.py +@file poll.py @author Bob Ippolito Copyright (c) 2005-2006, Bob Ippolito @@ -31,7 +31,7 @@ import traceback from time import sleep from eventlet import greenlib -from eventlet import hub +from eventlet.hubs import hub EXC_MASK = select.POLLERR | select.POLLHUP | select.POLLNVAL READ_MASK = select.POLLIN diff --git a/eventlet/selecthub.py b/eventlet/hubs/select.py similarity index 97% rename from eventlet/selecthub.py rename to eventlet/hubs/select.py index 798afbb..c155ff8 100644 --- a/eventlet/selecthub.py +++ b/eventlet/hubs/select.py @@ -1,5 +1,5 @@ """\ -@file selecthub.py +@file select.py Copyright (c) 2005-2006, Bob Ippolito Copyright (c) 2007, Linden Research, Inc. @@ -27,7 +27,7 @@ import select import errno import time -from eventlet import hub +from eventlet.hubs import hub import greenlet diff --git a/eventlet/kqueuehub.py b/eventlet/kqueuehub.py deleted file mode 100644 index 595e7b9..0000000 --- a/eventlet/kqueuehub.py +++ /dev/null @@ -1,219 +0,0 @@ -"""\ -@file kqueuehub.py -@author Donovan Preston - -Copyright (c) 2006-2007, Linden Research, Inc. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -""" - -import sys -import select -import kqueue -import traceback -from errno import EBADF - -from eventlet import greenlib -from eventlet.runloop import RunLoop, Timer - -import greenlet - -class Hub(object): - def __init__(self): - self.runloop = RunLoop(self.wait) - self.descriptor_queue = {} - self.descriptors = {} - self.greenlet = None - self.kfd = None - - def stop(self): - self.process_queue() - self.descriptors, self.descriptor_queue = self.descriptor_queue, {} - os.close(self.kfd) - self.kfd = None - self.runloop.abort() - if self.greenlet is not greenlet.getcurrent(): - self.switch() - - def schedule_call(self, *args, **kw): - return self.runloop.schedule_call(*args, **kw) - - def switch(self): - if not self.greenlet: - self.greenlet = greenlib.tracked_greenlet() - args = ((self.runloop.run,),) - else: - args = () - try: - greenlet.getcurrent().parent = self.greenlet - except ValueError: - pass - return greenlib.switch(self.greenlet, *args) - - def add_descriptor(self, fileno, read=None, write=None, exc=None): - self.descriptor_queue[fileno] = read, write, exc - - def remove_descriptor(self, fileno): - self.descriptor_queue[fileno] = None, None, None - - def exc_descriptor(self, fileno): - # We must handle two cases here, the descriptor - # may be changing or removing its exc handler - # in the queue, or it may be waiting on the queue. - exc = None - try: - exc = self.descriptor_queue[fileno][2] - except KeyError: - try: - exc = self.descriptors[fileno][2] - except KeyError: - pass - if exc is not None: - try: - exc() - except self.runloop.SYSTEM_EXCEPTIONS: - self.squelch_exception(fileno, sys.exc_info()) - - def squelch_exception(self, fileno, exc_info): - traceback.print_exception(*exc_info) - print >>sys.stderr, "Removing descriptor: %r" % (fileno,) - try: - self.remove_descriptor(fileno) - except Exception, e: - print >>sys.stderr, "Exception while removing descriptor! %r" % (e,) - - def process_queue(self): - if self.kfd is None: - self.kfd = kqueue.kqueue() - d = self.descriptors - - E_R = kqueue.EVFILT_READ - E_W = kqueue.EVFILT_WRITE - E = kqueue.Event - E_ADD = kqueue.EV_ADD - E_DEL = kqueue.EV_DELETE - - kevent = kqueue.kevent - kfd = self.kfd - for fileno, rwe in self.descriptor_queue.iteritems(): - read, write, exc = rwe - if read is None and write is None and exc is None: - try: - read, write, exc = d.pop(fileno) - except KeyError: - pass - else: - l = [] - if read is not None: - l.append(E(fileno, E_R, E_DEL)) - if write is not None: - l.append(E(fileno, E_W, E_DEL)) - if l: - try: - kevent(kfd, l, 0, 0) - except OSError, e: - if e[0] != EBADF: - raise - else: - l = [] - try: - oldr, oldw, olde = d[fileno] - except KeyError: - pass - else: - if oldr is not None: - if read is None: - l.append(E(fileno, E_R, E_DEL)) - else: - read = None - if oldw is not None: - if write is None: - l.append(E(fileno, E_W, E_DEL)) - else: - write = None - if read is not None: - l.append(E(fileno, E_R, E_ADD)) - if write is not None: - l.append(E(fileno, E_W, E_ADD)) - if l: - try: - kevent(kfd, l, 0, 0) - except OSError, e: - if e[0] != EBADF: - raise - try: - del d[fileno] - except KeyError: - pass - if exc is not None: - try: - exc(fileno) - except SYSTEM_EXCEPTIONS: - raise - except: - self.squelch_exception(fileno, sys.exc_info()) - continue - d[fileno] = rwe - self.descriptor_queue.clear() - - def wait(self, seconds=None): - - self.process_queue() - - if seconds is not None: - seconds *= 1000000000.0 - dct = self.descriptors - events = kqueue.kevent(self.kfd, [], len(dct), seconds) - - SYSTEM_EXCEPTIONS = self.runloop.SYSTEM_EXCEPTIONS - - E_R = kqueue.EVFILT_READ - E_W = kqueue.EVFILT_WRITE - E_EOF = kqueue.EV_EOF - - for e in events: - fileno = e.ident - event = e.filter - - try: - read, write, exc = dct[fileno] - except KeyError: - continue - - if read is not None and event == E_R: - try: - read(fileno) - except SYSTEM_EXCEPTIONS: - raise - except: - self.squelch_exception(fileno, sys.exc_info()) - elif exc is not None and e.fflags & E_EOF: - try: - exc(fileno) - except SYSTEM_EXCEPTIONS: - raise - except: - self.squelch_exception(fileno, sys.exc_info()) - - if write is not None and event == E_W: - try: - write(fileno) - except SYSTEM_EXCEPTIONS: - raise - except: - self.squelch_exception(fileno, sys.exc_info())