diff --git a/deluge/ui/signalreceiver.py b/deluge/ui/signalreceiver.py index aaea99071..4353e5b59 100644 --- a/deluge/ui/signalreceiver.py +++ b/deluge/ui/signalreceiver.py @@ -38,13 +38,14 @@ import socket from deluge.log import LOG as log -class SignalReceiver(SimpleXMLRPCServer.SimpleXMLRPCServer): +class SignalReceiver(ThreadingMixIn, SimpleXMLRPCServer.SimpleXMLRPCServer): def __init__(self): log.debug("SignalReceiver init..") # Set to true so that the receiver thread will exit self.signals = {} + self.emitted_signals = [] self.remote = False @@ -77,20 +78,10 @@ class SignalReceiver(SimpleXMLRPCServer.SimpleXMLRPCServer): # Register the emit_signal function self.register_function(self.emit_signal) - self.socket.setblocking(False) - - gobject.io_add_watch(self.socket.fileno(), gobject.IO_IN | gobject.IO_OUT | gobject.IO_PRI | gobject.IO_ERR | gobject.IO_HUP, self._on_socket_activity) - #gobject.timeout_add(50, self.handle_signals) - - def _on_socket_activity(self, source, condition): - """This gets called when there is activity on the socket, ie, data to read - or to write.""" - self.handle_request() - return True - def shutdown(self): """Shutdowns receiver thread""" log.debug("Shutting down signalreceiver") + self._shutdown = True # De-register with the daemon so it doesn't try to send us more signals try: client.deregister_client() @@ -98,6 +89,11 @@ class SignalReceiver(SimpleXMLRPCServer.SimpleXMLRPCServer): except Exception, e: log.debug("Unable to deregister client from server: %s", e) + self.socket.shutdown(socket.SHUT_RDWR) + log.debug("Joining listening thread..") + self.listening_thread.join(1.0) + return + def set_remote(self, remote): self.remote = remote self.start_server(self.port) @@ -105,20 +101,46 @@ class SignalReceiver(SimpleXMLRPCServer.SimpleXMLRPCServer): def run(self): """This gets called when we start the thread""" # Register the signal receiver with the core + self._shutdown = False client.register_client(str(self.port)) + self.listening_thread = threading.Thread(target=self.handle_thread) + + gobject.timeout_add(50, self.handle_signals) + + try: + self.listening_thread.start() + except Exception, e: + log.debug("Thread: %s", e) + + def handle_thread(self): + try: + while not self._shutdown: + self.handle_request() + self._shutdown = False + except Exception, e: + log.debug("handle_thread: %s", e) + def get_port(self): """Get the port that the SignalReceiver is listening on""" return self.port def emit_signal(self, signal, *data): """Exported method used by the core to emit a signal to the client""" - try: - for callback in self.signals[signal]: - gobject.idle_add(callback, *data) + self.emitted_signals.append((signal, data)) + return - except Exception, e: - log.warning("Unable to call callback for signal %s: %s", signal, e) + def handle_signals(self): + for signal, data in self.emitted_signals: + try: + for callback in self.signals[signal]: + gobject.idle_add(callback, *data) + + except Exception, e: + log.warning("Unable to call callback for signal %s: %s", signal, e) + + self.emitted_signals = [] + return True def connect_to_signal(self, signal, callback): """Connect to a signal""" @@ -127,3 +149,4 @@ class SignalReceiver(SimpleXMLRPCServer.SimpleXMLRPCServer): self.signals[signal].append(callback) except KeyError: self.signals[signal] = [callback] +