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.
This commit is contained in:
parent
2e2e16e281
commit
4df3aa569b
1 changed files with 51 additions and 0 deletions
|
@ -10,6 +10,7 @@ from __future__ import with_statement, unicode_literals
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import logging
|
import logging
|
||||||
|
import signal
|
||||||
import socket as Socket
|
import socket as Socket
|
||||||
import ssl
|
import ssl
|
||||||
import sys
|
import sys
|
||||||
|
@ -195,6 +196,53 @@ class XMLStream(object):
|
||||||
self.auto_reconnect = True
|
self.auto_reconnect = True
|
||||||
self.is_client = False
|
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):
|
def new_id(self):
|
||||||
"""
|
"""
|
||||||
Generate and return a new stream ID in hexadecimal form.
|
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:
|
if not self.stop.isSet() and self.auto_reconnect:
|
||||||
self.reconnect()
|
self.reconnect()
|
||||||
else:
|
else:
|
||||||
|
self.event('killed', direct=True)
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
self.event_queue.put(('quit', None, None))
|
self.event_queue.put(('quit', None, None))
|
||||||
self.scheduler.run = False
|
self.scheduler.run = False
|
||||||
|
@ -909,6 +958,7 @@ class XMLStream(object):
|
||||||
return False
|
return False
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
log.debug("Keyboard Escape Detected in _event_runner")
|
log.debug("Keyboard Escape Detected in _event_runner")
|
||||||
|
self.event('killed', direct=True)
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
return
|
return
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
|
@ -934,6 +984,7 @@ class XMLStream(object):
|
||||||
self.disconnect(self.auto_reconnect)
|
self.disconnect(self.auto_reconnect)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
log.debug("Keyboard Escape Detected in _send_thread")
|
log.debug("Keyboard Escape Detected in _send_thread")
|
||||||
|
self.event('killed', direct=True)
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
return
|
return
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
|
|
Loading…
Reference in a new issue