diff options
author | hut <hut@lavabit.com> | 2010-11-22 02:06:46 +0100 |
---|---|---|
committer | hut <hut@lavabit.com> | 2010-11-22 02:38:11 +0100 |
commit | 0940c18905ede976d576150f235e378fe8c4c8b5 (patch) | |
tree | d273eef518f2b80e9168038de8045d1c4d187e6a | |
parent | ffa2e9a0a763f8a284925edf52022e966c57fce3 (diff) | |
download | ranger-0940c18905ede976d576150f235e378fe8c4c8b5.tar.gz |
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()
-rw-r--r-- | ranger/core/environment.py | 2 | ||||
-rw-r--r-- | 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 |