fix(drift-trio): phase E — serialized fiber queue (#10a) + fiber-busy probes
runOnFiber now runs bodies strictly one-at-a-time through a park-safe FIFO (collab_common.h): the per-body fire-and-forget coroutine interleaved under load — an asyncify park inside commit.Push let the event loop start the next body, so a local commit and a remote apply ran interleaved on shared state (s_applyingRemote is one global), silently losing applies on the actively- editing receiver (fuzz finding #10a; B now fuzzes clean; 39-test suite green). kicadCollabFiberBusy embind probe (merged + standalone registrations): a bare-embind-stack scratch save during a parked fiber mis-dispatches (table index OOB) — trio.ts modelText/drift and production drift-detect now defer while fiber work is in flight (#10b hardening; the trap's root cause is still open and needs a symbolized stack — fuzz stays fixme'd). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G5cAM9M6q34n5X4dbrfVvi
This commit is contained in:
parent
a5751d8542
commit
3fc90e8fe2
6 changed files with 91 additions and 9 deletions
|
|
@ -322,11 +322,19 @@ export async function closeTrio(trio: Trio): Promise<void> {
|
|||
|
||||
// ── Per-tab probes ───────────────────────────────────────────────────────────
|
||||
|
||||
/** Silent save-to-MEMFS + read back — no onSave side effects. */
|
||||
/** Silent save-to-MEMFS + read back — no onSave side effects. Defers while
|
||||
* collab fiber work is in flight: a bare-embind-stack save during a parked
|
||||
* apply mis-dispatches (finding #10b) — the wait is JS-side, so it is safe. */
|
||||
export function modelText(page: Page, cfg: ToolCfg): Promise<string> {
|
||||
return page.evaluate(
|
||||
({ saveFn, ext }) => {
|
||||
const w = window as unknown as { FS: FSApi; Module: Mod };
|
||||
async ({ saveFn, ext }) => {
|
||||
const w = window as unknown as {
|
||||
FS: FSApi;
|
||||
Module: Mod & { kicadCollabFiberBusy?: () => boolean };
|
||||
};
|
||||
for (let i = 0; i < 200 && w.Module.kicadCollabFiberBusy?.(); i++) {
|
||||
await new Promise((r) => setTimeout(r, 25));
|
||||
}
|
||||
const out = `/home/kicad/documents/_dump.${ext}`;
|
||||
(w.Module[saveFn] as (p: string) => unknown)(out);
|
||||
return w.FS.readFile(out, { encoding: "utf8" });
|
||||
|
|
@ -360,10 +368,14 @@ export interface DriftSummary {
|
|||
/** Item-level drift summary via the production comparator (browser-entry-v2). */
|
||||
export function drift(page: Page, cfg: ToolCfg): Promise<DriftSummary | null> {
|
||||
return page.evaluate(
|
||||
({ saveFn, ext }) => {
|
||||
async ({ saveFn, ext }) => {
|
||||
const w = window as unknown as {
|
||||
KicadCollabV2: { driftReport(f: string, p: string): DriftSummary | null };
|
||||
Module: { kicadCollabFiberBusy?: () => boolean };
|
||||
};
|
||||
for (let i = 0; i < 200 && w.Module.kicadCollabFiberBusy?.(); i++) {
|
||||
await new Promise((r) => setTimeout(r, 25));
|
||||
}
|
||||
return w.KicadCollabV2.driftReport(saveFn, `/home/kicad/documents/_drift.${ext}`);
|
||||
},
|
||||
{ saveFn: cfg.saveFn, ext: cfg.ext },
|
||||
|
|
|
|||
Loading…
Reference in a new issue