Revision b9768937

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