device: lock computation of gestures and settings to prevent two threads from doing the same work

This commit is contained in:
Peter F. Patel-Schneider 2022-01-13 11:23:30 -05:00
parent a9c4950389
commit 22b99ecce7
1 changed files with 24 additions and 14 deletions

View File

@ -1,4 +1,5 @@
import errno as _errno
import threading as _threading
from logging import INFO as _INFO
from logging import getLogger
@ -77,9 +78,11 @@ class Device:
self._firmware = None
self._keys = None
self._gestures = None
self._gestures_lock = _threading.Lock()
self._registers = None
self._settings = None
self._feature_settings_checked = False
self._settings_lock = _threading.Lock()
# Misc stuff that's irrelevant to any functionality, but may be
# displayed in the UI and caching it here helps.
@ -287,6 +290,8 @@ class Device:
@property
def gestures(self):
if not self._gestures:
with self._gestures_lock:
if not self._gestures:
if self.online and self.protocol >= 2.0:
self._gestures = _hidpp20.get_gestures(self) or ()
@ -304,7 +309,9 @@ class Device:
@property
def settings(self):
if not self._settings:
self._settings = []
with self._settings_lock:
if not self._settings:
settings = []
if self.persister and self.descriptor and self.descriptor.settings:
for sclass in self.descriptor.settings:
try:
@ -314,7 +321,10 @@ class Device:
if self.online:
raise e
if setting is not None:
self._settings.append(setting)
settings.append(setting)
self._settings = settings
if not self._feature_settings_checked:
with self._settings_lock:
if not self._feature_settings_checked:
self._feature_settings_checked = _check_feature_settings(self, self._settings)
return self._settings