fix(windows/cursor): gate the between-session recycle off — calling it from ADD deadlocks
The ADD path holds the manager 'device' mutex, and invalidate_cached_device takes it. Its own doc says it must not be called from inside that mutex. Calling it there deadlocked the session: on .173 the ADD stopped after SET_RENDER_ADAPTER, no monitor was created, and the client reported 'no frames received'. The mechanism itself is sound and measured — recycling the driver's WUDFHost clears the declare (pid 3872 -> 19932, adapter_luid 0x8ed607 -> 0x1a8f6ca, cursor_excluded true -> false, next session streamed normally). What is missing is a call site that runs OUTSIDE that mutex and is still on every session's path; the handshake site tried earlier is not reached on this host. Off unless PUNKTFUNK_CURSOR_RECYCLE=1. A session that self-composites is the old behaviour; a deadlocked one is a regression, and the tree should not carry that while the call site is unsolved.
This commit is contained in:
@@ -910,7 +910,19 @@ impl VdisplayDriver for PfVdisplayDriver {
|
||||
// this monitor is added. The ADD path is the only place guaranteed to see every session
|
||||
// (the handshake call site this replaced sat in a `match (source, compositor)` arm that is
|
||||
// not taken on this host, so it never ran).
|
||||
if !hw_cursor {
|
||||
// ⚠ DISABLED BY DEFAULT — opt in with PUNKTFUNK_CURSOR_RECYCLE=1.
|
||||
//
|
||||
// The MECHANISM is proven (recycling the driver host clears the declare: measured pid
|
||||
// 3872→19932, adapter_luid 0x8ed607→0x1a8f6ca, cursor_excluded true→false, next session
|
||||
// streamed fine). What is NOT solved is calling it from HERE: `invalidate_cached_device`
|
||||
// takes the manager `device` mutex, which this ADD path already holds, so the session
|
||||
// DEADLOCKS — observed on .173, the ADD stops after SET_RENDER_ADAPTER and the client gets
|
||||
// "no frames received". Its own doc warns about exactly this.
|
||||
//
|
||||
// The fix is a call site that runs OUTSIDE the mutex and still on every session's path;
|
||||
// the handshake site tried before is not reached on this host. Until then this stays off:
|
||||
// a session that self-composites is the old behaviour, a deadlocked one is a regression.
|
||||
if !hw_cursor && std::env::var("PUNKTFUNK_CURSOR_RECYCLE").is_ok_and(|v| v == "1") {
|
||||
clean_cursor_for_next_session(false);
|
||||
}
|
||||
let session_id = next_session_id();
|
||||
|
||||
Reference in New Issue
Block a user