You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: engine C-API's active-engine/callback globals were not thread-local, letting concurrent engines cross-contaminate
Follow-up to verifying an external Tengo-comparison report's concurrency
concern: engine.zig's g_active_engine/write_callback/read_callback and
host_abi.zig's native_host_call_fn/native_host_call_ctx were plain
process-global vars, unlike the 8 internal Runtime.activate()-pinned state
pointers (chunk/globals/heap/vm/tasks/fs/net/http), which are already
threadlocal.
pushEngineState/popEngineState overwrite these 5 fields for the duration
of every engine_run/engine_call. Two threads calling into two different
engines concurrently (an officially-supported pattern per
docs/embedding.md) could interleave those writes, so one engine's script
ran with the other engine's write/read callback, or the other engine's
host-call function paired with the other engine's ctx pointer -- a real
type-confusion hazard, since callbacks @ptrCast/@aligncast that ctx back
to their own expected struct type.
Confirmed with a real two-thread repro (added as a regression test) before
fixing: it reliably produced wrong results and even corrupted an unrelated
later test in the same process. Fixed by making all 5 fields threadlocal.
Verified under standard, -Dpreset=stress, and -Dgc_stress=true builds.
if (argc!=1orargs[0].tag!=@intFromEnum(WireTag.number) or (args[0].flags & host_abi.FLAG_INTEGER) ==0) return@intFromEnum(host_abi.CallStatus.bad_args);
0 commit comments