From 0aee445e6976b03f7e04bcab6ec40ecf14b5d1a4 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Thu, 16 Dec 2010 22:21:50 -0500 Subject: Use daemon threads instead of signals. Daemonized threads exit once the main program has quit, and the only threads left running are all daemon threads. Should fix hanging clients while not trampling over anyone else's signal handlers. --- sleekxmpp/xmlstream/xmlstream.py | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'sleekxmpp/xmlstream/xmlstream.py') diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py index 9e91b5d8..2317f04c 100644 --- a/sleekxmpp/xmlstream/xmlstream.py +++ b/sleekxmpp/xmlstream/xmlstream.py @@ -16,7 +16,6 @@ import sys import threading import time import types -import signal try: import queue except ImportError: @@ -209,24 +208,6 @@ class XMLStream(object): self.auto_reconnect = True self.is_client = False - try: - if hasattr(signal, 'SIGHUP'): - signal.signal(signal.SIGHUP, self._handle_kill) - if hasattr(signal, 'SIGTERM'): - # Used in Windows - signal.signal(signal.SIGTERM, self._handle_kill) - except: - log.debug("Can not set interrupt signal handlers. " + \ - "SleekXMPP is not running from a main thread.") - - def _handle_kill(self, signum, frame): - """ - Capture kill event and disconnect cleanly after first - spawning the "killed" event. - """ - self.event("killed", direct=True) - self.disconnect() - def new_id(self): """ Generate and return a new stream ID in hexadecimal form. @@ -705,6 +686,7 @@ class XMLStream(object): def start_thread(name, target): self.__thread[name] = threading.Thread(name=name, target=target) + self.__thread[name].daemon = True self.__thread[name].start() for t in range(0, HANDLER_THREADS): -- cgit v1.2.3 From 34c374a1e1dad468869c8e5dc6fb2ea7b1d90c7e Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Fri, 17 Dec 2010 13:11:03 -0500 Subject: Make tests pass for catching exceptions. May now use sys.excepthook to catch exceptions from threaded handlers. --- sleekxmpp/xmlstream/xmlstream.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'sleekxmpp/xmlstream/xmlstream.py') diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py index 2317f04c..d5c1043b 100644 --- a/sleekxmpp/xmlstream/xmlstream.py +++ b/sleekxmpp/xmlstream/xmlstream.py @@ -682,6 +682,7 @@ class XMLStream(object): Event handlers and the send queue will be threaded regardless of this parameter's value. """ + self._thread_excepthook() self.scheduler.process(threaded=True) def start_thread(name, target): @@ -954,3 +955,26 @@ class XMLStream(object): self.disconnect() self.event_queue.put(('quit', None, None)) return + + def _thread_excepthook(self): + """ + If a threaded event handler raises an exception, there is no way to + catch it except with an excepthook. Currently, each thread has its own + excepthook, but ideally we could use the main sys.excepthook. + + Modifies threading.Thread to use sys.excepthook when an exception + is not caught. + """ + init_old = threading.Thread.__init__ + def init(self, *args, **kwargs): + init_old(self, *args, **kwargs) + run_old = self.run + def run_with_except_hook(*args, **kw): + try: + run_old(*args, **kw) + except (KeyboardInterrupt, SystemExit): + raise + except: + sys.excepthook(*sys.exc_info()) + self.run = run_with_except_hook + threading.Thread.__init__ = init -- cgit v1.2.3