ui: nonblocking Params writes (#37982)

ui: nonblocking writes for ExperimentalMode + DriverView toggles + cycle-restart

All four put calls fire from the main render thread on user interaction
and block on disk fsync, causing visible UI frame spikes.

Each consumer is safe under nonblocking:
- onboarding inactivity_callback: write-and-forget (~25 ms saved)
- home long-press exp toggle: ui_state.experimental_mode owns visual state (~10 ms)
- onroad exp_button: $held_mode + selfdriveState owns visual state
- restart_needed_callback (OnroadCycleRequested): cross-process signal,
  consumer is selfdrived which polls the param

BigParamControl-driven toggles in settings (developer.py, toggles.py)
are intentionally left blocking — those widgets refresh visual state
from disk every frame to mirror external changes, which would race a
nonblocking write.
This commit is contained in:
Shane Smiskol
2026-05-07 23:34:53 -07:00
committed by GitHub
parent 01e7606b70
commit 32671d1c3f
4 changed files with 5 additions and 5 deletions
+1 -1
View File
@@ -2,4 +2,4 @@ from openpilot.selfdrive.ui.ui_state import ui_state
def restart_needed_callback(_=None):
ui_state.params.put_bool("OnroadCycleRequested", True)
ui_state.params.put_bool_nonblocking("OnroadCycleRequested", True)
+1 -1
View File
@@ -109,7 +109,7 @@ class TrainingGuideDMTutorial(NavWidget):
# Disable driver monitoring model when device times out for inactivity
def inactivity_callback():
ui_state.params.put_bool("IsDriverViewEnabled", False)
ui_state.params.put_bool_nonblocking("IsDriverViewEnabled", False)
device.add_interactive_timeout_callback(inactivity_callback)
@@ -41,7 +41,7 @@ class BaseDriverCameraDialog(Widget):
def show_event(self):
super().show_event()
ui_state.params.put_bool("IsDriverViewEnabled", True)
ui_state.params.put_bool_nonblocking("IsDriverViewEnabled", True)
self._publish_alert_sound(None)
device.set_override_interactive_timeout(300)
ui_state.params.remove("DriverTooDistracted")
@@ -49,7 +49,7 @@ class BaseDriverCameraDialog(Widget):
def hide_event(self):
super().hide_event()
ui_state.params.put_bool("IsDriverViewEnabled", False)
ui_state.params.put_bool_nonblocking("IsDriverViewEnabled", False)
device.set_override_interactive_timeout(None)
def _handle_mouse_release(self, _):
+1 -1
View File
@@ -36,7 +36,7 @@ class ExpButton(Widget):
super()._handle_mouse_release(_)
if self._is_toggle_allowed():
new_mode = not self._experimental_mode
self._params.put_bool("ExperimentalMode", new_mode)
self._params.put_bool_nonblocking("ExperimentalMode", new_mode)
# Hold new state temporarily
self._held_mode = new_mode