summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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: