summaryrefslogtreecommitdiffstats
path: root/src/context.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/context.c')
-rw-r--r--src/context.c69
1 files changed, 63 insertions, 6 deletions
diff --git a/src/context.c b/src/context.c
index 47e63d4..7a14203 100644
--- a/src/context.c
+++ b/src/context.c
@@ -4,7 +4,7 @@
* @author Michal Vasko <mvasko@cesnet.cz>
* @brief Context implementations
*
- * Copyright (c) 2015 - 2021 CESNET, z.s.p.o.
+ * Copyright (c) 2015 - 2023 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
@@ -228,6 +228,17 @@ cleanup:
return mod;
}
+/**
+ * @brief Hash table value-equal callback for comparing context error hash table record.
+ */
+static ly_bool
+ly_ctx_ht_err_equal_cb(void *val1_p, void *val2_p, ly_bool UNUSED(mod), void *UNUSED(cb_data))
+{
+ struct ly_ctx_err_rec *err1 = val1_p, *err2 = val2_p;
+
+ return !memcmp(&err1->tid, &err2->tid, sizeof err1->tid);
+}
+
LIBYANG_API_DEF LY_ERR
ly_ctx_new(const char *search_dir, uint16_t options, struct ly_ctx **new_ctx)
{
@@ -251,8 +262,9 @@ ly_ctx_new(const char *search_dir, uint16_t options, struct ly_ctx **new_ctx)
/* plugins */
LY_CHECK_ERR_GOTO(lyplg_init(), LOGINT(NULL); rc = LY_EINT, cleanup);
- /* initialize thread-specific keys */
- while ((pthread_key_create(&ctx->errlist_key, ly_err_free)) == EAGAIN) {}
+ /* initialize thread-specific error hash table */
+ ctx->err_ht = lyht_new(1, sizeof(struct ly_ctx_err_rec), ly_ctx_ht_err_equal_cb, NULL, 1);
+ LY_CHECK_ERR_GOTO(!ctx->err_ht, rc = LY_EMEM, cleanup);
/* init LYB hash lock */
pthread_mutex_init(&ctx->lyb_hash_lock, NULL);
@@ -657,6 +669,39 @@ ly_ctx_get_change_count(const struct ly_ctx *ctx)
return ctx->change_count;
}
+LIBYANG_API_DEF uint32_t
+ly_ctx_get_modules_hash(const struct ly_ctx *ctx)
+{
+ const struct lys_module *mod;
+ uint32_t i = ly_ctx_internal_modules_count(ctx), hash = 0, fi = 0;
+ struct lysp_feature *f = NULL;
+
+ LY_CHECK_ARG_RET(ctx, ctx, 0);
+
+ while ((mod = ly_ctx_get_module_iter(ctx, &i))) {
+ /* name */
+ hash = lyht_hash_multi(hash, mod->name, strlen(mod->name));
+
+ /* revision */
+ if (mod->revision) {
+ hash = lyht_hash_multi(hash, mod->revision, strlen(mod->revision));
+ }
+
+ /* enabled features */
+ while ((f = lysp_feature_next(f, mod->parsed, &fi))) {
+ if (f->flags & LYS_FENABLED) {
+ hash = lyht_hash_multi(hash, f->name, strlen(f->name));
+ }
+ }
+
+ /* imported/implemented */
+ hash = lyht_hash_multi(hash, (char *)&mod->implemented, sizeof mod->implemented);
+ }
+
+ hash = lyht_hash_multi(hash, NULL, 0);
+ return hash;
+}
+
LIBYANG_API_DEF ly_module_imp_clb
ly_ctx_get_module_imp_clb(const struct ly_ctx *ctx, void **user_data)
{
@@ -1228,6 +1273,19 @@ error:
return ret;
}
+/**
+ * @brief Callback for freeing context error hash table values.
+ *
+ * @param[in] val_p Pointer to a pointer to an error item to free with all the siblings.
+ */
+static void
+ly_ctx_ht_err_rec_free(void *val_p)
+{
+ struct ly_ctx_err_rec *err = val_p;
+
+ ly_err_free(err->err);
+}
+
LIBYANG_API_DEF void
ly_ctx_destroy(struct ly_ctx *ctx)
{
@@ -1260,9 +1318,8 @@ ly_ctx_destroy(struct ly_ctx *ctx)
/* leftover unres */
lys_unres_glob_erase(&ctx->unres);
- /* clean the error list */
- ly_err_clean(ctx, 0);
- pthread_key_delete(ctx->errlist_key);
+ /* clean the error hash table */
+ lyht_free(ctx->err_ht, ly_ctx_ht_err_rec_free);
/* dictionary */
lydict_clean(&ctx->dict);