From 80e55b0c817d1a251ca333c6973ed3b250d68031 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 24 Mar 2013 21:25:55 +0400 Subject: [PATCH 1/6] Replace update_lock with shutdon_event --- powerline/lib/threaded.py | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/powerline/lib/threaded.py b/powerline/lib/threaded.py index 147de23b..73aff250 100644 --- a/powerline/lib/threaded.py +++ b/powerline/lib/threaded.py @@ -5,18 +5,17 @@ from __future__ import absolute_import from powerline.lib.time import monotonic from time import sleep -from threading import Thread, Lock +from threading import Thread, Lock, Event class ThreadedSegment(object): - daemon = True min_sleep_time = 0.1 update_first = True interval = 1 def __init__(self): super(ThreadedSegment, self).__init__() - self.update_lock = Lock() + self.shutdown_event = Event() self.write_lock = Lock() self.keep_going = True self.run_once = True @@ -50,39 +49,27 @@ class ThreadedSegment(object): def start(self): self.thread = Thread(target=self.run) - self.thread.daemon = self.daemon self.thread.start() def sleep(self, adjust_time): - sleep(max(self.interval - adjust_time, self.min_sleep_time)) + self.shutdown_event.wait(max(self.interval - adjust_time, self.min_sleep_time)) + if self.shutdown_event.is_set(): + self.keep_going = False def run(self): while self.keep_going: start_time = monotonic() - try: - if self.update_lock.acquire(False): - try: - self.update() - except Exception as e: - self.error('Exception while updating: {0}', str(e)) - self.skip = True - else: - self.skip = False - else: - return - finally: - # Release lock in any case. If it is not locked in this thread, - # it was done in main thread in .shutdown method, and the lock - # will never be released. - self.update_lock.release() - + self.update() + except Exception as e: + self.error('Exception while updating: {0}', str(e)) + self.skip = True + else: + self.skip = False self.sleep(monotonic() - start_time) def shutdown(self): - if self.keep_going: - self.keep_going = False - self.update_lock.acquire() + self.shutdown_event.set() def set_interval(self, interval=None): # Allowing “interval” keyword in configuration. From 00271c2a0c98a18dc8806e62b3ac9b36c7aa3d66 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 24 Mar 2013 21:30:17 +0400 Subject: [PATCH 2/6] Shut down network_load segment in tests --- tests/test_segments.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_segments.py b/tests/test_segments.py index 9ce53e27..beb354de 100644 --- a/tests/test_segments.py +++ b/tests/test_segments.py @@ -251,6 +251,7 @@ class TestCommon(TestCase): {'divider_highlight_group': 'background:divider', 'contents': 'r 1 KiB/s', 'highlight_group': ['network_load_recv', 'network_load']}, {'divider_highlight_group': 'background:divider', 'contents': 's 2 KiB/s', 'highlight_group': ['network_load_sent_gradient', 'network_load_gradient', 'network_load_sent', 'network_load'], 'gradient_level': ApproxEqual()}, ]) + common.network_load.shutdown() def test_virtualenv(self): with replace_env('VIRTUAL_ENV', '/abc/def/ghi') as pl: From 3809b8b3b5be159e3e492a0db0c99da29dbfd14b Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 24 Mar 2013 21:38:08 +0400 Subject: [PATCH 3/6] Allow multiple shutdowns with multiple starts --- powerline/lib/threaded.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powerline/lib/threaded.py b/powerline/lib/threaded.py index 73aff250..0089e1c7 100644 --- a/powerline/lib/threaded.py +++ b/powerline/lib/threaded.py @@ -17,7 +17,6 @@ class ThreadedSegment(object): super(ThreadedSegment, self).__init__() self.shutdown_event = Event() self.write_lock = Lock() - self.keep_going = True self.run_once = True self.did_set_interval = False self.thread = None @@ -48,6 +47,7 @@ class ThreadedSegment(object): return self.thread and self.thread.is_alive() def start(self): + self.keep_going = True self.thread = Thread(target=self.run) self.thread.start() From 3aab9ef96c7b8b0c4c48be4cca2d8f8813099110 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 24 Mar 2013 21:40:11 +0400 Subject: [PATCH 4/6] Make zsh/zpython also call .shutdown correctly --- powerline/bindings/zsh/__init__.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/powerline/bindings/zsh/__init__.py b/powerline/bindings/zsh/__init__.py index ff82a5af..420f0e86 100644 --- a/powerline/bindings/zsh/__init__.py +++ b/powerline/bindings/zsh/__init__.py @@ -1,9 +1,18 @@ # vim:fileencoding=utf-8:noet import zsh +import atexit from powerline.shell import ShellPowerline from powerline.lib import parsedotval +used_powerlines = [] + + +def shutdown(): + for powerline in used_powerlines: + powerline.renderer.shutdown() + + def get_var_config(var): try: return [parsedotval(i) for i in zsh.getvalue(var).items()] @@ -69,17 +78,17 @@ class Environment(object): class Prompt(object): - __slots__ = ('render', 'side', 'savedpsvar', 'savedps', 'args') + __slots__ = ('powerline', 'side', 'savedpsvar', 'savedps', 'args') def __init__(self, powerline, side, savedpsvar=None, savedps=None): - self.render = powerline.renderer.render + self.powerline = powerline self.side = side self.savedpsvar = savedpsvar self.savedps = savedps self.args = powerline.args def __str__(self): - r = self.render(width=zsh.columns(), side=self.side, segment_info=self.args) + r = self.powerline.renderer.render(width=zsh.columns(), side=self.side, segment_info=self.args) if type(r) is not str: if type(r) is bytes: return r.decode('utf-8') @@ -90,6 +99,9 @@ class Prompt(object): def __del__(self): if self.savedps: zsh.setvalue(self.savedpsvar, self.savedps) + used_powerlines.remove(self.powerline) + if self.powerline not in used_powerlines: + self.powerline.renderer.shutdown() def set_prompt(powerline, psvar, side): @@ -103,5 +115,8 @@ def set_prompt(powerline, psvar, side): def setup(): environ = Environment() powerline = ShellPowerline(Args(), environ=environ, getcwd=lambda: environ['PWD']) + used_powerlines.append(powerline) + used_powerlines.append(powerline) set_prompt(powerline, 'PS1', 'left') set_prompt(powerline, 'RPS1', 'right') + atexit.register(shutdown) From 8c63d20880635efe8d6200172c0f9415dc8fe6ad Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 24 Mar 2013 22:39:31 +0400 Subject: [PATCH 5/6] Fix update_first --- powerline/lib/threaded.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/powerline/lib/threaded.py b/powerline/lib/threaded.py index 0089e1c7..19b841f5 100644 --- a/powerline/lib/threaded.py +++ b/powerline/lib/threaded.py @@ -37,6 +37,8 @@ class ThreadedSegment(object): if update_first and self.update_first: self.update() self.start() + elif not self.updated: + self.update() if self.skip: return self.crashed_value @@ -80,9 +82,10 @@ class ThreadedSegment(object): self.interval = interval self.has_set_interval = True - def set_state(self, interval=None, **kwargs): + def set_state(self, interval=None, update_first=True, **kwargs): if not self.did_set_interval or interval: self.set_interval(interval) + self.updated = not (update_first and self.update_first) def startup(self, pl, **kwargs): self.run_once = False @@ -111,12 +114,13 @@ def printed(func): class KwThreadedSegment(ThreadedSegment): drop_interval = 10 * 60 - update_first = False + update_first = True def __init__(self): super(KwThreadedSegment, self).__init__() self.queries = {} self.crashed = set() + self.updated = True @staticmethod def key(**kwargs): @@ -157,7 +161,7 @@ class KwThreadedSegment(ThreadedSegment): for key in removes: self.queries.pop(key) - def set_state(self, interval=None, **kwargs): + def set_state(self, interval=None, update_first=True, **kwargs): if not self.did_set_interval or (interval < self.interval): self.set_interval(interval) From 92652ca5c4f8cb0f4deeaaa4b2efdc74388049f1 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 25 Mar 2013 00:10:54 +0400 Subject: [PATCH 6/6] Some fixes for flake8 --- powerline/lib/threaded.py | 1 - tests/test_segments.py | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/powerline/lib/threaded.py b/powerline/lib/threaded.py index 19b841f5..50d7895e 100644 --- a/powerline/lib/threaded.py +++ b/powerline/lib/threaded.py @@ -4,7 +4,6 @@ from __future__ import absolute_import from powerline.lib.time import monotonic -from time import sleep from threading import Thread, Lock, Event diff --git a/tests/test_segments.py b/tests/test_segments.py index beb354de..87c460f1 100644 --- a/tests/test_segments.py +++ b/tests/test_segments.py @@ -193,6 +193,7 @@ class TestCommon(TestCase): def test_network_load(self): from time import sleep + def gb(interface): return None