Skip to content

Commit 12d0058

Browse files
committed
context UPDATE differentiate priv/shared ctx data
1 parent 9a82ba0 commit 12d0058

File tree

11 files changed

+273
-300
lines changed

11 files changed

+273
-300
lines changed

src/context.c

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ LIBYANG_API_DEF LY_ERR
614614
ly_ctx_set_options(struct ly_ctx *ctx, uint32_t option)
615615
{
616616
LY_ERR lyrc = LY_SUCCESS;
617-
struct ly_ctx_data *ctx_data;
617+
struct ly_ctx_private_data *ctx_data;
618618
struct lys_module *mod;
619619
uint32_t i;
620620

@@ -637,7 +637,7 @@ ly_ctx_set_options(struct ly_ctx *ctx, uint32_t option)
637637
}
638638

639639
if (!(ctx->opts & LY_CTX_LEAFREF_LINKING) && (option & LY_CTX_LEAFREF_LINKING)) {
640-
ctx_data = ly_ctx_data_get(ctx);
640+
ctx_data = ly_ctx_private_data_get(ctx);
641641
ctx_data->leafref_links_ht = lyht_new(1, sizeof(struct lyd_leafref_links_rec *), ly_ctx_ht_leafref_links_equal_cb, NULL, 1);
642642
LY_CHECK_ERR_RET(!ctx_data->leafref_links_ht, LOGARG(ctx, option), LY_EMEM);
643643
}
@@ -699,13 +699,13 @@ ly_ctx_unset_options(struct ly_ctx *ctx, uint32_t option)
699699
LY_ARRAY_COUNT_TYPE u, v;
700700
const struct lysc_ext_instance *ext;
701701
struct lysc_node *root;
702-
struct ly_ctx_data *ctx_data;
702+
struct ly_ctx_private_data *ctx_data;
703703

704704
LY_CHECK_ARG_RET(ctx, ctx, !(ctx->opts & LY_CTX_INT_IMMUTABLE), LY_EINVAL);
705705
LY_CHECK_ERR_RET(option & LY_CTX_NO_YANGLIBRARY, LOGARG(ctx, option), LY_EINVAL);
706706

707707
if ((ctx->opts & LY_CTX_LEAFREF_LINKING) && (option & LY_CTX_LEAFREF_LINKING)) {
708-
ctx_data = ly_ctx_data_get(ctx);
708+
ctx_data = ly_ctx_private_data_get(ctx);
709709
lyht_free(ctx_data->leafref_links_ht, ly_ctx_ht_leafref_links_rec_free);
710710
ctx_data->leafref_links_ht = NULL;
711711
}
@@ -828,12 +828,12 @@ ly_ctx_set_module_imp_clb(struct ly_ctx *ctx, ly_module_imp_clb clb, void *user_
828828
LIBYANG_API_DEF ly_ext_data_clb
829829
ly_ctx_set_ext_data_clb(const struct ly_ctx *ctx, ly_ext_data_clb clb, void *user_data)
830830
{
831-
struct ly_ctx_data *ctx_data;
831+
struct ly_ctx_private_data *ctx_data;
832832
ly_ext_data_clb prev;
833833

834834
LY_CHECK_ARG_RET(ctx, ctx, NULL);
835835

836-
ctx_data = ly_ctx_data_get(ctx);
836+
ctx_data = ly_ctx_private_data_get(ctx);
837837
prev = ctx_data->ext_clb;
838838
ctx_data->ext_clb = clb;
839839
ctx_data->ext_clb_data = user_data;
@@ -1466,7 +1466,10 @@ ly_ctx_new_printed(const void *mem, struct ly_ctx **ctx)
14661466

14671467
cleanup:
14681468
if (rc) {
1469-
ly_ctx_data_del(*ctx);
1469+
if (rc != LY_EEXIST) {
1470+
/* do not free another context's data */
1471+
ly_ctx_data_del(*ctx);
1472+
}
14701473
*ctx = NULL;
14711474
}
14721475
return rc;
@@ -1495,15 +1498,6 @@ ly_ctx_destroy(struct ly_ctx *ctx)
14951498
return;
14961499
}
14971500

1498-
/* check if this is the last instance of the context */
1499-
if (ly_ctx_data_refcount_get(ctx) > 1) {
1500-
/* not the last instance, just decrease the ctx and plg reference counts,
1501-
* since other instances might still be using parsed, compiled, and other data */
1502-
ly_ctx_data_del(ctx);
1503-
lyplg_clean();
1504-
return;
1505-
}
1506-
15071501
/* free the parsed and compiled modules (both can reference ext instances, which need to be freed, so their
15081502
* definitions can be freed) */
15091503
for (i = 0; i < ctx->modules.count; ++i) {

src/context.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,9 @@ LIBYANG_API_DECL LY_ERR ly_ctx_compiled_print(const struct ly_ctx *ctx, void *me
693693
/**
694694
* @brief Create a (immutable) context that was printed into a memory chunk.
695695
*
696+
* This function allows a given thread to create only one printed context at a particular memory address at any time.
697+
* Another thread, however, may create a separate context at the same address.
698+
*
696699
* @param[in] mem Memory to use.
697700
* @param[out] ctx Created immutable context.
698701
* @return LY_ERR value.

src/log.c

Lines changed: 36 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -176,100 +176,46 @@ ly_err_new(struct ly_err_item **err, LY_ERR ecode, LY_VECODE vecode, char *data_
176176
return e->err;
177177
}
178178

179-
static struct ly_ctx_data_err *
180-
ly_err_data_get(const struct ly_ctx *ctx)
181-
{
182-
struct ly_ctx_data *ctx_data;
183-
pthread_t tid = pthread_self();
184-
uint32_t i;
185-
struct ly_ctx_data_err *data_err = NULL;
186-
187-
/* get context data */
188-
ctx_data = ly_ctx_data_get(ctx);
189-
190-
/* ERR READ LOCK */
191-
pthread_rwlock_rdlock(&ctx_data->err_rwlock);
192-
193-
/* find the thread-specific err */
194-
for (i = 0; i < ctx_data->err_count; ++i) {
195-
if (!memcmp(&ctx_data->errs[i]->tid, &tid, sizeof tid)) {
196-
data_err = ctx_data->errs[i];
197-
goto cleanup;
198-
}
199-
}
200-
201-
/* ERR UNLOCK */
202-
pthread_rwlock_unlock(&ctx_data->err_rwlock);
203-
204-
/* ERR WRITE LOCK */
205-
pthread_rwlock_wrlock(&ctx_data->err_rwlock);
206-
207-
/* no need to retry the search, this thread is executing this function */
208-
209-
/* not found, so create it */
210-
ctx_data->errs = ly_realloc(ctx_data->errs, (ctx_data->err_count + 1) * sizeof *ctx_data->errs);
211-
ctx_data->errs[ctx_data->err_count] = calloc(1, sizeof **ctx_data->errs);
212-
memcpy(&ctx_data->errs[ctx_data->err_count]->tid, &tid, sizeof tid);
213-
214-
++ctx_data->err_count;
215-
216-
data_err = ctx_data->errs[ctx_data->err_count - 1];
217-
218-
cleanup:
219-
/* ERR UNLOCK */
220-
pthread_rwlock_unlock(&ctx_data->err_rwlock);
221-
return data_err;
222-
}
223-
224179
LIBYANG_API_DEF const struct ly_err_item *
225180
ly_err_first(const struct ly_ctx *ctx)
226181
{
227-
struct ly_ctx_data_err *err_data;
228-
229-
if (!ctx) {
230-
return NULL;
231-
}
182+
struct ly_ctx_private_data *ctx_data;
232183

233-
/* get context err data */
234-
err_data = ly_err_data_get(ctx);
184+
LY_CHECK_ARG_RET(NULL, ctx, NULL);
235185

236-
return err_data ? err_data->err : NULL;
186+
ctx_data = ly_ctx_private_data_get(ctx);
187+
return ctx_data->errs;
237188
}
238189

239190
LIBYANG_API_DEF const struct ly_err_item *
240191
ly_err_last(const struct ly_ctx *ctx)
241192
{
242-
struct ly_ctx_data_err *err_data;
243-
244-
if (!ctx) {
245-
return NULL;
246-
}
193+
struct ly_ctx_private_data *ctx_data;
247194

248-
/* get context err data */
249-
err_data = ly_err_data_get(ctx);
195+
LY_CHECK_ARG_RET(NULL, ctx, NULL);
250196

251-
if (!err_data) {
252-
return NULL;
253-
}
254-
255-
return err_data->err ? err_data->err->prev : NULL;
197+
ctx_data = ly_ctx_private_data_get(ctx);
198+
return ctx_data->errs ? ctx_data->errs->prev : NULL;
256199
}
257200

258201
void
259202
ly_err_move(struct ly_ctx *src_ctx, struct ly_ctx *trg_ctx)
260203
{
261-
struct ly_ctx_data_err *err_data;
262-
struct ly_err_item *err = NULL;
204+
struct ly_ctx_private_data *src_data, *trg_data;
205+
struct ly_err_item *errs = NULL;
263206

264-
/* get src context err data */
265-
err_data = ly_err_data_get(src_ctx);
266-
err = err_data->err;
267-
err_data->err = NULL;
207+
/* get src context errs */
208+
src_data = ly_ctx_private_data_get(src_ctx);
209+
errs = src_data->errs;
210+
src_data->errs = NULL;
211+
212+
/* get and free the trg context errs */
213+
trg_data = ly_ctx_private_data_get(trg_ctx);
214+
ly_err_free(trg_data->errs);
268215

269216
/* set them for trg */
270-
err_data = ly_err_data_get(trg_ctx);
271-
ly_err_free(err_data->err);
272-
err_data->err = err;
217+
ly_err_free(trg_data->errs);
218+
trg_data->errs = errs;
273219
}
274220

275221
LIBYANG_API_DEF void
@@ -290,24 +236,28 @@ ly_err_free(void *ptr)
290236
LIBYANG_API_DEF void
291237
ly_err_clean(const struct ly_ctx *ctx, struct ly_err_item *eitem)
292238
{
293-
struct ly_ctx_data_err *err_data;
239+
struct ly_ctx_private_data *ctx_data;
294240
struct ly_err_item *e;
295241

296-
err_data = ly_err_data_get(ctx);
297-
if (err_data->err == eitem) {
242+
if (!ctx) {
243+
return;
244+
}
245+
246+
ctx_data = ly_ctx_private_data_get(ctx);
247+
if (ctx_data->errs == eitem) {
298248
eitem = NULL;
299249
}
300250

301251
if (!eitem) {
302252
/* free all err */
303-
ly_err_free(err_data->err);
304-
err_data->err = NULL;
253+
ly_err_free(ctx_data->errs);
254+
ctx_data->errs = NULL;
305255
} else {
306256
/* disconnect the error */
307-
for (e = err_data->err; e && (e->next != eitem); e = e->next) {}
257+
for (e = ctx_data->errs; e && (e->next != eitem); e = e->next) {}
308258
assert(e);
309259
e->next = NULL;
310-
err_data->err->prev = e;
260+
ctx_data->errs->prev = e;
311261

312262
/* free this err and newer */
313263
ly_err_free(eitem);
@@ -456,15 +406,15 @@ static LY_ERR
456406
log_store(const struct ly_ctx *ctx, LY_LOG_LEVEL level, LY_ERR err, LY_VECODE vecode, char *msg, char *data_path,
457407
char *schema_path, uint64_t line, char *apptag)
458408
{
459-
struct ly_ctx_data_err *err_data;
409+
struct ly_ctx_private_data *ctx_data;
460410
struct ly_err_item *e, *last;
461411

462412
assert(ctx && (level < LY_LLVRB));
463413

464-
/* get context err data */
465-
err_data = ly_err_data_get(ctx);
414+
/* get context private data */
415+
ctx_data = ly_ctx_private_data_get(ctx);
466416

467-
e = err_data->err;
417+
e = ctx_data->errs;
468418
if (!e) {
469419
/* if we are only to fill in path, there must have been an error stored */
470420
assert(msg);
@@ -473,7 +423,7 @@ log_store(const struct ly_ctx *ctx, LY_LOG_LEVEL level, LY_ERR err, LY_VECODE ve
473423
e->prev = e;
474424
e->next = NULL;
475425

476-
err_data->err = e;
426+
ctx_data->errs = e;
477427
} else if (!msg) {
478428
/* only filling the path */
479429
assert(data_path || schema_path);

0 commit comments

Comments
 (0)