1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 14:51:16 +02:00

nix_api_expr: switch to refcounting

Remove GCRef, keep references in a map. Change to nix_gc_incref and
nix_gc_decref, where users will mostly use nix_gc_decref.
This commit is contained in:
Yorick van Pelt 2023-07-28 10:49:21 +02:00 committed by José Luis Lafuente
parent bebee700ea
commit ded0ef6f6c
No known key found for this signature in database
GPG key ID: 8A3455EBE455489A
7 changed files with 71 additions and 81 deletions

View file

@ -16,6 +16,7 @@
#include "nix_api_util_internal.h"
#ifdef HAVE_BOEHMGC
#include <mutex>
#define GC_INCLUDE_NEW 1
#include "gc_cpp.h"
#endif
@ -100,27 +101,42 @@ State *nix_state_create(nix_c_context *context, const char **searchPath_c,
void nix_state_free(State *state) { delete state; }
GCRef *nix_gc_ref(nix_c_context *context, void *obj) {
if (context)
context->last_err_code = NIX_OK;
try {
#if HAVE_BOEHMGC
return new (NoGC) GCRef{obj};
#else
return new GCRef{obj};
#endif
#ifdef HAVE_BOEHMGC
std::unordered_map<
const void *, unsigned int, std::hash<const void *>,
std::equal_to<const void *>,
traceable_allocator<std::pair<const void *const, unsigned int>>>
nix_refcounts;
std::mutex nix_refcount_lock;
void nix_gc_incref(const void *p) {
std::scoped_lock lock(nix_refcount_lock);
auto f = nix_refcounts.find(p);
if (f != nix_refcounts.end()) {
f->second++;
} else {
nix_refcounts[p] = 1;
}
NIXC_CATCH_ERRS_NULL
}
void nix_gc_free(GCRef *ref) {
#if HAVE_BOEHMGC
GC_FREE(ref);
#else
delete ref;
#endif
void nix_gc_decref(const void *p) {
std::scoped_lock lock(nix_refcount_lock);
auto f = nix_refcounts.find(p);
if (f != nix_refcounts.end()) {
if (f->second == 1)
nix_refcounts.erase(f);
else
f->second--;
}
// todo: else { throw? }
}
#else
void nix_gc_incref(const void *){};
void nix_gc_decref(const void *){};
#endif
void nix_gc_register_finalizer(void *obj, void *cd,
void (*finalizer)(void *obj, void *cd)) {
#ifdef HAVE_BOEHMGC