mirror of
https://github.com/logos-messaging/nim-ffi.git
synced 2026-05-06 18:29:27 +00:00
protect against mem leag in case of failures sending requests to ffi thread
This commit is contained in:
parent
bb8a3e7e22
commit
c6cbb08de3
@ -60,18 +60,23 @@ proc sendRequestToFFIThread*(
|
||||
## Sending the request
|
||||
let sentOk = ctx.reqChannel.trySend(ffiRequest)
|
||||
if not sentOk:
|
||||
deleteRequest(ffiRequest)
|
||||
return err("Couldn't send a request to the ffi thread")
|
||||
|
||||
let fireSyncRes = ctx.reqSignal.fireSync()
|
||||
if fireSyncRes.isErr():
|
||||
deleteRequest(ffiRequest)
|
||||
return err("failed fireSync: " & $fireSyncRes.error)
|
||||
|
||||
if fireSyncRes.get() == false:
|
||||
deleteRequest(ffiRequest)
|
||||
return err("Couldn't fireSync in time")
|
||||
|
||||
## wait until the FFI working thread properly received the request
|
||||
let res = ctx.reqReceivedSignal.waitSync(timeout)
|
||||
if res.isErr():
|
||||
## Do not free ffiRequest here: the FFI thread was already signaled and
|
||||
## will process (and free) it.
|
||||
return err("Couldn't receive reqReceivedSignal signal")
|
||||
|
||||
## Notice that in case of "ok", the deallocShared(req) is performed by the FFI Thread in the
|
||||
|
||||
@ -6,11 +6,16 @@ import std/[json, macros], results, tables
|
||||
import chronos, chronos/threadsync
|
||||
import ./ffi_types, ./internal/ffi_macro, ./alloc
|
||||
|
||||
type FFIDestroyContentProc* = proc(content: pointer) {.nimcall.}
|
||||
|
||||
type FFIThreadRequest* = object
|
||||
callback: FFICallBack
|
||||
userData: pointer
|
||||
reqId*: cstring
|
||||
reqContent*: pointer
|
||||
deleteReqContent*: FFIDestroyContentProc
|
||||
## Called by sendRequestToFFIThread on failure to free reqContent when
|
||||
## the FFI thread will never process (and thus never free) this request.
|
||||
|
||||
proc init*(
|
||||
T: typedesc[FFIThreadRequest],
|
||||
@ -26,7 +31,9 @@ proc init*(
|
||||
ret[].reqContent = reqContent
|
||||
return ret
|
||||
|
||||
proc deleteRequest(request: ptr FFIThreadRequest) =
|
||||
proc deleteRequest*(request: ptr FFIThreadRequest) =
|
||||
if not request[].deleteReqContent.isNil():
|
||||
request[].deleteReqContent(request[].reqContent)
|
||||
deallocShared(request[].reqId)
|
||||
deallocShared(request)
|
||||
|
||||
|
||||
@ -164,6 +164,9 @@ proc buildFfiNewReqProc(reqTypeName, body: NimNode): NimNode =
|
||||
let typeStr = $T
|
||||
var ret =
|
||||
FFIThreadRequest.init(callback, userData, typeStr.cstring, `reqObjIdent`)
|
||||
proc destroyContent(content: pointer) {.nimcall.} =
|
||||
ffiDeleteReq(cast[ptr `reqTypeName`](content))
|
||||
ret[].deleteReqContent = destroyContent
|
||||
return ret
|
||||
)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user