Skip to content

fix(#298): fix fillet reentrancy in the kernel; drop the serialization lock#308

Merged
gsdali merged 1 commit into
mainfrom
fix/fillet-reentrancy-298
Jul 18, 2026
Merged

fix(#298): fix fillet reentrancy in the kernel; drop the serialization lock#308
gsdali merged 1 commit into
mainfrom
fix/fillet-reentrancy-298

Conversation

@gsdali

@gsdali gsdali commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Completes #298. v1.12.1 stopped the corruption by serialising every 3D fillet/chamfer build behind a bridge mutex (occtFilletMutex); this replaces that with the real kernel fix and removes the lock, so concurrent fillet/chamfer run in parallel again.

Root cause (ThreadSanitizer)

BRepFilletAPI_MakeFillet reconstructs its result solid through OCCT's legacy TopOpeBRepBuild engine (ChFi3d_Builder::ComputeTopOpeBRepBuild_HBuilder::MergeSolidTopOpeBRepBuild_Builder::SplitSolid), which passed state between methods through a file-scope static, STATIC_SOLIDINDEX: SplitSolid sets it to 1/2 to tell FillSolid which operand it is splitting, and FillSolid reads it back to pick the operand shape. Two fillet builds on independent shapes on separate threads clobbered each other's flag, so FillSolid mis-classified faces and returned a wrong-but-plausible solid (one solid, positive volume, fails BRepCheck). This is not the BlendFunc scratch the v1.12.1 notes first suspected — those race benignly.

Fix

  • Scripts/patches/0003 converts the fillet-path statics to thread_local (each thread keeps its own copy; single-thread behaviour unchanged): STATIC_SOLIDINDEX + STATIC_lastVPind (functional), plus BlendFunc_ConstRad/EvolRad + ChFi3d_Builder checkcurve scratch (benign, converted so the path is TSan-clean). Upstreamed as Open-Cascade-SAS/OCCT#1374.
  • xcframework rebuilt with 0003; Package.swift url+checksum bumped to v1.12.3.
  • occtFilletMutex removed (16 bridge guard sites) — the kernel is reentrant now.

Verification

  • Pure-C++ 8-thread stress: 0/1600 concurrent fillet builds invalid with a single correct volume (was ~15–20% corrupt); ThreadSanitizer reports the fillet path clean.
  • Issue298FilletThreadSafetyTests passes with the lock removed; OCCTModelingTests (409), OCCTThreadTests (55) pass against the patched binary.

Binary release — remote SPM consumers pick up the rebuilt lock-free kernel via the new url + checksum.

🤖 Generated with Claude Code

…n lock

The real fix for #298 lands in the pinned OCCT, replacing the v1.12.1 bridge lock.

Root cause (found with ThreadSanitizer): BRepFilletAPI_MakeFillet reconstructs its
result solid via OCCT's legacy TopOpeBRepBuild engine, which passed state between
methods through a file-scope static, STATIC_SOLIDINDEX (SplitSolid sets 1/2,
FillSolid reads it back to pick the operand). Concurrent fillets on independent
shapes clobbered each other's flag, mis-classifying faces -> wrong-but-plausible
solid that fails BRepCheck. NOT the BlendFunc scratch the v1.12.1 notes suspected
(those race benignly).

- Scripts/patches/0003: converts the fillet-path statics to thread_local
  (STATIC_SOLIDINDEX + STATIC_lastVPind functional; BlendFunc_ConstRad/EvolRad and
  ChFi3d_Builder checkcurve scratch benign, for TSan-clean). Upstreamed as
  Open-Cascade-SAS/OCCT#1374.
- xcframework rebuilt with 0003; Package.swift url+checksum bumped to v1.12.3.
- occtFilletMutex and its 16 bridge guard sites removed — fillet/chamfer are
  reentrant in the kernel now, so concurrent builds run in parallel again.
- Issue298FilletThreadSafetyTests kept; passes with the lock removed.

Verified: pure-C++ 8-thread stress 0/1600 invalid (was ~15-20%), TSan-clean on the
fillet path; the Swift regression + Modeling/Thread suites pass against the patched
binary with the lock gone.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gsdali
gsdali merged commit d57721a into main Jul 18, 2026
@gsdali
gsdali deleted the fix/fillet-reentrancy-298 branch July 18, 2026 02:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant