def test_signals(self):
signalled_all.acquire()
self.spawnSignallingThread()
signalled_all.acquire()
# the signals that we asked the kernel to send
# will come back, but we don't know when.
# (it might even be after the thread exits
# and might be out of order.) If we haven't seen
# the signals yet, send yet another signal and
# wait for it return.
if signal_blackboard[signal.SIGUSR1]['tripped'] == 0 \
or signal_blackboard[signal.SIGUSR2]['tripped'] == 0:
signal.alarm(1)
signal.pause()
signal.alarm(0)
self.assertEqual( signal_blackboard[signal.SIGUSR1]['tripped'], 1)
self.assertEqual( signal_blackboard[signal.SIGUSR1]['tripped_by'],
thread.get_ident())
self.assertEqual( signal_blackboard[signal.SIGUSR2]['tripped'], 1)
self.assertEqual( signal_blackboard[signal.SIGUSR2]['tripped_by'],
thread.get_ident())
signalled_all.release()
python类alarm()的实例源码
def check_reentrant_write(self, data, **fdopen_kwargs):
def on_alarm(*args):
# Will be called reentrantly from the same thread
wio.write(data)
1//0
signal.signal(signal.SIGALRM, on_alarm)
r, w = os.pipe()
wio = self.io.open(w, **fdopen_kwargs)
try:
signal.alarm(1)
# Either the reentrant call to wio.write() fails with RuntimeError,
# or the signal handler raises ZeroDivisionError.
with self.assertRaises((ZeroDivisionError, RuntimeError)) as cm:
while 1:
for i in range(100):
wio.write(data)
wio.flush()
# Make sure the buffer doesn't fill up and block further writes
os.read(r, len(data) * 100)
exc = cm.exception
if isinstance(exc, RuntimeError):
self.assertTrue(str(exc).startswith("reentrant call"), str(exc))
finally:
wio.close()
os.close(r)
def check_interrupted_read_retry(self, decode, **fdopen_kwargs):
"""Check that a buffered read, when it gets interrupted (either
returning a partial result or EINTR), properly invokes the signal
handler and retries if the latter returned successfully."""
r, w = os.pipe()
fdopen_kwargs["closefd"] = False
def alarm_handler(sig, frame):
os.write(w, b"bar")
signal.signal(signal.SIGALRM, alarm_handler)
try:
rio = self.io.open(r, **fdopen_kwargs)
os.write(w, b"foo")
signal.alarm(1)
# Expected behaviour:
# - first raw read() returns partial b"foo"
# - second raw read() returns EINTR
# - third raw read() returns b"bar"
self.assertEqual(decode(rio.read(6)), "foobar")
finally:
rio.close()
os.close(w)
os.close(r)
def accept(self):
# Messages are passed from remote client to server line by line
# A number representing the number of lines to receive will be passed first
# Then serialCommunicationServer should loop the exact time to receive the following lines
# All these reads add up tp ONE timeout: acceptTimeout. Once exceeded, this timeout will trigger a callback raising an exception
# Throw acceptTimeoutException, ValueError
# Store the incoming parameters into an internal data structure
self._returnList = []
self._log.writeLog("Clear internal list. Size: " + str(len(self._returnList)))
signal.alarm(self._acceptTimeout) # Enable SIGALRM
self._log.writeLog("Accept-timer starts, with acceptTimeout: " + str(self._acceptTimeout) + " second(s).")
numLines = int(self._basicInput()) # Get number of lines to receive
self._log.writeLog(str(numLines) + " lines to be received. Loop begins.")
loopCount = 1
while(loopCount <= numLines):
currElementIn = self._basicInput()
self._returnList.append(currElementIn)
self._log.writeLog("Received: " + str(loopCount) + "/" + str(numLines) + " Message is: " + currElementIn)
loopCount += 1
signal.alarm(0) # Finish reading from remote client, disable SIGALRM
self._log.writeLog("Finish reading from remote client. Accept-timer ends.")
return self._returnList
def timeout(seconds=20):
def decorator(func):
def _handle_timeout(command, signum, frame):
raise TimeoutError("'%s' command did not return" % command)
def wrapper(*args, **kwargs):
if len(args) >= 3:
signal.signal(signal.SIGALRM, partial(_handle_timeout,
args[2]))
else:
signal.signal(signal.SIGALRM, partial(_handle_timeout, None))
signal.alarm(seconds)
try:
result = func(*args, **kwargs)
finally:
signal.alarm(0)
return result
return wraps(func)(wrapper)
return decorator
def timeout(seconds=10, error_message=os.strerror(errno.ETIME)):
def decorator(func):
def _handle_timeout(signum, frame):
raise TimeoutError(error_message)
def wrapper(*args, **kwargs):
signal.signal(signal.SIGALRM, _handle_timeout)
signal.alarm(seconds)
try:
result = func(*args, **kwargs)
finally:
signal.alarm(0)
return result
return wraps(func)(wrapper)
return decorator
def time_limit(seconds):
'''
Context manager (with statement) to handle long function calls.
Needed to test the while loop in Listener
:param seconds: time before stop
'''
def signal_handler(signum, frame):
raise SignalTimeoutException('{sec} seconds are over!'.format(sec=seconds))
# Sets a timeout using signal
signal.signal(signal.SIGALRM, signal_handler)
signal.alarm(seconds)
try:
yield
finally:
signal.alarm(0)
def timeout(seconds=10, error_message=os.strerror(errno.ETIME)):
"""returns a decorator controlling the running time of the decorated function.
Throws a TimeoutError exception if the decorated function does not return in given time.
"""
def decorator(func):
"""the decorator."""
def _handle_timeout(_signum, _frame):
raise TimeoutError(error_message)
def wrapper(*args, **kwargs):
"""wraps the function"""
signal.signal(signal.SIGALRM, _handle_timeout)
signal.alarm(seconds)
try:
result = func(*args, **kwargs)
finally:
signal.alarm(0)
return result
return wraps(func)(wrapper)
return decorator
def __call__(self, func):
def _handle_timeout(signum, frame):
raise TimeoutException()
@functools.wraps(func)
def wrapper(*args, **kwargs):
try:
# set the alarm and execute func
signal.signal(signal.SIGALRM, _handle_timeout)
signal.alarm(self.timeoutSeconds)
result = func(*args, **kwargs)
finally:
# clear the alarm
signal.alarm(0)
return result
return wrapper
# ---------------- Context managers ----------------
def test_multiprocessing():
"""Tests that the number of children we produce is correct"""
# Selects a number at random so we can spot check
num_workers = random.choice(range(2, multiprocessing.cpu_count() * 2 + 1))
app = Sanic('test_multiprocessing')
process_list = set()
def stop_on_alarm(*args):
for process in multiprocessing.active_children():
process_list.add(process.pid)
process.terminate()
signal.signal(signal.SIGALRM, stop_on_alarm)
signal.alarm(1)
app.run(HOST, PORT, workers=num_workers)
assert len(process_list) == num_workers
def connect_pipe(pipe, pipeName):
"""
"""
oldHandler = signal.getsignal(signal.SIGALRM)
try:
signal.signal(signal.SIGALRM, SIGALRM_handler)
signal.alarm(CONNECT_TIMEOUT_SECS + 1)
retval = os.open(pipeName, os.O_RDONLY)
signal.alarm(0)
except OSError:
# Alarm Timeout
retval = None
except BaseException:
# Keyboard interrupt
retval = None
# cancel the alarm and restore prev handler
signal.signal(signal.SIGALRM, oldHandler)
return retval
def loop(self, timeout=5):
""" main loop for the consumer client """
consumer_tag = "callback_%s" % self.name
chan = self.connection.channel()
def callback(msg):
""" callback for message received """
if options.verbose:
print "Client %s saw this message: '%s'" % (self.name, msg.body)
if self.check_end(msg): # we have been asked to quit
self._quit = True
chan.basic_consume(queue=self.name, no_ack=True, callback=callback,
consumer_tag=consumer_tag)
signal.signal(signal.SIGALRM, alarm_handler)
signal.alarm(timeout)
while True:
chan.wait()
if self._quit:
break
# cancel alarm for receive wait
signal.alarm(0)
chan.basic_cancel(consumer_tag)
chan.close()
return self._quit
def test_lock_acquire_interruption(self):
# Mimic receiving a SIGINT (KeyboardInterrupt) with SIGALRM while stuck
# in a deadlock.
# XXX this test can fail when the legacy (non-semaphore) implementation
# of locks is used in thread_pthread.h, see issue #11223.
oldalrm = signal.signal(signal.SIGALRM, self.alarm_interrupt)
try:
lock = thread.allocate_lock()
lock.acquire()
signal.alarm(1)
t1 = time.time()
self.assertRaises(KeyboardInterrupt, lock.acquire, timeout=5)
dt = time.time() - t1
# Checking that KeyboardInterrupt was raised is not sufficient.
# We want to assert that lock.acquire() was interrupted because
# of the signal, not that the signal handler was called immediately
# after timeout return of lock.acquire() (which can fool assertRaises).
self.assertLess(dt, 3.0)
finally:
signal.signal(signal.SIGALRM, oldalrm)
def test_rlock_acquire_interruption(self):
# Mimic receiving a SIGINT (KeyboardInterrupt) with SIGALRM while stuck
# in a deadlock.
# XXX this test can fail when the legacy (non-semaphore) implementation
# of locks is used in thread_pthread.h, see issue #11223.
oldalrm = signal.signal(signal.SIGALRM, self.alarm_interrupt)
try:
rlock = thread.RLock()
# For reentrant locks, the initial acquisition must be in another
# thread.
def other_thread():
rlock.acquire()
thread.start_new_thread(other_thread, ())
# Wait until we can't acquire it without blocking...
while rlock.acquire(blocking=False):
rlock.release()
time.sleep(0.01)
signal.alarm(1)
t1 = time.time()
self.assertRaises(KeyboardInterrupt, rlock.acquire, timeout=5)
dt = time.time() - t1
# See rationale above in test_lock_acquire_interruption
self.assertLess(dt, 3.0)
finally:
signal.signal(signal.SIGALRM, oldalrm)
def test_wakeup_fd_early(self):
self.check_wakeup("""def test():
import select
import time
TIMEOUT_FULL = 10
TIMEOUT_HALF = 5
signal.alarm(1)
before_time = time.time()
# We attempt to get a signal during the sleep,
# before select is called
time.sleep(TIMEOUT_FULL)
mid_time = time.time()
dt = mid_time - before_time
if dt >= TIMEOUT_HALF:
raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
select.select([read], [], [], TIMEOUT_FULL)
after_time = time.time()
dt = after_time - mid_time
if dt >= TIMEOUT_HALF:
raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
""", signal.SIGALRM)
def test_sigwaitinfo_interrupted(self):
self.wait_helper(signal.SIGUSR1, '''
def test(signum):
import errno
hndl_called = True
def alarm_handler(signum, frame):
hndl_called = False
signal.signal(signal.SIGALRM, alarm_handler)
signal.alarm(1)
try:
signal.sigwaitinfo([signal.SIGUSR1])
except OSError as e:
if e.errno == errno.EINTR:
if not hndl_called:
raise Exception("SIGALRM handler not called")
else:
raise Exception("Expected EINTR to be raised by sigwaitinfo")
else:
raise Exception("Expected EINTR to be raised by sigwaitinfo")
''')
def check_reentrant_write(self, data, **fdopen_kwargs):
def on_alarm(*args):
# Will be called reentrantly from the same thread
wio.write(data)
1/0
signal.signal(signal.SIGALRM, on_alarm)
r, w = os.pipe()
wio = self.io.open(w, **fdopen_kwargs)
try:
signal.alarm(1)
# Either the reentrant call to wio.write() fails with RuntimeError,
# or the signal handler raises ZeroDivisionError.
with self.assertRaises((ZeroDivisionError, RuntimeError)) as cm:
while 1:
for i in range(100):
wio.write(data)
wio.flush()
# Make sure the buffer doesn't fill up and block further writes
os.read(r, len(data) * 100)
exc = cm.exception
if isinstance(exc, RuntimeError):
self.assertTrue(str(exc).startswith("reentrant call"), str(exc))
finally:
wio.close()
os.close(r)
def check_interrupted_read_retry(self, decode, **fdopen_kwargs):
"""Check that a buffered read, when it gets interrupted (either
returning a partial result or EINTR), properly invokes the signal
handler and retries if the latter returned successfully."""
r, w = os.pipe()
fdopen_kwargs["closefd"] = False
def alarm_handler(sig, frame):
os.write(w, b"bar")
signal.signal(signal.SIGALRM, alarm_handler)
try:
rio = self.io.open(r, **fdopen_kwargs)
os.write(w, b"foo")
signal.alarm(1)
# Expected behaviour:
# - first raw read() returns partial b"foo"
# - second raw read() returns EINTR
# - third raw read() returns b"bar"
self.assertEqual(decode(rio.read(6)), "foobar")
finally:
rio.close()
os.close(w)
os.close(r)
def borgcubed_idle(apiserver):
"""Check schedule. Are we supposed to do something right about now?"""
# seconds = seconds_until_next_occurence()
# log.debug('setting alarm clock to beep in %d seconds', seconds)
# signal.alarm(seconds)
this_very_moment = now()
for schedule in data_root().schedules:
if not schedule.recurrence_enabled:
continue
# TODO: when django-recurrence#81 is resolved, use cache.
occurence = schedule.recurrence.after(this_very_moment)
if latest_executions.get(schedule._p_oid) == occurence:
continue
if occurence and abs((occurence - this_very_moment).total_seconds()) < 10:
latest_executions[schedule._p_oid] = occurence
execute(apiserver, schedule)
def __call__(self, *args, **keyArgs):
# If we have SIGALRM signal, use it to cause an exception if and
# when this function runs too long. Otherwise check the time taken
# after the method has returned, and throw an exception then.
if hasattr(signal, 'SIGALRM'):
old = signal.signal(signal.SIGALRM, self.handle_timeout)
signal.alarm(self.timeout)
try:
result = self.function(*args, **keyArgs)
finally:
signal.signal(signal.SIGALRM, old)
signal.alarm(0)
else:
startTime = time.time()
result = self.function(*args, **keyArgs)
timeElapsed = time.time() - startTime
if timeElapsed >= self.timeout:
self.handle_timeout(None, None)
return result