diff options
Diffstat (limited to '')
-rw-r--r-- | src/context.c | 69 |
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); |