summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLance Stout <lancestout@gmail.com>2011-02-23 10:09:53 -0500
committerLance Stout <lancestout@gmail.com>2011-02-23 10:20:04 -0500
commit4df3aa569bc8e88b70986022e558ee9024dd7ffb (patch)
tree8cb2f89b89b9e8a868e89c71a125cdb77df892b1
parent2e2e16e281be81e4f19e45021fe23fb3196ada83 (diff)
downloadslixmpp-4df3aa569bc8e88b70986022e558ee9024dd7ffb.tar.gz
slixmpp-4df3aa569bc8e88b70986022e558ee9024dd7ffb.tar.bz2
slixmpp-4df3aa569bc8e88b70986022e558ee9024dd7ffb.tar.xz
slixmpp-4df3aa569bc8e88b70986022e558ee9024dd7ffb.zip
Bring back the signal handlers (and the "killed" event).
Now done more responsibly, saving any existing signal handlers and calling them when an interrupt occurs in addition to the one Sleek installs. NOTE: You may need to explicitly use "kill <process id>" in order to trigger the proper signal handler execution, and to raise the "killed" event.
-rw-r--r--sleekxmpp/xmlstream/xmlstream.py51
1 files changed, 51 insertions, 0 deletions
diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py
index a5151d7b..18d891a3 100644
--- a/sleekxmpp/xmlstream/xmlstream.py
+++ b/sleekxmpp/xmlstream/xmlstream.py
@@ -10,6 +10,7 @@ from __future__ import with_statement, unicode_literals
import copy
import logging
+import signal
import socket as Socket
import ssl
import sys
@@ -195,6 +196,53 @@ class XMLStream(object):
self.auto_reconnect = True
self.is_client = False
+ def use_signals(self, signals=None):
+ """
+ Register signal handlers for SIGHUP and SIGTERM, if possible,
+ which will raise a "killed" event when the application is
+ terminated.
+
+ If a signal handler already existed, it will be executed first,
+ before the "killed" event is raised.
+
+ Arguments:
+ signals -- A list of signal names to be monitored.
+ Defaults to ['SIGHUP', 'SIGTERM'].
+ """
+ if signals is None:
+ signals = ['SIGHUP', 'SIGTERM']
+
+ existing_handlers = {}
+ for sig_name in signals:
+ if hasattr(signal, sig_name):
+ sig = getattr(signal, sig_name)
+ handler = signal.getsignal(sig)
+ if handler:
+ existing_handlers[sig] = handler
+
+ def handle_kill(signum, frame):
+ """
+ Capture kill event and disconnect cleanly after first
+ spawning the "killed" event.
+ """
+
+ if signum in existing_handlers and \
+ existing_handlers[signum] != handle_kill:
+ existing_handlers[signum](signum, frame)
+
+ self.event("killed", direct=True)
+ self.disconnect()
+
+ try:
+ for sig_name in signals:
+ if hasattr(signal, sig_name):
+ sig = getattr(signal, sig_name)
+ signal.signal(sig, handle_kill)
+ self.__signals_installed = True
+ except:
+ log.debug("Can not set interrupt signal handlers. " + \
+ "SleekXMPP is not running from a main thread.")
+
def new_id(self):
"""
Generate and return a new stream ID in hexadecimal form.
@@ -731,6 +779,7 @@ class XMLStream(object):
if not self.stop.isSet() and self.auto_reconnect:
self.reconnect()
else:
+ self.event('killed', direct=True)
self.disconnect()
self.event_queue.put(('quit', None, None))
self.scheduler.run = False
@@ -909,6 +958,7 @@ class XMLStream(object):
return False
except KeyboardInterrupt:
log.debug("Keyboard Escape Detected in _event_runner")
+ self.event('killed', direct=True)
self.disconnect()
return
except SystemExit:
@@ -934,6 +984,7 @@ class XMLStream(object):
self.disconnect(self.auto_reconnect)
except KeyboardInterrupt:
log.debug("Keyboard Escape Detected in _send_thread")
+ self.event('killed', direct=True)
self.disconnect()
return
except SystemExit: