avoid finalizer, may destabilize the GC (#28)
forgot about https://github.com/nim-lang/Nim/issues/4851 when writing it generally, will only be a problem if threads are created and destroyed often
This commit is contained in:
parent
a9d5cba699
commit
af9611c187
|
@ -88,7 +88,7 @@ type
|
||||||
## Representation of recoverable signature.
|
## Representation of recoverable signature.
|
||||||
data: secp256k1_ecdsa_recoverable_signature
|
data: secp256k1_ecdsa_recoverable_signature
|
||||||
|
|
||||||
SkContext* = ref object
|
SkContext = object
|
||||||
## Representation of Secp256k1 context object.
|
## Representation of Secp256k1 context object.
|
||||||
context: ptr secp256k1_context
|
context: ptr secp256k1_context
|
||||||
|
|
||||||
|
@ -132,14 +132,21 @@ template ptr0(v: array|openArray): ptr cuchar =
|
||||||
template ptr0(v: SkMessage): ptr cuchar =
|
template ptr0(v: SkMessage): ptr cuchar =
|
||||||
ptr0(distinctBase(v))
|
ptr0(distinctBase(v))
|
||||||
|
|
||||||
func shutdownLibsecp256k1(ctx: SkContext) =
|
proc releaseThread*(T: type SkContext): T =
|
||||||
# TODO: use destructor when finalizer are deprecated for destructors
|
if not isNil(secpContext.context):
|
||||||
if not(isNil(ctx.context)):
|
secp256k1_context_destroy(secpContext.context)
|
||||||
secp256k1_context_destroy(ctx.context)
|
secpContext.context = nil
|
||||||
|
|
||||||
proc newSkContext(): SkContext =
|
proc init(T: type SkContext): T =
|
||||||
## Create new Secp256k1 context object.
|
## Create new Secp256k1 context object - when no longer needed, it should be
|
||||||
new(result, shutdownLibsecp256k1)
|
## destroyed
|
||||||
|
|
||||||
|
# TODO We _should_ release the context on thread shutdown but there's no
|
||||||
|
# reliable way to do that short of doing it manually, which the code is
|
||||||
|
# not really prepared for - unfortunately, nim finalizers are broken:
|
||||||
|
# https://github.com/nim-lang/Nim/issues/4851
|
||||||
|
# A workaround is to call SkContext.releaseThread() on thread end - this
|
||||||
|
# will become a no-op when the issue is fixed
|
||||||
let flags = cuint(SECP256K1_CONTEXT_VERIFY or SECP256K1_CONTEXT_SIGN)
|
let flags = cuint(SECP256K1_CONTEXT_VERIFY or SECP256K1_CONTEXT_SIGN)
|
||||||
result.context = secp256k1_context_create(flags)
|
result.context = secp256k1_context_create(flags)
|
||||||
secp256k1_context_set_illegal_callback(
|
secp256k1_context_set_illegal_callback(
|
||||||
|
@ -156,8 +163,8 @@ func getContext(): ptr secp256k1_context =
|
||||||
# Technically, it should be possible to precompute a static context
|
# Technically, it should be possible to precompute a static context
|
||||||
# at compile time and use that instead, which would turn this into
|
# at compile time and use that instead, which would turn this into
|
||||||
# a truly side-effect-free function, instead of an as-if-free one.
|
# a truly side-effect-free function, instead of an as-if-free one.
|
||||||
if isNil(secpContext):
|
if isNil(secpContext.context):
|
||||||
secpContext = newSkContext()
|
secpContext = SkContext.init()
|
||||||
secpContext.context
|
secpContext.context
|
||||||
|
|
||||||
func fromHex*(T: type seq[byte], s: string): SkResult[T] =
|
func fromHex*(T: type seq[byte], s: string): SkResult[T] =
|
||||||
|
|
Loading…
Reference in New Issue