crates/namir-worker/src/submit.rs:81-82
try_submit calls self.lock() (submit.rs:139, a plain Mutex::lock), and submit_with_deadline (:113) holds that same guard across its entire sleep/retry loop until DEFAULT_DEADLINE (2 s).
The doc says "One attempt, never blocks. This is what the UI thread uses", and Instance::try_submit_param (lib.rs:320) repeats it; namir-clap/src/ui_host.rs:189 and namir-app/src/host.rs:420 both cite that claim from the GUI thread.
Scenario: a host deactivates a plugin (ring stops draining, consumer still alive), a worker Instance::load enters the 2 s wait holding the producer mutex, the user moves a knob -- the GUI thread stalls up to 2 s inside a "non-blocking" call. That is the D-15.3 / FR-UI-060 violation namir-clap/src/audio.rs:14-19 explicitly reasons about for the audio thread but never for the GUI thread.
lib.rs:755 try_submit_param_never_blocks_on_a_full_ring is single-threaded and only exercises the full-ring path, never the contended-mutex path -- so the property the doc asserts is checked by nothing.
Fix: try_submit should use producer.try_lock() and return the command on contention.
crates/namir-worker/src/submit.rs:81-82try_submitcallsself.lock()(submit.rs:139, a plainMutex::lock), andsubmit_with_deadline(:113) holds that same guard across its entire sleep/retry loop untilDEFAULT_DEADLINE(2 s).The doc says "One attempt, never blocks. This is what the UI thread uses", and
Instance::try_submit_param(lib.rs:320) repeats it;namir-clap/src/ui_host.rs:189andnamir-app/src/host.rs:420both cite that claim from the GUI thread.Scenario: a host deactivates a plugin (ring stops draining, consumer still alive), a worker
Instance::loadenters the 2 s wait holding the producer mutex, the user moves a knob -- the GUI thread stalls up to 2 s inside a "non-blocking" call. That is the D-15.3 / FR-UI-060 violationnamir-clap/src/audio.rs:14-19explicitly reasons about for the audio thread but never for the GUI thread.lib.rs:755 try_submit_param_never_blocks_on_a_full_ringis single-threaded and only exercises the full-ring path, never the contended-mutex path -- so the property the doc asserts is checked by nothing.Fix:
try_submitshould useproducer.try_lock()and return the command on contention.