You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
roberth opened this issue
Feb 13, 2025
· 0 comments
Labels
c apiNix as a C library with a stable interfacefeatureFeature request or proposallanguageThe Nix expression language; parser, interpreter, primops, evaluation, etc
Additionally, there does not appear to be any general mechanism to detect when an external value is freed, meaning the user has no clear way to know when to clean up their allocated memory. This leads to the question: Am I just meant to leak my void* v?
Proposed solution
A free callback should be added to NixCExternalValueDesc to allow proper cleanup of void* v when an external value is garbage collected. This would ensure that resources are not leaked unnecessarily.
Implement a mechanism for registering finalizers in mkExternal, so that destructors may be called.
Since Nix uses a conservative garbage collector, finalizers are not always guaranteed to run before process exit. Even so, adding a free callback would improve resource management in most cases. This should be documented.
To ensure correctness, a test utility should be introduced to force finalization, allowing unit tests to verify that the free callback is correctly handled.
Alternative solutions
Document the current behavior explicitly to warn users about potential memory leaks.
Additional context
This issue was initially raised by sodiboo on Matrix. Investigation shows that while ExternalValueBase has a virtual destructor, it is never called because Value relies entirely on GC, and mkExternal does not register a finalizer. This means that external values are never explicitly freed, leading to potential memory leaks.
If Nix were to introduce finalization in the future, it could start invoking code written by C API consumers that has never run before. If finalization is not fully implemented and tested, this could result in unexpected crashes when untested code starts executing. Ensuring that finalization is tested from the start would mitigate this risk.
The text was updated successfully, but these errors were encountered:
roberth
added
c api
Nix as a C library with a stable interface
feature
Feature request or proposal
language
The Nix expression language; parser, interpreter, primops, evaluation, etc
labels
Feb 13, 2025
c apiNix as a C library with a stable interfacefeatureFeature request or proposallanguageThe Nix expression language; parser, interpreter, primops, evaluation, etc
Feature Request: Add Free Callback for
void* v
innix_create_external_value
Is your feature request related to a problem?
Currently, the
nix_create_external_value
API takes avoid* v
argument, which is typically used as user data. While the returnedExternalValue*
is owned by the Nix evaluator, there is no clear mechanism for managing the lifecycle ofvoid* v
. Since Nix cannot free this memory itself, one would expect to see a free callback in[NixCExternalValueDesc](https://hydra.nixos.org/build/289480061/download/1/html/structNixCExternalValueDesc.html#details)
, but no such function exists.Additionally, there does not appear to be any general mechanism to detect when an external value is freed, meaning the user has no clear way to know when to clean up their allocated memory. This leads to the question:
Am I just meant to leak my
void* v
?Proposed solution
A free callback should be added to
NixCExternalValueDesc
to allow proper cleanup ofvoid* v
when an external value is garbage collected. This would ensure that resources are not leaked unnecessarily.Implement a mechanism for registering finalizers in
mkExternal
, so that destructors may be called.Since Nix uses a conservative garbage collector, finalizers are not always guaranteed to run before process exit. Even so, adding a free callback would improve resource management in most cases. This should be documented.
To ensure correctness, a test utility should be introduced to force finalization, allowing unit tests to verify that the free callback is correctly handled.
Alternative solutions
Additional context
This issue was initially raised by sodiboo on Matrix. Investigation shows that while
ExternalValueBase
has a virtual destructor, it is never called becauseValue
relies entirely on GC, andmkExternal
does not register a finalizer. This means that external values are never explicitly freed, leading to potential memory leaks.If Nix were to introduce finalization in the future, it could start invoking code written by C API consumers that has never run before. If finalization is not fully implemented and tested, this could result in unexpected crashes when untested code starts executing. Ensuring that finalization is tested from the start would mitigate this risk.
Add 👍 to issues you find important.
The text was updated successfully, but these errors were encountered: