Source code for weblib.watch

import os
import signal
import sys
import logging
import time


[docs]class Watcher(object): """this class solves two problems with multithreaded programs in Python, (1) a signal might be delivered to any thread (which is just a malfeature) and (2) if the thread that gets the signal is waiting, the signal is ignored (which is a bug). The watcher is a concurrent process (not thread) that waits for a signal and the process that contains the threads. See Appendix A of The Little Book of Semaphores. http://greenteapress.com/semaphores/ I have only tested this on Linux. I would expect it to work on the Macintosh and not work on Windows. """ def __init__(self): """ Creates a child thread, which returns. The parent thread waits for a KeyboardInterrupt and then kills the child thread. """ self.child = os.fork() if self.child == 0: return else: self.watch() def watch(self): try: os.wait() except KeyboardInterrupt: logging.debug('Watcher process received KeyboardInterrupt') """ signals = ( ('SIGTERM', 1), ('SIGKILL', 2), ) for sig, sleep_time in signals: if not os.path.exists('/proc/%d' % self.child): logging.debug('Process terminated!') break else: logging.debug('Sending %s signal to child process' % sig) try: os.kill(self.child, getattr(signal, sig)) except OSError: pass logging.debug('Waiting %s second after sending %s' % (sleep_time, sig)) for x in xrange(10): time.sleep(sleep_time / 10.0) if not os.path.exists('/proc/%d' % self.child): break """ wait_time = 1 for x in xrange(10): os.kill(self.child, signal.SIGKILL) if not os.path.exists('/proc/%d' % self.child): break else: time.sleep(wait_time / 10.0) """ if os.path.exists('/proc/%d' % self.child): logging.error('Process pid=%d still exists' % self.child) """ sys.exit()
def watch(): Watcher()