solaar: add locks to prevent multiple persisters for device
This commit is contained in:
parent
3954bbd111
commit
8744506259
|
@ -74,6 +74,7 @@ class Device:
|
||||||
self._feature_settings_checked = False
|
self._feature_settings_checked = False
|
||||||
self._gestures_lock = _threading.Lock()
|
self._gestures_lock = _threading.Lock()
|
||||||
self._settings_lock = _threading.Lock()
|
self._settings_lock = _threading.Lock()
|
||||||
|
self._persister_lock = _threading.Lock()
|
||||||
self._notification_handlers = {} # See `add_notification_handler`
|
self._notification_handlers = {} # See `add_notification_handler`
|
||||||
|
|
||||||
if not self.path:
|
if not self.path:
|
||||||
|
@ -105,6 +106,7 @@ class Device:
|
||||||
)
|
)
|
||||||
if self.number is None: # for direct-connected devices get 'number' from descriptor protocol else use 0xFF
|
if self.number is None: # for direct-connected devices get 'number' from descriptor protocol else use 0xFF
|
||||||
self.number = 0x00 if self.descriptor and self.descriptor.protocol and self.descriptor.protocol < 2.0 else 0xFF
|
self.number = 0x00 if self.descriptor and self.descriptor.protocol and self.descriptor.protocol < 2.0 else 0xFF
|
||||||
|
self.ping() # determine whether a direct-connected device is online
|
||||||
|
|
||||||
if self.descriptor:
|
if self.descriptor:
|
||||||
self._name = self.descriptor.name
|
self._name = self.descriptor.name
|
||||||
|
@ -306,7 +308,9 @@ class Device:
|
||||||
@property
|
@property
|
||||||
def persister(self):
|
def persister(self):
|
||||||
if not self._persister:
|
if not self._persister:
|
||||||
self._persister = _configuration.persister(self)
|
with self._persister_lock:
|
||||||
|
if not self._persister:
|
||||||
|
self._persister = _configuration.persister(self)
|
||||||
return self._persister
|
return self._persister
|
||||||
|
|
||||||
def battery(self): # None or level, next, status, voltage
|
def battery(self): # None or level, next, status, voltage
|
||||||
|
|
|
@ -122,7 +122,7 @@ def _device_entry_from_config_dict(data, discard_derived_properties):
|
||||||
|
|
||||||
|
|
||||||
save_timer = None
|
save_timer = None
|
||||||
save_lock = threading.Lock()
|
configuration_lock = threading.Lock()
|
||||||
defer_saves = False # don't allow configuration saves to be deferred
|
defer_saves = False # don't allow configuration saves to be deferred
|
||||||
|
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ def save(defer=False):
|
||||||
if not defer or not defer_saves:
|
if not defer or not defer_saves:
|
||||||
do_save()
|
do_save()
|
||||||
else:
|
else:
|
||||||
with save_lock:
|
with configuration_lock:
|
||||||
if not save_timer:
|
if not save_timer:
|
||||||
save_timer = threading.Timer(5.0, lambda: GLib.idle_add(do_save))
|
save_timer = threading.Timer(5.0, lambda: GLib.idle_add(do_save))
|
||||||
save_timer.start()
|
save_timer.start()
|
||||||
|
@ -148,7 +148,7 @@ def save(defer=False):
|
||||||
|
|
||||||
def do_save():
|
def do_save():
|
||||||
global save_timer
|
global save_timer
|
||||||
with save_lock:
|
with configuration_lock:
|
||||||
if save_timer:
|
if save_timer:
|
||||||
save_timer.cancel()
|
save_timer.cancel()
|
||||||
save_timer = None
|
save_timer = None
|
||||||
|
@ -239,25 +239,28 @@ def persister(device):
|
||||||
modelId and modelId == c.get(_KEY_MODEL_ID) and unitId and unitId == c.get(_KEY_UNIT_ID)
|
modelId and modelId == c.get(_KEY_MODEL_ID) and unitId and unitId == c.get(_KEY_UNIT_ID)
|
||||||
)
|
)
|
||||||
|
|
||||||
if not _config:
|
with configuration_lock:
|
||||||
_load()
|
if not _config:
|
||||||
entry = None
|
_load()
|
||||||
modelId = device.modelId if device.modelId != "000000000000" else device.name if device.modelId else None
|
entry = None
|
||||||
for c in _config:
|
# some devices report modelId and unitId as zero so use name and serial for them
|
||||||
if isinstance(c, _DeviceEntry) and match(device.wpid, device.serial, modelId, device.unitId, c):
|
modelId = device.modelId if device.modelId != "000000000000" else device._name if device.modelId else None
|
||||||
entry = c
|
unitId = device.unitId if device.modelId != "000000000000" else device._serial if device.unitId else None
|
||||||
break
|
for c in _config:
|
||||||
if not entry:
|
if isinstance(c, _DeviceEntry) and match(device.wpid, device._serial, modelId, unitId, c):
|
||||||
if not device.online: # don't create entry for offline devices
|
entry = c
|
||||||
|
break
|
||||||
|
if not entry:
|
||||||
|
if not device.online: # don't create entry for offline devices
|
||||||
|
if logger.isEnabledFor(logging.INFO):
|
||||||
|
logger.info("not setting up persister for offline device %s", device._name)
|
||||||
|
return
|
||||||
if logger.isEnabledFor(logging.INFO):
|
if logger.isEnabledFor(logging.INFO):
|
||||||
logger.info("not setting up persister for offline device %s", device.name)
|
logger.info("setting up persister for device %s", device.name)
|
||||||
return
|
entry = _DeviceEntry()
|
||||||
if logger.isEnabledFor(logging.INFO):
|
_config.append(entry)
|
||||||
logger.info("setting up persister for device %s", device.name)
|
entry.update(device.name, device.wpid, device.serial, modelId, unitId)
|
||||||
entry = _DeviceEntry()
|
return entry
|
||||||
_config.append(entry)
|
|
||||||
entry.update(device.name, device.wpid, device.serial, modelId, device.unitId)
|
|
||||||
return entry
|
|
||||||
|
|
||||||
|
|
||||||
def attach_to(device):
|
def attach_to(device):
|
||||||
|
|
Loading…
Reference in New Issue