pcbjam/learning.md
Viktor Vaczi 51b158f6b1 fix(wasm): Fix Asyncify modal errors with global lock mechanism
Update wxwidgets submodule with fix for consecutive modal dialog crashes.
The fix prevents overlapping Asyncify operations that caused "indirect call
to null" and "func is not a function" errors when a second modal was
triggered immediately after the first one completed.

Also includes:
- docs: Clarify build script order and descriptions in CLAUDE.md
- refactor(test): Remove debug logging from wizard test

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 14:35:08 +01:00

40 lines
1.5 KiB
Markdown

# Learning Notes
## Asyncify and Consecutive Modal Dialogs
### Problem
When multiple modal dialogs are triggered in quick succession, Asyncify operations can overlap causing crashes:
- "indirect call to null"
- "func is not a function"
- "index out of bounds"
### Root Cause
Per Emscripten docs: "It is not safe to start an async operation while another is already running."
When the first modal completes:
1. Asyncify begins rewinding the C++ stack
2. C++ code triggers second modal before rewind completes
3. Second modal's Asyncify operation conflicts with first modal's cleanup
4. Asyncify state corruption occurs
### Key Insight
**You cannot use ANY Asyncify mechanism to wait** - neither `EM_ASYNC_JS` await nor `emscripten_sleep()` - while another Asyncify operation is cleaning up. Both use Asyncify internally and cause the same conflict.
### Solution Pattern
1. Use a **global lock** to track when Asyncify is busy
2. Check lock with **synchronous JS** (`EM_JS`, not `EM_ASYNC_JS`) - this doesn't use Asyncify
3. If locked, **return immediately** instead of waiting
4. Release lock via **double setTimeout(0)** to ensure Asyncify fully completes before allowing new operations
```javascript
// Good: Synchronous check (no Asyncify)
EM_JS(int, isLocked, (), { return Module._locked ? 1 : 0; });
// Bad: This uses Asyncify and will cause conflicts
while (isLocked()) {
emscripten_sleep(10); // Uses Asyncify!
}
```
### File Reference
`wxwidgets/src/wasm/dialog.cpp` - Modal implementation with lock mechanism