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

nix_api_expr: add error handling to incref, decref

This commit is contained in:
Yorick van Pelt 2023-07-28 16:21:29 +02:00 committed by José Luis Lafuente
parent ada2af4f88
commit 866558af34
No known key found for this signature in database
GPG key ID: 8A3455EBE455489A
4 changed files with 43 additions and 26 deletions

View file

@ -110,33 +110,50 @@ std::unordered_map<
std::mutex nix_refcount_lock; std::mutex nix_refcount_lock;
void nix_gc_incref(const void *p) { nix_err nix_gc_incref(nix_c_context *context, const void *p) {
std::scoped_lock lock(nix_refcount_lock); if (context)
auto f = nix_refcounts.find(p); context->last_err_code = NIX_OK;
if (f != nix_refcounts.end()) { try {
f->second++; std::scoped_lock lock(nix_refcount_lock);
} else { auto f = nix_refcounts.find(p);
nix_refcounts[p] = 1; if (f != nix_refcounts.end()) {
f->second++;
} else {
nix_refcounts[p] = 1;
}
} }
NIXC_CATCH_ERRS
} }
void nix_gc_decref(const void *p) { nix_err nix_gc_decref(nix_c_context *context, const void *p) {
std::scoped_lock lock(nix_refcount_lock);
auto f = nix_refcounts.find(p); if (context)
if (f != nix_refcounts.end()) { context->last_err_code = NIX_OK;
if (f->second == 1) try {
nix_refcounts.erase(f); std::scoped_lock lock(nix_refcount_lock);
else auto f = nix_refcounts.find(p);
f->second--; if (f != nix_refcounts.end()) {
if (--f->second == 0)
nix_refcounts.erase(f);
} else
throw std::runtime_error("nix_gc_decref: object was not referenced");
} }
// todo: else { throw? } NIXC_CATCH_ERRS
} }
void nix_gc_now() { GC_gcollect(); } void nix_gc_now() { GC_gcollect(); }
#else #else
void nix_gc_incref(const void *) {} void nix_gc_incref(nix_c_context *context, const void *) {
void nix_gc_decref(const void *) {} if (context)
context->last_err_code = NIX_OK;
return NIX_OK;
}
void nix_gc_decref(nix_c_context *context, const void *) {
if (context)
context->last_err_code = NIX_OK;
return NIX_OK;
}
void nix_gc_now() {} void nix_gc_now() {}
#endif #endif

View file

@ -120,13 +120,13 @@ void nix_state_free(State *state);
* *
* @param[in] object The object to keep alive * @param[in] object The object to keep alive
*/ */
void nix_gc_incref(const void *); nix_err nix_gc_incref(nix_c_context *, const void *);
/** /**
* @brief Decrease the GC refcount * @brief Decrease the GC refcount
* *
* @param[in] object The object to stop referencing * @param[in] object The object to stop referencing
*/ */
void nix_gc_decref(const void *); nix_err nix_gc_decref(nix_c_context *, const void *);
/** /**
* @brief Trigger the garbage collector manually * @brief Trigger the garbage collector manually

View file

@ -178,7 +178,7 @@ ExternalValue *nix_create_external_value(nix_c_context *context,
(GC) (GC)
#endif #endif
NixCExternalValue(*desc, v); NixCExternalValue(*desc, v);
nix_gc_incref(ret); nix_gc_incref(nullptr, ret);
return (ExternalValue *)ret; return (ExternalValue *)ret;
} }
NIXC_CATCH_ERRS_NULL NIXC_CATCH_ERRS_NULL

View file

@ -49,7 +49,7 @@ PrimOp *nix_alloc_primop(nix_c_context *context, PrimOpFun fun, int arity,
if (args) if (args)
for (size_t i = 0; args[i]; i++) for (size_t i = 0; args[i]; i++)
p->args.emplace_back(*args); p->args.emplace_back(*args);
nix_gc_incref(p); nix_gc_incref(nullptr, p);
return (PrimOp *)p; return (PrimOp *)p;
} }
NIXC_CATCH_ERRS_NULL NIXC_CATCH_ERRS_NULL
@ -60,7 +60,7 @@ Value *nix_alloc_value(nix_c_context *context, State *state) {
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
try { try {
Value *res = state->state.allocValue(); Value *res = state->state.allocValue();
nix_gc_incref(res); nix_gc_incref(nullptr, res);
return res; return res;
} }
NIXC_CATCH_ERRS_NULL NIXC_CATCH_ERRS_NULL
@ -208,7 +208,7 @@ Value *nix_get_list_byidx(nix_c_context *context, const Value *value,
auto &v = check_value_not_null(value); auto &v = check_value_not_null(value);
assert(v.type() == nix::nList); assert(v.type() == nix::nList);
auto *p = v.listElems()[ix]; auto *p = v.listElems()[ix];
nix_gc_incref(p); nix_gc_incref(nullptr, p);
return (Value *)p; return (Value *)p;
} }
NIXC_CATCH_ERRS_NULL NIXC_CATCH_ERRS_NULL
@ -224,7 +224,7 @@ Value *nix_get_attr_byname(nix_c_context *context, const Value *value,
nix::Symbol s = state->state.symbols.create(name); nix::Symbol s = state->state.symbols.create(name);
auto attr = v.attrs->get(s); auto attr = v.attrs->get(s);
if (attr) { if (attr) {
nix_gc_incref(attr->value); nix_gc_incref(nullptr, attr->value);
return attr->value; return attr->value;
} }
nix_set_err_msg(context, NIX_ERR_KEY, "missing attribute"); nix_set_err_msg(context, NIX_ERR_KEY, "missing attribute");
@ -257,7 +257,7 @@ Value *nix_get_attr_byidx(nix_c_context *context, const Value *value,
auto &v = check_value_not_null(value); auto &v = check_value_not_null(value);
const nix::Attr &a = (*v.attrs)[i]; const nix::Attr &a = (*v.attrs)[i];
*name = ((const std::string &)(state->state.symbols[a.name])).c_str(); *name = ((const std::string &)(state->state.symbols[a.name])).c_str();
nix_gc_incref(a.value); nix_gc_incref(nullptr, a.value);
return a.value; return a.value;
} }
NIXC_CATCH_ERRS_NULL NIXC_CATCH_ERRS_NULL