Revision b9768937 lib/utils.py
b/lib/utils.py | ||
---|---|---|
3258 | 3258 |
return wrap |
3259 | 3259 |
|
3260 | 3260 |
|
3261 |
class SignalWakeupFd(object): |
|
3262 |
try: |
|
3263 |
# This is only supported in Python 2.5 and above (some distributions |
|
3264 |
# backported it to Python 2.4) |
|
3265 |
_set_wakeup_fd_fn = signal.set_wakeup_fd |
|
3266 |
except AttributeError: |
|
3267 |
# Not supported |
|
3268 |
def _SetWakeupFd(self, _): # pylint: disable-msg=R0201 |
|
3269 |
return -1 |
|
3270 |
else: |
|
3271 |
def _SetWakeupFd(self, fd): |
|
3272 |
return self._set_wakeup_fd_fn(fd) |
|
3273 |
|
|
3274 |
def __init__(self): |
|
3275 |
"""Initializes this class. |
|
3276 |
|
|
3277 |
""" |
|
3278 |
(read_fd, write_fd) = os.pipe() |
|
3279 |
|
|
3280 |
# Once these succeeded, the file descriptors will be closed automatically. |
|
3281 |
# Buffer size 0 is important, otherwise .read() with a specified length |
|
3282 |
# might buffer data and the file descriptors won't be marked readable. |
|
3283 |
self._read_fh = os.fdopen(read_fd, "r", 0) |
|
3284 |
self._write_fh = os.fdopen(write_fd, "w", 0) |
|
3285 |
|
|
3286 |
self._previous = self._SetWakeupFd(self._write_fh.fileno()) |
|
3287 |
|
|
3288 |
# Utility functions |
|
3289 |
self.fileno = self._read_fh.fileno |
|
3290 |
self.read = self._read_fh.read |
|
3291 |
|
|
3292 |
def Reset(self): |
|
3293 |
"""Restores the previous wakeup file descriptor. |
|
3294 |
|
|
3295 |
""" |
|
3296 |
if hasattr(self, "_previous") and self._previous is not None: |
|
3297 |
self._SetWakeupFd(self._previous) |
|
3298 |
self._previous = None |
|
3299 |
|
|
3300 |
def Notify(self): |
|
3301 |
"""Notifies the wakeup file descriptor. |
|
3302 |
|
|
3303 |
""" |
|
3304 |
self._write_fh.write("\0") |
|
3305 |
|
|
3306 |
def __del__(self): |
|
3307 |
"""Called before object deletion. |
|
3308 |
|
|
3309 |
""" |
|
3310 |
self.Reset() |
|
3311 |
|
|
3312 |
|
|
3261 | 3313 |
class SignalHandler(object): |
3262 | 3314 |
"""Generic signal handler class. |
3263 | 3315 |
|
... | ... | |
3272 | 3324 |
@ivar called: tracks whether any of the signals have been raised |
3273 | 3325 |
|
3274 | 3326 |
""" |
3275 |
def __init__(self, signum, handler_fn=None): |
|
3327 |
def __init__(self, signum, handler_fn=None, wakeup=None):
|
|
3276 | 3328 |
"""Constructs a new SignalHandler instance. |
3277 | 3329 |
|
3278 | 3330 |
@type signum: int or list of ints |
... | ... | |
3287 | 3339 |
self.called = False |
3288 | 3340 |
|
3289 | 3341 |
self._handler_fn = handler_fn |
3342 |
self._wakeup = wakeup |
|
3290 | 3343 |
|
3291 | 3344 |
self._previous = {} |
3292 | 3345 |
try: |
... | ... | |
3336 | 3389 |
# solution in Python -- there are no atomic types. |
3337 | 3390 |
self.called = True |
3338 | 3391 |
|
3392 |
if self._wakeup: |
|
3393 |
# Notify whoever is interested in signals |
|
3394 |
self._wakeup.Notify() |
|
3395 |
|
|
3339 | 3396 |
if self._handler_fn: |
3340 | 3397 |
self._handler_fn(signum, frame) |
3341 | 3398 |
|
Also available in: Unified diff