mirror of
https://github.com/NixOS/nix
synced 2025-06-25 19:01:16 +02:00
nix_api_expr: add error handling to incref, decref
This commit is contained in:
parent
ada2af4f88
commit
866558af34
4 changed files with 43 additions and 26 deletions
|
@ -110,7 +110,10 @@ 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) {
|
||||||
|
if (context)
|
||||||
|
context->last_err_code = NIX_OK;
|
||||||
|
try {
|
||||||
std::scoped_lock lock(nix_refcount_lock);
|
std::scoped_lock lock(nix_refcount_lock);
|
||||||
auto f = nix_refcounts.find(p);
|
auto f = nix_refcounts.find(p);
|
||||||
if (f != nix_refcounts.end()) {
|
if (f != nix_refcounts.end()) {
|
||||||
|
@ -119,24 +122,38 @@ void nix_gc_incref(const void *p) {
|
||||||
nix_refcounts[p] = 1;
|
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) {
|
||||||
|
|
||||||
|
if (context)
|
||||||
|
context->last_err_code = NIX_OK;
|
||||||
|
try {
|
||||||
std::scoped_lock lock(nix_refcount_lock);
|
std::scoped_lock lock(nix_refcount_lock);
|
||||||
auto f = nix_refcounts.find(p);
|
auto f = nix_refcounts.find(p);
|
||||||
if (f != nix_refcounts.end()) {
|
if (f != nix_refcounts.end()) {
|
||||||
if (f->second == 1)
|
if (--f->second == 0)
|
||||||
nix_refcounts.erase(f);
|
nix_refcounts.erase(f);
|
||||||
else
|
} else
|
||||||
f->second--;
|
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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue