mirror of
https://github.com/logos-messaging/nim-ffi.git
synced 2026-06-26 11:20:09 +00:00
fix(pool): deinit context resources in full teardown
destroyFFIContext stopped/joined the worker threads and marked the slot for rebuild, but no longer deinited the context — so the six ThreadSignalPtr fds were orphaned every full teardown (the exact leak this path exists to prevent), and the still-initialised Lock + event registry/queue locks were left live. createFFIContext's rebuild path (initialized == false) reruns initContextResources, which calls initLock / initEventRegistry / initEventQueue and installs fresh signals over the stale handles — re-initialising a live lock is UB. Restore the deinitContextResources() call (as the pre-recycle code did) before marking the slot uninitialised so the rebuild starts from clean state. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
6bc626946e
commit
79e5dc64c6
@ -50,11 +50,19 @@ proc destroyFFIContext*[T](
|
||||
## for process/pool shutdown — normal destruction uses releaseFFIContext.
|
||||
ctx.stopAndJoinThreads().isOkOr:
|
||||
return err("destroyFFIContext(pool): " & $error)
|
||||
# Close the ThreadSignalPtr fds and deinit the lock + event registry/queue
|
||||
# BEFORE the slot is marked for rebuild. createFFIContext's rebuild path reruns
|
||||
# initContextResources (initLock / initEventRegistry / initEventQueue + fresh
|
||||
# signals); skipping deinit here would re-init still-live locks (UB) and orphan
|
||||
# the old fds — the very leak this teardown exists to prevent.
|
||||
let deinitRes = ctx.deinitContextResources()
|
||||
for i in 0 ..< MaxFFIContexts:
|
||||
if pool.contexts[i].addr == ctx:
|
||||
pool.initialized[i].store(false)
|
||||
break
|
||||
ctx.release()
|
||||
deinitRes.isOkOr:
|
||||
return err("destroyFFIContext(pool): " & $error)
|
||||
return ok()
|
||||
|
||||
proc isValidCtx*[T](pool: var FFIContextPool[T], ctx: pointer): bool =
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user