From c4e760d5e7c865ba4402888e25fd6449a11e3364 Mon Sep 17 00:00:00 2001 From: kuben Date: Sun, 29 Dec 2019 23:43:12 +0100 Subject: [PATCH] lemonbar: Replace queue with Condition object in DateTime module --- .i3/lemonbar/i3_lemonbar_modules.py | 47 +++++++++++++++++++---------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/.i3/lemonbar/i3_lemonbar_modules.py b/.i3/lemonbar/i3_lemonbar_modules.py index 41403ca..37fbcd6 100644 --- a/.i3/lemonbar/i3_lemonbar_modules.py +++ b/.i3/lemonbar/i3_lemonbar_modules.py @@ -2,7 +2,6 @@ import threading import subprocess import contextlib import time, os, signal, getpass -import queue import i3_lemonbar_config as config import i3_lemonbar_common as common @@ -87,46 +86,62 @@ def format_load(data, module, alert): class DateTimeModule(LemonModule): def __init__(self): - self.show_secs = False super().__init__() def _start_module(self): class DateTimeThread(threading.Thread): def __init__(self, secs_mode = False): self.secs_mode = secs_mode - self.last_out = '' - self.w_condition = threading.Condition() - self.out_queue = queue.Queue() - self.out_queue.readline = self.out_queue.get + self.readline = self.__readline_first + self.output = '' + + lock = threading.Lock() + self.output_ready = threading.Condition(lock) + self.clock_tick = threading.Condition(lock) # Needed, because sleep may be interrupted when user + # changes H:M to H:M:S super().__init__() + def __readline_first(self): + # Should return instantly the first time + self.readline = self.__readline_blocking + return self.output + + def __readline_blocking(self): + self.output_ready.acquire() + self.output_ready.wait() + self.output_ready.release() + return self.output + def run(self): while True: fmt = "%a %d %b %H:%M:%S" if self.secs_mode else "%a %d %b %H:%M" timestr = time.strftime(fmt, time.localtime()) - if timestr != self.last_out: - self.last_out = timestr - self.out_queue.put('{}\n'.format(timestr)) + if timestr != self.output: + self.output = timestr + self.output_ready.acquire() + self.output_ready.notify() + self.output_ready.release() self.sleep_until_change() def sleep_until_change(self): # Sleep for an appropriate amount of time (depending on if showing seconds or not) # with the possibility of being woken early if self.secs_mode: - rem = 0.1 + rem = 0.1 # TODO fiddle with this, benchmarking it else: rem = time.time() % 5.0 # 5 seconds, 60 is unnecessarily long - self.w_condition.acquire() - self.w_condition.wait(rem) + self.clock_tick.acquire() + self.clock_tick.wait(rem) + self.clock_tick.release() def wake(self): - self.w_condition.acquire() - self.w_condition.notify() - self.w_condition.release() + self.clock_tick.acquire() + self.clock_tick.notify() + self.clock_tick.release() self.dt_thread = DateTimeThread() self.dt_thread.start() - self.status_handle = self.dt_thread.out_queue + self.status_handle = self.dt_thread # Only readline() is used self.date = parser.IconTextUnit('date', action='date', order=40) self.time = parser.IconTextUnit('time', action='toggle_secs', order=41