Skip to content

Instantly share code, notes, and snippets.

@nonZero
Created June 10, 2012 22:11
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save nonZero/2907502 to your computer and use it in GitHub Desktop.
Save nonZero/2907502 to your computer and use it in GitHub Desktop.
GracefulInterruptHandler
import signal
class GracefulInterruptHandler(object):
def __init__(self, sig=signal.SIGINT):
self.sig = sig
def __enter__(self):
self.interrupted = False
self.released = False
self.original_handler = signal.getsignal(self.sig)
def handler(signum, frame):
self.release()
self.interrupted = True
signal.signal(self.sig, handler)
return self
def __exit__(self, type, value, tb):
self.release()
def release(self):
if self.released:
return False
signal.signal(self.sig, self.original_handler)
self.released = True
return True
if __name__ == '__main__':
import unittest
import time
class GracefulInterruptHandlerTestCase(unittest.TestCase):
def test_simple(self):
with GracefulInterruptHandler() as h:
while True:
print "..."
time.sleep(1)
if h.interrupted:
print "interrupted!"
time.sleep(5)
break
def test_nested(self):
with GracefulInterruptHandler() as h1:
while True:
print "(1)..."
time.sleep(1)
with GracefulInterruptHandler() as h2:
while True:
print "\t(2)..."
time.sleep(1)
if h2.interrupted:
print "\t(2) interrupted!"
time.sleep(2)
break
if h1.interrupted:
print "(1) interrupted!"
time.sleep(2)
break
unittest.main()
@nalbat
Copy link

nalbat commented May 29, 2014

Hello!

Why should you call release() from within signal handler?

I'm going to use this module to catch SGHUP signal and reload configs and all the other daemon program resources.

        with GracefulInterruptHandler(sig=signal.SIGHUP) as hup_hdl:
            while True:
                self.main(hup_hdl)
                if hup_hdl.interrupted:
                    hup_hdl.interrupted = False
                else:
                    break

Function self.main() at first reload configs and resources, and then proceed to an almost infinite loop.

        for line in ct:
            # do stuff
            if self.hup_hdl.interrupted:
                break

Thus, it's okay to catch SIGHUP several times during this daemon process runtime. But calling release() inside handler brakes things.

What do you think abuot it?

Sorry for my bad english.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment