summaryrefslogtreecommitdiff
path: root/sleekxmpp/xmlstream/xmlstream.py
diff options
context:
space:
mode:
Diffstat (limited to 'sleekxmpp/xmlstream/xmlstream.py')
-rw-r--r--sleekxmpp/xmlstream/xmlstream.py54
1 files changed, 52 insertions, 2 deletions
diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py
index a5151d7b..1c165562 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.
@@ -305,8 +353,7 @@ class XMLStream(object):
self.send_raw(self.stream_footer)
# Wait for confirmation that the stream was
# closed in the other direction.
- if not reconnect:
- self.auto_reconnect = False
+ self.auto_reconnect = reconnect
self.stream_end_event.wait(4)
if not self.auto_reconnect:
self.stop.set()
@@ -731,6 +778,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 +957,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 +983,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: