+++ /dev/null
-import sys
-import traceback
-import event
-import types
-
-from eventlet.support import greenlets as greenlet, six
-from eventlet.hubs.hub import BaseHub, READ, WRITE
-
-
-class event_wrapper(object):
-
- def __init__(self, impl=None, seconds=None):
- self.impl = impl
- self.seconds = seconds
-
- def __repr__(self):
- if self.impl is not None:
- return repr(self.impl)
- else:
- return object.__repr__(self)
-
- def __str__(self):
- if self.impl is not None:
- return str(self.impl)
- else:
- return object.__str__(self)
-
- def cancel(self):
- if self.impl is not None:
- self.impl.delete()
- self.impl = None
-
- @property
- def pending(self):
- return bool(self.impl and self.impl.pending())
-
-
-class Hub(BaseHub):
-
- SYSTEM_EXCEPTIONS = (KeyboardInterrupt, SystemExit)
-
- def __init__(self):
- super(Hub, self).__init__()
- event.init()
-
- self.signal_exc_info = None
- self.signal(
- 2,
- lambda signalnum, frame: self.greenlet.parent.throw(KeyboardInterrupt))
- self.events_to_add = []
-
- def dispatch(self):
- loop = event.loop
- while True:
- for e in self.events_to_add:
- if e is not None and e.impl is not None and e.seconds is not None:
- e.impl.add(e.seconds)
- e.seconds = None
- self.events_to_add = []
- result = loop()
-
- if getattr(event, '__event_exc', None) is not None:
- # only have to do this because of bug in event.loop
- t = getattr(event, '__event_exc')
- setattr(event, '__event_exc', None)
- assert getattr(event, '__event_exc') is None
- six.reraise(t[0], t[1], t[2])
-
- if result != 0:
- return result
-
- def run(self):
- while True:
- try:
- self.dispatch()
- except greenlet.GreenletExit:
- break
- except self.SYSTEM_EXCEPTIONS:
- raise
- except:
- if self.signal_exc_info is not None:
- self.schedule_call_global(
- 0, greenlet.getcurrent().parent.throw, *self.signal_exc_info)
- self.signal_exc_info = None
- else:
- self.squelch_timer_exception(None, sys.exc_info())
-
- def abort(self, wait=True):
- self.schedule_call_global(0, self.greenlet.throw, greenlet.GreenletExit)
- if wait:
- assert self.greenlet is not greenlet.getcurrent(
- ), "Can't abort with wait from inside the hub's greenlet."
- self.switch()
-
- def _getrunning(self):
- return bool(self.greenlet)
-
- def _setrunning(self, value):
- pass # exists for compatibility with BaseHub
- running = property(_getrunning, _setrunning)
-
- def add(self, evtype, fileno, real_cb, real_tb, mac):
- # this is stupid: pyevent won't call a callback unless it's a function,
- # so we have to force it to be one here
- if isinstance(real_cb, types.BuiltinMethodType):
- def cb(_d):
- real_cb(_d)
- else:
- cb = real_cb
-
- if evtype is READ:
- evt = event.read(fileno, cb, fileno)
- elif evtype is WRITE:
- evt = event.write(fileno, cb, fileno)
-
- return super(Hub, self).add(evtype, fileno, evt, real_tb, mac)
-
- def signal(self, signalnum, handler):
- def wrapper():
- try:
- handler(signalnum, None)
- except:
- self.signal_exc_info = sys.exc_info()
- event.abort()
- return event_wrapper(event.signal(signalnum, wrapper))
-
- def remove(self, listener):
- super(Hub, self).remove(listener)
- listener.cb.delete()
-
- def remove_descriptor(self, fileno):
- for lcontainer in six.itervalues(self.listeners):
- listener = lcontainer.pop(fileno, None)
- if listener:
- try:
- listener.cb.delete()
- except self.SYSTEM_EXCEPTIONS:
- raise
- except:
- traceback.print_exc()
-
- def schedule_call_local(self, seconds, cb, *args, **kwargs):
- current = greenlet.getcurrent()
- if current is self.greenlet:
- return self.schedule_call_global(seconds, cb, *args, **kwargs)
- event_impl = event.event(_scheduled_call_local, (cb, args, kwargs, current))
- wrapper = event_wrapper(event_impl, seconds=seconds)
- self.events_to_add.append(wrapper)
- return wrapper
-
- schedule_call = schedule_call_local
-
- def schedule_call_global(self, seconds, cb, *args, **kwargs):
- event_impl = event.event(_scheduled_call, (cb, args, kwargs))
- wrapper = event_wrapper(event_impl, seconds=seconds)
- self.events_to_add.append(wrapper)
- return wrapper
-
- def _version_info(self):
- baseversion = event.__version__
- return baseversion
-
-
-def _scheduled_call(event_impl, handle, evtype, arg):
- cb, args, kwargs = arg
- try:
- cb(*args, **kwargs)
- finally:
- event_impl.delete()
-
-
-def _scheduled_call_local(event_impl, handle, evtype, arg):
- cb, args, kwargs, caller_greenlet = arg
- try:
- if not caller_greenlet.dead:
- cb(*args, **kwargs)
- finally:
- event_impl.delete()