fix(audio): route device probing through the message thread; document timeout desync

Review follow-up (PR #113, finding 1): ProbeDeviceOptions constructs and
destroys short-lived ASIO device objects (DeviceSetup::probeDual /
rateSupportedBy createDevice) on the Node thread - the same
create/destroy-off-the-message-thread pattern as the lifecycle ops, and a
probe ASIOAudioIODevice owns the same reset-timer machinery. Wrap it in
runDeviceLifecycleOp for consistency.

Finding 2 (timeout desync - op reported failed may still complete late)
is documented as a known limitation on the helper.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
OmikronApex
2026-07-16 23:45:29 +02:00
co-authored by Claude Fable 5
parent aa0bb9d173
commit 895d0af969
2 changed files with 26 additions and 3 deletions
+8
View File
@@ -80,6 +80,14 @@ inline bool dispatchOnMessageThread(Func&& func)
// closure must own everything it touches — capture by value (engine
// snapshot, args) and write results through a shared_ptr, never through
// references to the caller's stack.
//
// KNOWN LIMITATION (timeout desync): when the 15 s wait expires the binding
// reports failure to JS, but the closure may still complete afterwards —
// e.g. addSource returns -1 yet the source gets created, holding its input
// device until the next reconfigure. Memory-safe by the capture rule above,
// just not logically reconciled; only reachable with the message thread
// jammed > 15 s. Callers that care can re-query engine state (listSources,
// getCurrentDevice) after a reported failure.
template <typename Func>
inline bool runDeviceLifecycleOp(Func&& func)
{