[sldev-commits] r56 - branches/beta-1/eventlet

phoenix.linden at svn.secondlife.com phoenix.linden at svn.secondlife.com
Mon Dec 3 15:48:10 PST 2007


Author: phoenix.linden
Date: 2007-12-03 17:48:10 -0600 (Mon, 03 Dec 2007)
New Revision: 56

Modified:
   branches/beta-1/eventlet/coros.py
   branches/beta-1/eventlet/coros_test.py
   branches/beta-1/eventlet/runloop.py
   branches/beta-1/eventlet/runloop_test.py
   branches/beta-1/eventlet/timer.py
   branches/beta-1/eventlet/timer_test.py
Trac: http://svn.secondlife.com/trac/eventlet/changeset/56
Log:
clean up timers when coroutines are returned to the pool. DEV-6116 DEV-6120

Modified: branches/beta-1/eventlet/coros.py
===================================================================
--- branches/beta-1/eventlet/coros.py	2007-12-01 01:27:14 UTC (rev 55)
+++ branches/beta-1/eventlet/coros.py	2007-12-03 23:48:10 UTC (rev 56)
@@ -110,6 +110,7 @@
                 traceback.print_exc()
                 if evt is not None:
                     evt.send(exc=e)
+            api.get_hub().runloop.cancel_timers(api.getcurrent())
             self.put(sender)
 
     def create(self):

Modified: branches/beta-1/eventlet/coros_test.py
===================================================================
--- branches/beta-1/eventlet/coros_test.py	2007-12-01 01:27:14 UTC (rev 55)
+++ branches/beta-1/eventlet/coros_test.py	2007-12-03 23:48:10 UTC (rev 56)
@@ -22,6 +22,7 @@
 THE SOFTWARE.
 """
 from eventlet import tests
+from eventlet import timer
 from eventlet import coros, api
 
 class TestEvent(tests.TestCase):
@@ -140,5 +141,16 @@
         done.wait()
         self.assertEquals(['cons1', 'prod', 'cons2'], results)
 
+    def test_timer_cancel(self):
+        def some_work():
+            t = timer.Timer(5, lambda: None)
+            t.schedule()
+            return t
+        pool = coros.CoroutinePool(0, 2)
+        worker = pool.execute(some_work)
+        t = worker.wait()
+        api.sleep(0)
+        self.assertEquals(t.cancelled, True)
+
 if __name__ == '__main__':
     tests.main()

Modified: branches/beta-1/eventlet/runloop.py
===================================================================
--- branches/beta-1/eventlet/runloop.py	2007-12-01 01:27:14 UTC (rev 55)
+++ branches/beta-1/eventlet/runloop.py	2007-12-03 23:48:10 UTC (rev 56)
@@ -32,6 +32,8 @@
 import sys
 import traceback
 
+import greenlet
+
 from eventlet.timer import Timer
 
 
@@ -48,6 +50,7 @@
         self.stopping = False
         self.running = False
         self.timers = []
+        self.timers_by_greenlet = {}
         self.next_timers = []
         self.observers = {}
         self.observer_modes = {
@@ -164,8 +167,14 @@
     def add_timer(self, timer):
         scheduled_time = self.clock() + timer.seconds
         self._add_absolute_timer(scheduled_time, timer)
+        current_greenlet = greenlet.getcurrent()
+        if current_greenlet not in self.timers_by_greenlet:
+            self.timers_by_greenlet[current_greenlet] = {}
+        self.timers_by_greenlet[current_greenlet][timer] = True
+        timer.greenlet = current_greenlet
         return scheduled_time
-    
+
+
     def prepare_timers(self):
         ins = bisect.insort_right
         t = self.timers
@@ -192,9 +201,25 @@
         for i in xrange(last):
             timer = t[i][2]
             try:
-                timer()
-            except self.SYSTEM_EXCEPTIONS:
-                raise
-            except:
-                self.squelch_timer_exception(timer, sys.exc_info())
+                try:
+                    timer()
+                except self.SYSTEM_EXCEPTIONS:
+                    raise
+                except:
+                    self.squelch_timer_exception(timer, sys.exc_info())
+            finally:
+                try:
+                    del self.timers_by_greenlet[timer.greenlet][timer]
+                except KeyError:
+                    pass
         del t[:last]
+
+    def cancel_timers(self, greenlet):
+        for timer in self.timers_by_greenlet[greenlet]:
+            if timer.seconds:
+                ## If timer.seconds is 0, this isn't a timer, it's
+                ## actually eventlet's silly way of specifying whether
+                ## a coroutine is "ready to run" or not.
+                timer.cancel()
+        del self.timers_by_greenlet[greenlet]
+        

Modified: branches/beta-1/eventlet/runloop_test.py
===================================================================
--- branches/beta-1/eventlet/runloop_test.py	2007-12-01 01:27:14 UTC (rev 55)
+++ branches/beta-1/eventlet/runloop_test.py	2007-12-03 23:48:10 UTC (rev 56)
@@ -1,5 +1,5 @@
 """\
- at file test_runloop.py
+ at file runloop_test.py
 @author Donovan Preston
 
 Copyright (c) 2006-2007, Linden Research, Inc.

Modified: branches/beta-1/eventlet/timer.py
===================================================================
--- branches/beta-1/eventlet/timer.py	2007-12-01 01:27:14 UTC (rev 55)
+++ branches/beta-1/eventlet/timer.py	2007-12-03 23:48:10 UTC (rev 56)
@@ -25,7 +25,7 @@
 from eventlet.api import get_hub
 
 class Timer(object):
-    __slots__ = ['seconds', 'tpl', 'called', 'cancelled', 'scheduled_time']
+    __slots__ = ['seconds', 'tpl', 'called', 'cancelled', 'scheduled_time', 'greenlet']
     def __init__(self, seconds, cb, *args, **kw):
         """Create a timer.
             seconds: The minimum number of seconds to wait before calling

Modified: branches/beta-1/eventlet/timer_test.py
===================================================================
--- branches/beta-1/eventlet/timer_test.py	2007-12-01 01:27:14 UTC (rev 55)
+++ branches/beta-1/eventlet/timer_test.py	2007-12-03 23:48:10 UTC (rev 56)
@@ -1,5 +1,5 @@
 """\
- at file test_timer.py
+ at file timer_test.py
 @author Donovan Preston
 
 Copyright (c) 2006-2007, Linden Research, Inc.



More information about the sldev-commits mailing list