mirror of
https://github.com/got-feedBack/feedBack-desktop.git
synced 2026-09-11 06:04:10 +00:00
fix(audio): address PR #107 review — close serializer gaps, editor lifetime races, dispatch failures
All 8 CodeRabbit findings verified against the code and fixed: - ChainOps: macOS LoadVST routes its addProcessor through chainMutationMutex (macOS is a first-class platform; deadlock-safe — a worker holding the mutex never waits on the Node/main thread there). All four single-slot workers (LoadVST/NAM/IR/ReplaceIR) now bump chainGeneration so the executor's foreign-write detection sees direct loads, not just presets. - Rebuild barrier (beginChainRebuild/endChainRebuild): LoadPreset and ClearChain arm it before editor teardown; OpenPluginEditor refuses to open while a teardown+clear/rebuild is pending (#56 window between closeAllPluginEditorWindows returning and the worker taking the mutex). - EditorWindows: all slot/processor resolution in editor lambdas runs under a try_lock of chainMutationMutex (try_lock, never blocking — workers holding the mutex block-wait on the message thread). Sandbox promotion bumps chainGeneration. editorWindows map is now message-thread-only (duplicate-window check and close-erase moved into the queued lambdas). Null slot->processor recheck after a faulted promotion capture. - closeAllPluginEditorWindows returns false on refused post / 15s timeout; ClearChain skips the clear and LoadPreset resolves {success:false} instead of freeing processors under a live editor. - AddonContext: dispatchOnMessageThread reports refused-post/timeout; doShutdown leaves the message thread running when teardown didn't complete instead of unloading mid-destruction. - RendererBus::push rejects NaN/Inf/non-positive rates and a step that underflows to zero; new testRejectsUnusableRates unit case. Verified: addon builds clean, all 78 JS tests pass (storm, contracts, executor, N-API fuzz), all 5 engine_units native tests pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
d887c68014
commit
ea8c6a9ccd
@@ -8,6 +8,7 @@
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
using slopsmith::RendererBus;
|
||||
@@ -165,9 +166,35 @@ static void testFlushOnDisable()
|
||||
assert(dl[1] == 7.0f && "post-re-enable audio must be the fresh push");
|
||||
}
|
||||
|
||||
// Rate validation (PR #107 review): non-finite rates cross the JS/IPC
|
||||
// boundary; NaN passes a plain `<= 0` check, and a subnormal source rate can
|
||||
// underflow step to 0 — both must be rejected before the resample loop.
|
||||
// A bad sourceRate falls back to deviceRate (documented behaviour).
|
||||
static void testRejectsUnusableRates()
|
||||
{
|
||||
RendererBus bus;
|
||||
bus.setEnabled(true, 1.0f);
|
||||
const auto chunk = rampChunk(128, 1.0f, 0.0f);
|
||||
const double nan = std::nan("");
|
||||
const double inf = std::numeric_limits<double>::infinity();
|
||||
assert(!bus.push(chunk.data(), 128, 48000.0, nan));
|
||||
assert(!bus.push(chunk.data(), 128, 48000.0, inf));
|
||||
assert(!bus.push(chunk.data(), 128, 48000.0, -48000.0));
|
||||
assert(!bus.push(chunk.data(), 128, 48000.0, 0.0));
|
||||
// step underflow: denormal source over huge device rate → step == 0.
|
||||
assert(!bus.push(chunk.data(), 128, 5e-324, 1e308));
|
||||
assert(bus.metrics().pushedFrames == 0 && "rejected pushes must stage nothing");
|
||||
// NaN/Inf/negative SOURCE rate falls back to deviceRate (step == 1).
|
||||
assert(bus.push(chunk.data(), 128, nan, 48000.0));
|
||||
assert(bus.push(chunk.data(), 128, inf, 48000.0));
|
||||
assert(bus.push(chunk.data(), 128, -1.0, 48000.0));
|
||||
assert(bus.metrics().pushedFrames > 0);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
testEqualRateBitExact();
|
||||
testRejectsUnusableRates();
|
||||
testResampleContinuityAcrossPushes();
|
||||
testPrimeGate();
|
||||
testUnderflowReprimes();
|
||||
|
||||
Reference in New Issue
Block a user