From 2f62137e89bbd7710c323c9fd8e2f492cc70ccf6 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 17 May 2009 19:27:14 -0700 Subject: [PATCH] Removed exc_greenlet from the hubs and the waiters_by_greenlet dict that was needed to support that functionality because the try/finally around hub.switch in trampoline does the right thing already. Added a unit test to verify that this still works. --- eventlet/api.py | 2 +- eventlet/hubs/hub.py | 9 --------- eventlet/hubs/libev.py | 2 -- eventlet/hubs/libevent.py | 2 -- eventlet/hubs/twistedr.py | 9 --------- greentest/api_test.py | 30 ++++++++++++++++++++++++++++++ 6 files changed, 31 insertions(+), 23 deletions(-) diff --git a/eventlet/api.py b/eventlet/api.py index 7e7d300..0a2aa4a 100644 --- a/eventlet/api.py +++ b/eventlet/api.py @@ -431,7 +431,7 @@ def exc_after(seconds, *throw_args): timer.cancel() """ hub = get_hub() - return call_after(seconds, hub.exc_greenlet, getcurrent(), *throw_args) + return call_after(seconds, getcurrent().throw, *throw_args) def get_default_hub(): diff --git a/eventlet/hubs/hub.py b/eventlet/hubs/hub.py index 55de1d4..74b1427 100644 --- a/eventlet/hubs/hub.py +++ b/eventlet/hubs/hub.py @@ -41,7 +41,6 @@ class BaseHub(object): self.readers = {} self.writers = {} self.excs = {} - self.waiters_by_greenlet = {} self.clock = clock self.greenlet = greenlet.greenlet(self.run) @@ -87,20 +86,12 @@ class BaseHub(object): self.excs[fileno] = exc else: self.excs.pop(fileno, None) - self.waiters_by_greenlet[greenlet.getcurrent()] = fileno return fileno def remove_descriptor(self, fileno): self.readers.pop(fileno, None) self.writers.pop(fileno, None) self.excs.pop(fileno, None) - self.waiters_by_greenlet.pop(greenlet.getcurrent(), None) - - def exc_greenlet(self, gr, *throw_args): - fileno = self.waiters_by_greenlet.pop(gr, None) - if fileno is not None: - self.remove_descriptor(fileno) - gr.throw(*throw_args) def exc_descriptor(self, fileno): exc = self.excs.get(fileno) diff --git a/eventlet/hubs/libev.py b/eventlet/hubs/libev.py index 57f009a..8964778 100644 --- a/eventlet/hubs/libev.py +++ b/eventlet/hubs/libev.py @@ -66,7 +66,6 @@ class Hub(hub.BaseHub): if exc: self.excs[fileno] = exc - self.waiters_by_greenlet[greenlet.getcurrent()] = fileno return fileno def remove_descriptor(self, fileno): @@ -75,7 +74,6 @@ class Hub(hub.BaseHub): if tpl is not None: tpl[0].stop() self.excs.pop(fileno, None) - self.waiters_by_greenlet.pop(greenlet.getcurrent(), None) def abort(self): super(Hub, self).abort() diff --git a/eventlet/hubs/libevent.py b/eventlet/hubs/libevent.py index 948abba..2184649 100644 --- a/eventlet/hubs/libevent.py +++ b/eventlet/hubs/libevent.py @@ -72,7 +72,6 @@ class Hub(hub.BaseHub): if exc: self.excs[fileno] = exc - self.waiters_by_greenlet[greenlet.getcurrent()] = fileno return fileno def remove_descriptor(self, fileno): @@ -81,7 +80,6 @@ class Hub(hub.BaseHub): if tpl is not None: tpl[0].delete() self.excs.pop(fileno, None) - self.waiters_by_greenlet.pop(greenlet.getcurrent(), None) def abort(self): super(Hub, self).abort() diff --git a/eventlet/hubs/twistedr.py b/eventlet/hubs/twistedr.py index 0540d89..7d429b4 100644 --- a/eventlet/hubs/twistedr.py +++ b/eventlet/hubs/twistedr.py @@ -106,7 +106,6 @@ class BaseTwistedHub(object): def __init__(self, mainloop_greenlet): self.greenlet = mainloop_greenlet - self.waiters_by_greenlet = {} def switch(self): assert api.getcurrent() is not self.greenlet, "Cannot switch from MAINLOOP to MAINLOOP" @@ -128,20 +127,12 @@ class BaseTwistedHub(object): if write: reactor.addWriter(descriptor) # XXX exc will not work if no read nor write - self.waiters_by_greenlet[api.getcurrent()] = descriptor return descriptor def remove_descriptor(self, descriptor): from twisted.internet import reactor reactor.removeReader(descriptor) reactor.removeWriter(descriptor) - self.waiters_by_greenlet.pop(api.getcurrent(), None) - - def exc_greenlet(self, gr, *throw_args): - fileno = self.waiters_by_greenlet.pop(gr, None) - if fileno is not None: - self.remove_descriptor(fileno) - gr.throw(*throw_args) # required by GreenSocket def exc_descriptor(self, _fileno): diff --git a/greentest/api_test.py b/greentest/api_test.py index 60799e1..561bab0 100644 --- a/greentest/api_test.py +++ b/greentest/api_test.py @@ -186,6 +186,36 @@ class TestApi(tests.TestCase): self.assertRaises( ImportError, api.named, 'this_name_should_hopefully_not_exist.Foo') + def test_timeout_and_final_write(self): + # This test verifies that a write on a socket that we've + # stopped listening for doesn't result in an incorrect switch + from eventlet import greenio + rpipe, wpipe = os.pipe() + rfile = os.fdopen(rpipe,"r",0) + wrap_rfile = greenio.GreenPipe(rfile) + wfile = os.fdopen(wpipe,"w",0) + wrap_wfile = greenio.GreenPipe(wfile) + + def sender(evt): + api.sleep(0.02) + wrap_wfile.write('hi') + evt.send('sent via event') + + from eventlet import coros + evt = coros.event() + api.spawn(sender, evt) + try: + # try and get some data off of this pipe + # but bail before any is sent + api.exc_after(0.01, api.TimeoutError) + _c = wrap_rfile.read(1) + self.fail() + except api.TimeoutError: + pass + + result = evt.wait() + self.assertEquals(result, 'sent via event') + class Foo(object): pass