Fix blocking detector for cases that don't have the itimer module installed.

This commit is contained in:
Ryan Williams
2010-08-28 16:04:58 -07:00
parent 2675a1e47d
commit 8e1a262fcc
2 changed files with 28 additions and 13 deletions

View File

@@ -134,10 +134,23 @@ def tpool_exceptions(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.
behavior in an application.
It does this by telling the kernel to raise a SIGALARM after a
short timeout, and clearing the timeout every time the hub
greenlet is resumed. Therefore, any code that runs for a long
time without yielding to the hub will get interrupted by the
blocking detector (don't use it in production!).
The *resolution* argument governs how long the SIGALARM timeout
waits in seconds. If on Python 2.6 or later, the implementation
uses :func:`signal.setitimer` and can be specified as a
floating-point value. On 2.5 or earlier, 1 second is the minimum.
The shorter the resolution, the greater the chance of false
positives.
"""
from eventlet import hubs
assert resolution > 0
hubs.get_hub().debug_blocking = state
hubs.get_hub().debug_blocking_resolution = resolution
if(not state):

View File

@@ -1,20 +1,23 @@
import heapq
import sys
import math
import traceback
import warnings
import signal
import sys
import warnings
HAS_ITIMER = False
alarm_func = signal.alarm
arm_alarm = None
if hasattr(signal, 'setitimer'):
HAS_ITIMER = True
def alarm_itimer(seconds):
signal.setitimer(signal.ITIMER_REAL, seconds)
arm_alarm = alarm_itimer
else:
try:
import itimer
HAS_ITIMER = True
alarm_func = itimer.alarm
arm_alarm = itimer.alarm
except ImportError:
pass
def alarm_signal(seconds):
signal.alarm(math.ceil(seconds))
arm_alarm = alarm_signal
from eventlet.support import greenlets as greenlet, clear_sys_exc_info
from eventlet.hubs import timer
@@ -57,7 +60,7 @@ class DebugListener(FdListener):
def alarm_handler(signum, frame):
import inspect
raise RuntimeError("ALARMED at" + str(inspect.getframeinfo(frame)))
raise RuntimeError("Blocking detector ALARMED at" + str(inspect.getframeinfo(frame)))
class BaseHub(object):
@@ -91,8 +94,7 @@ class BaseHub(object):
if tmp != alarm_handler:
self._old_signal_handler = tmp
if HAS_ITIMER:
alarm_func(self.debug_blocking_resolution)
arm_alarm(self.debug_blocking_resolution)
def block_detect_post(self):
if (hasattr(self, "_old_signal_handler") and