Skip to content

Commit 1f73c89

Browse files
committed
Ignore stale scan worker signals
Add sender() checks and debug logs to scan-related handlers so signals from old/stale scan workers are ignored. Update _is_scan_running to also consider the worker's isRunning() state. Only call _finish_scan("cancel") when there is no active worker to avoid prematurely finishing cancellation. These changes reduce race conditions when restarting/canceling camera scans and ensure UI reflects the current worker's state.
1 parent 4865edb commit 1f73c89

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

dlclivegui/gui/camera_config/camera_config_dialog.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,10 @@ def _on_backend_changed(self, _index: int) -> None:
457457
self._refresh_available_cameras()
458458

459459
def _is_scan_running(self) -> bool:
460-
return self._scan_state in (CameraScanState.RUNNING, CameraScanState.CANCELING)
460+
if self._scan_state in (CameraScanState.RUNNING, CameraScanState.CANCELING):
461+
return True
462+
w = self._scan_worker
463+
return bool(w and w.isRunning())
461464

462465
def _set_scan_state(self, state: CameraScanState, message: str | None = None) -> None:
463466
"""Single source of truth for scan-related UI controls."""
@@ -539,11 +542,17 @@ def _refresh_available_cameras(self) -> None:
539542
w.start()
540543

541544
def _on_scan_progress(self, msg: str) -> None:
545+
if self.sender() is not self._scan_worker:
546+
LOGGER.debug("[Scan] Ignoring progress from old worker: %s", msg)
547+
return
542548
if self._scan_state not in (CameraScanState.RUNNING, CameraScanState.CANCELING):
543549
return
544550
self._show_scan_overlay(msg or "Discovering cameras…")
545551

546552
def _on_scan_result(self, cams: list) -> None:
553+
if self.sender() is not self._scan_worker:
554+
LOGGER.debug("[Scan] Ignoring result from old worker: %d cameras", len(cams) if cams else 0)
555+
return
547556
if self._scan_state not in (CameraScanState.RUNNING, CameraScanState.CANCELING):
548557
return
549558

@@ -566,6 +575,9 @@ def _on_scan_result(self, cams: list) -> None:
566575
self._finish_scan("result")
567576

568577
def _on_scan_error(self, msg: str) -> None:
578+
if self.sender() is not self._scan_worker:
579+
LOGGER.debug("[Scan] Ignoring error from old worker: %s", msg)
580+
return
569581
if self._scan_state not in (CameraScanState.RUNNING, CameraScanState.CANCELING):
570582
return
571583

@@ -598,9 +610,13 @@ def request_scan_cancel(self) -> None:
598610
placeholder.setFlags(Qt.ItemIsEnabled)
599611
self.available_cameras_list.addItem(placeholder)
600612

601-
self._finish_scan("cancel")
613+
if w is None or not w.isRunning():
614+
self._finish_scan("cancel")
602615

603616
def _on_scan_canceled(self) -> None:
617+
if self.sender() is not self._scan_worker:
618+
LOGGER.debug("[Scan] Ignoring canceled signal from old worker.")
619+
return
604620
self._set_scan_state(CameraScanState.CANCELING, message="Finalizing cancellation…")
605621
# If cancel is requested without clicking cancel (e.g., dialog closing), ensure UI finishes
606622
if self._scan_state in (CameraScanState.RUNNING, CameraScanState.CANCELING):

0 commit comments

Comments
 (0)