fix: set up foreign-thread GC in event-listener entry points

sds_add_event_listener / sds_remove_event_listener run on the foreign
caller thread and allocate Nim memory ($eventName, the listener registry
Table+seq), but unlike the ctor/dtor they never called initializeLibrary.
A foreign host (Go) migrates goroutines across OS threads, so the thread
running add_event_listener may not be the one that ran a prior entry
point; without setupForeignThreadGc its per-thread allocator region is
uninitialised and the first Nim allocation faults in the allocator.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Ivan FB 2026-06-19 23:26:43 +02:00
parent 021f469041
commit a6b22fc6df
No known key found for this signature in database
GPG Key ID: DF0C67A04C543270

View File

@ -147,6 +147,12 @@ macro declareLibrary*(libraryName: static[string], libType: untyped): untyped =
let addName = libraryName & "_add_event_listener"
let addErr = "error: invalid context in " & addName
let addBody = quote:
# Runs on the foreign caller thread, which may not be the one that ran a
# prior entry point: initialize this thread's GC before any Nim allocation
# ($eventName / the registry Table+seq), else the per-thread allocator
# region is uninitialized and faults.
when declared(initializeLibrary):
initializeLibrary()
var ret: uint64 = 0
if isNil(ctx):
echo `addErr`
@ -181,6 +187,8 @@ macro declareLibrary*(libraryName: static[string], libType: untyped): untyped =
let removeName = libraryName & "_remove_event_listener"
let removeErr = "error: invalid context in " & removeName
let removeBody = quote:
when declared(initializeLibrary):
initializeLibrary()
var ret: cint = 1
if isNil(ctx):
echo `removeErr`