From a6b22fc6dfa43d8ae71a5b53fd7e7a0543cc7f6e Mon Sep 17 00:00:00 2001 From: Ivan FB Date: Fri, 19 Jun 2026 23:26:43 +0200 Subject: [PATCH] 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 --- ffi/internal/ffi_library.nim | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ffi/internal/ffi_library.nim b/ffi/internal/ffi_library.nim index e0e00e8..e43ec87 100644 --- a/ffi/internal/ffi_library.nim +++ b/ffi/internal/ffi_library.nim @@ -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`