diff options
author | hut <hut@lavabit.com> | 2010-11-22 02:06:46 +0100 |
---|---|---|
committer | hut <hut@lavabit.com> | 2010-11-22 02:06:46 +0100 |
commit | e3f6f484f0bb516a802f60f6dae89580d47a2217 (patch) | |
tree | b8f6093800e3c10627d193096a6d8a9aa84ecea5 | |
parent | fe6e709f4ccff7e0fe8aa8e492b79396012c780c (diff) | |
download | ranger-e3f6f484f0bb516a802f60f6dae89580d47a2217.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/signals.py | 26 |
2 files changed, 22 insertions, 6 deletions
diff --git a/ranger/core/environment.py b/ranger/core/environment.py index 8f5cece7..2a72229b 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/signals.py b/ranger/ext/signals.py index 3f407bff..5d80590a 100644 --- a/ranger/ext/signals.py +++ b/ranger/ext/signals.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 |