Commits

Anonymous committed 97a9826

Add support for the itimer module with blocking detection

This will allow for subsecond blocking detection thanks to the itimer
module recently released by Slide, Inc:
http://github.com/slideinc/itimer

  • Participants
  • Parent commits 71f9e63

Comments (0)

Files changed (4)

eventlet/debug.py

     from eventlet import tpool
     tpool.QUIET = not state
 
-def hub_blocking_detection(state = False):
+def hub_blocking_detection(state = False, resolution = 1):
     """Toggles whether Eventlet makes an effort to detect blocking
     behavior in other code.  It does this by setting a SIGALARM with a short 
     timeout.
     """
     from eventlet import hubs
     hubs.get_hub().debug_blocking = state
+    hubs.get_hub().debug_blocking_resolution = resolution
     if(not state):
         hubs.get_hub().block_detect_post()
     

eventlet/hubs/hub.py

 import warnings
 import signal
 
+HAS_ITIMER = False
+try:
+    import itimer
+    HAS_ITIMER = True
+except ImportError:
+    pass
+
 from eventlet.support import greenlets as greenlet, clear_sys_exc_info
 from eventlet.hubs import timer
 from eventlet import patcher
         self.timers_canceled = 0
         self.debug_exceptions = True
         self.debug_blocking = False
+        self.debug_blocking_resolution = 1
 
     def block_detect_pre(self):
         # shortest alarm we can possibly raise is one second
         tmp = signal.signal(signal.SIGALRM, alarm_handler)
         if tmp != alarm_handler:
             self._old_signal_handler = tmp
-        signal.alarm(1)
+
+        if HAS_ITIMER:
+            itimer.alarm(self.debug_blocking_resolution)
+        else:
+            signal.alarm(self.debug_blocking_resolution)
+
     def block_detect_post(self):
         if (hasattr(self, "_old_signal_handler") and
             self._old_signal_handler):

tests/__init__.py

     import sys
     return skip_if(sys.platform.startswith('win'))(func)
 
+def skip_if_no_itimer(func):
+    """ Decorator that skips a test if the `itimer` module isn't found """
+    has_itimer = False
+    try:
+        import itimer
+        has_itimer = True
+    except ImportError:
+        pass
+    return skip_unless(has_itimer)(func)
+
 
 class TestIsTakingTooLong(Exception):
     """ Custom exception class to be raised when a test's runtime exceeds a limit. """

tests/hub_test.py

-from tests import LimitedTestCase, main, skip_with_pyevent
+from tests import LimitedTestCase, main, skip_with_pyevent, skip_if_no_itimer
 import time
 import eventlet
 from eventlet import hubs
         self.assertRaises(RuntimeError, gt.wait)
         debug.hub_blocking_detection(False)
 
+    @skip_if_no_itimer
+    def test_block_detect_with_itimer(self):
+        def look_im_blocking():
+            import time
+            time.sleep(0.5)
+
+        from eventlet import debug
+        debug.hub_blocking_detection(True, resolution=0.1)
+        gt = eventlet.spawn(look_im_blocking)
+        self.assertRaises(RuntimeError, gt.wait)
+        debug.hub_blocking_detection(False)
+
 class TestSuspend(LimitedTestCase):
     TEST_TIMEOUT=3
     def test_suspend_doesnt_crash(self):