mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-07 21:11:05 +03:00
fix(wayland): back off the polling display lookups after a failure (drm) (#15865)
* fix(wayland): back off the polling display lookups after a failure (drm) In drm builds an enumeration that fails with no endpoint named in the environment falls back to the socket probe, which forks a child bounded by seconds, and the display service asks again every 300 ms -- at a greeter with no reachable compositor that is a probe child per turn, forever. Such a failure now stamps a shared 5 s backoff, and only the polling callers honor it: the 300 ms displays-changed check skips its turn and the 1.5 s live layout poll returns no answer for that turn. Only the failure that would fork stamps. A session server is spawned with WAYLAND_DISPLAY set, so its failed connect bails in-process before any fork; stamping there would buy nothing and cost recovery latency, so live sessions keep master's behavior exactly. The stamp also survives clear_wayland_displays_cache: it describes the seat, not the cache, and the ~1/s capturer rebuild loop clears on every teardown -- dropping the stamp with the cache would let that loop defeat the backoff and would turn every post-hotplug failure into a "first" one forever. The displays-changed check weighs the backoff against what is already published. With nothing synced yet it always populates -- an unaugmented DRM list beats the empty broadcast the send path would otherwise emit. With a synced layout, a suppressed turn keeps it, and a fresh first failure keeps it too; only a failure that persists across a backoff replaces it with the DRM stack, so a hotplug at a failing seat converges within one backoff while a transient failure never tears down a good layout. One-shot callers -- session init, pipewire stream setup, capturer info -- keep probing fresh through get_displays, whose failure semantics are unchanged: replaying a transient failure there would latch an empty answer into session-long state. Non-drm builds compile none of this. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(wayland): log DRM lookup failure once * fix(wayland): reset lookup warning after recovery --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -346,8 +346,21 @@ fn check_get_displays_changed_msg() -> Option<Message> {
|
||||
// list that overwrites the login peer-info displays and the client shows "No displays".
|
||||
#[cfg(feature = "drm")]
|
||||
if super::drm_capturer::is_available_cached() {
|
||||
if let Some(displays) = super::drm_capturer::get_display_infos() {
|
||||
SYNC_DISPLAYS.lock().unwrap().check_changed(&displays);
|
||||
let synced = !SYNC_DISPLAYS.lock().unwrap().displays.is_empty();
|
||||
let stamped_before = scrap::wayland::display::wayland_failure_stamped();
|
||||
// With nothing published yet, even the unaugmented DRM list beats the empty
|
||||
// broadcast below; with a synced layout, a suppressed turn keeps it instead.
|
||||
if !synced || !scrap::wayland::display::wayland_lookup_suppressed() {
|
||||
if let Some(displays) = super::drm_capturer::get_display_infos() {
|
||||
// A first failure keeps the synced layout for one backoff; only a
|
||||
// failure that persists across one replaces it with the DRM stack.
|
||||
if !synced
|
||||
|| stamped_before
|
||||
|| !scrap::wayland::display::wayland_lookup_suppressed()
|
||||
{
|
||||
SYNC_DISPLAYS.lock().unwrap().check_changed(&displays);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return get_displays_msg();
|
||||
|
||||
Reference in New Issue
Block a user