diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2023-12-29 14:35:36 -0500 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2023-12-30 12:55:59 -0500 |
commit | 92fe8f15b82d7c7ccb7f8ac6552259adeac471fb (patch) | |
tree | a39197b16bc0f4228458066ae101f6a06a768f49 | |
parent | 25bc649cd263683855e892433ef3f615903d99c7 (diff) | |
download | kutter-92fe8f15b82d7c7ccb7f8ac6552259adeac471fb.tar.gz kutter-92fe8f15b82d7c7ccb7f8ac6552259adeac471fb.tar.xz kutter-92fe8f15b82d7c7ccb7f8ac6552259adeac471fb.zip |
buttons: Fix possible ordering issue if a callback blocks
Invoke button callbacks directly from the background thread. This
ensures that button notifications are delivered and delivered in the
correct order. Previously, if a callback blocked, it was possible a
new update could start before the previous update was completed, which
could lead to lost events or out of order events.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r-- | klippy/extras/buttons.py | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/klippy/extras/buttons.py b/klippy/extras/buttons.py index 47274257..70d76a60 100644 --- a/klippy/extras/buttons.py +++ b/klippy/extras/buttons.py @@ -1,6 +1,6 @@ # Support for button detection and callbacks # -# Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net> +# Copyright (C) 2018-2023 Kevin O'Connor <kevin@koconnor.net> # # This file may be distributed under the terms of the GNU GPLv3 license. import logging @@ -69,17 +69,17 @@ class MCU_buttons: # Send ack to MCU self.ack_cmd.send([self.oid, new_count]) self.ack_count += new_count - # Call self.handle_button() with this event in main thread - for nb in new_buttons: - self.reactor.register_async_callback( - (lambda e, s=self, b=nb: s.handle_button(e, b))) - def handle_button(self, eventtime, button): - button ^= self.invert - changed = button ^ self.last_button - for mask, shift, callback in self.callbacks: - if changed & mask: - callback(eventtime, (button & mask) >> shift) - self.last_button = button + # Invoke callbacks with this event in main thread + btime = params['#receive_time'] + for button in new_buttons: + button ^= self.invert + changed = button ^ self.last_button + self.last_button = button + for mask, shift, callback in self.callbacks: + if changed & mask: + state = (button & mask) >> shift + self.reactor.register_async_callback( + (lambda et, c=callback, bt=btime, s=state: c(bt, s))) ###################################################################### |