From 0940c18905ede976d576150f235e378fe8c4c8b5 Mon Sep 17 00:00:00 2001 From: hut Date: Mon, 22 Nov 2010 02:06:46 +0100 Subject: ext.signals: fixed memory leak Signal handlers with dead weak references are only cleaned up when using signal_emit. If no signals are emitted, dead signal handlers will accumulate. This is avoided by adding the function signal_garbage_collect() and calling it in env.garbage_collect() --- ranger/core/environment.py | 2 ++ ranger/ext/signal_dispatcher.py | 26 ++++++++++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/ranger/core/environment.py b/ranger/core/environment.py index 8d4c60df..417e36c0 100644 --- a/ranger/core/environment.py +++ b/ranger/core/environment.py @@ -128,6 +128,8 @@ class Environment(SettingsAware, SignalDispatcher): del self.directories[key] if value.is_directory: value.files = None + self.settings.signal_garbage_collect() + self.signal_garbage_collect() def get_selection(self): if self.cwd: diff --git a/ranger/ext/signal_dispatcher.py b/ranger/ext/signal_dispatcher.py index 3f407bff..5d80590a 100644 --- a/ranger/ext/signal_dispatcher.py +++ b/ranger/ext/signal_dispatcher.py @@ -74,6 +74,20 @@ class SignalDispatcher(object): except: pass + def signal_garbage_collect(self): + for handler_list in self._signals.values(): + i = len(handler_list) + while i: + i -= 1 + handler = handler_list[i] + try: + if isinstance(handler.function, tuple): + handler.function[1].__class__ + else: + handler.function.__class__ + except ReferenceError: + del handler_list[i] + def signal_emit(self, signal_name, **kw): assert isinstance(signal_name, str) if signal_name not in self._signals: @@ -87,17 +101,17 @@ class SignalDispatcher(object): # propagate for handler in tuple(handlers): if handler.active: + if isinstance(handler.function, tuple): + fnc = MethodType(*handler.function) + else: + fnc = handler.function try: - if isinstance(handler.function, tuple): - fnc = MethodType(*handler.function) - else: - fnc = handler.function if handler.pass_signal: fnc(signal) else: fnc() - if signal.stopped: - return False except ReferenceError: handlers.remove(handler) + if signal.stopped: + return False return True -- cgit 1.4.1-2-gfad0