Undo-block review fixes: exception-safe depth, corrected docs, real test teeth

Fixes ctor exception safety, a ValidatePtr2 guard, false SDK-citation and
enforcement claims, the span-depth invariant, and vacuous fx_reclaim tests.
This commit is contained in:
2026-08-07 17:07:56 -04:00
parent b7b93a7ac3
commit 3d95eb715c
8 changed files with 126 additions and 38 deletions
+26 -14
View File
@@ -1478,7 +1478,19 @@ static void testNoTerminatorLeavesTheSpanOpenWithTheLoopAsleep() {
// 2. The state-load terminator. `abandon` is the one move that clears the wakeup with
// work still owed, which is what makes the close-FIRST ordering load-bearing rather
// than tidy — reverse the two and the loop is asleep under an open block.
// than tidy. Proved both ways, not asserted by construction: the WRONG order below
// (abandon, then close) is caught mid-sequence by the same predicate the RIGHT order
// is checked against — swapping the two lines here would make the first CHECK below
// fail, which is the teeth `fxReclaimAbandonForStateLoad` closing FIRST relies on.
{
FxReclaimQueue q;
UndoSpan span;
q.invalidate();
span.begin(kProjA, "ReaSampler: activate Design view", 9);
q.abandon(); // WRONG order: wakeup cleared before the span closes
CHECK(asleepWithTheSpanOpen(q, span)); // the exact leak the real order avoids
span.end();
}
{
FxReclaimQueue q;
UndoSpan span;
@@ -1492,8 +1504,13 @@ static void testNoTerminatorLeavesTheSpanOpenWithTheLoopAsleep() {
// 3. The project moving out from under the span. No active project sleeps the loop
// (beginTick's nullptr arm), a tab switch does not — but both close, because the
// span is keyed on its OWN project and neither one is it.
for (ReaProject* arrived : {static_cast<ReaProject*>(nullptr), kProjB}) {
// span is keyed on its OWN project and neither one is it. kProjA is the control: a
// tick landing back on the SAME project must NOT close the span, or a live switch's
// block would drop the flags-and-items mask it opened with mid-drain. Sweeping all
// three, with a branch-dependent CHECK, is what gives the guard real teeth — the
// original two-value sweep always took the close branch, so the no-close branch was
// never exercised.
for (ReaProject* arrived : {kProjA, static_cast<ReaProject*>(nullptr), kProjB}) {
FxReclaimQueue q;
UndoSpan span;
q.invalidate();
@@ -1503,21 +1520,16 @@ static void testNoTerminatorLeavesTheSpanOpenWithTheLoopAsleep() {
if (span.project() != arrived) span.end();
q.beginTick(arrived);
CHECK(!span.open());
if (arrived == kProjA) CHECK(span.open()); // same project: nothing to close
else CHECK(!span.open());
CHECK(!asleepWithTheSpanOpen(q, span));
}
// 4. The terminators with no queue move at all — a project save, an extension unload,
// the next real switch superseding. Each is the idempotent close alone, so the
// wakeup is whatever it already was; the implication has to hold either way.
for (bool woken : {false, true}) {
FxReclaimQueue q;
UndoSpan span;
if (woken) q.invalidate();
span.begin(kProjA, "ReaSampler: activate Design view", 9);
span.end();
CHECK(!asleepWithTheSpanOpen(q, span));
}
// the next real switch superseding. Each is the idempotent close alone, with no
// guard and nothing else to sweep, so it reduces to end()'s own idempotency
// (testTheSpanOpensOnceAndClosesOnceHoweverManyTimesItIsAsked) rather than adding a
// separate claim here.
}
int main() {