diff --git a/lib/clixon/clixon_yang.h b/lib/clixon/clixon_yang.h index b9ce42c4..4a254e36 100644 --- a/lib/clixon/clixon_yang.h +++ b/lib/clixon/clixon_yang.h @@ -266,6 +266,9 @@ cvec *yang_cvec_get(yang_stmt *ys); int yang_cvec_set(yang_stmt *ys, cvec *cvv); cg_var *yang_cvec_add(yang_stmt *ys, enum cv_type type, char *name); int yang_cvec_rm(yang_stmt *ys, char *name); +int yang_ref_get(yang_stmt *ys); +int yang_ref_inc(yang_stmt *ys); +int yang_ref_dec(yang_stmt *ys); uint16_t yang_flag_get(yang_stmt *ys, uint16_t flag); int yang_flag_set(yang_stmt *ys, uint16_t flag); int yang_flag_reset(yang_stmt *ys, uint16_t flag); diff --git a/lib/src/clixon_datastore_read.c b/lib/src/clixon_datastore_read.c index 63ffcb31..d728b5ae 100644 --- a/lib/src/clixon_datastore_read.c +++ b/lib/src/clixon_datastore_read.c @@ -708,7 +708,7 @@ xmldb_readfile(clixon_handle h, * Same ymodules are inserted into yspec1, ie pointers only */ if (needclone && xmodfile){ - if ((yspec1 = yspec_new1(h, YANG_DOMAIN_TOP, "tmp")) == NULL) + if ((yspec1 = yspec_new1(h, YANG_DOMAIN_TOP, "prevyang")) == NULL) goto done; xmsd = NULL; while ((xmsd = xml_child_each(xmodfile, xmsd, CX_ELMNT)) != NULL) { @@ -722,6 +722,7 @@ xmldb_readfile(clixon_handle h, continue; // XXX error? if (yn_insert1(yspec1, ymod) < 0) goto done; + yang_ref_inc(ymod); } } } /* if msdiff */ @@ -747,8 +748,6 @@ xmldb_readfile(clixon_handle h, done: if (mr.mr_subdir) free(mr.mr_subdir); - if (yspec1) - ys_free1(yspec1, 1); if (xmodfile) xml_free(xmodfile); if (msdiff) diff --git a/lib/src/clixon_yang.c b/lib/src/clixon_yang.c index c9fdab3f..90c515f9 100644 --- a/lib/src/clixon_yang.c +++ b/lib/src/clixon_yang.c @@ -425,6 +425,47 @@ yang_cvec_rm(yang_stmt *ys, return 0; } +/*! Get yang object reference count + * + * @param[in] ys Yang statement + * @retval ref Reference coun t + */ +int +yang_ref_get(yang_stmt *ys) +{ + return ys->ys_ref; +} + +/*! Increment yang object reference count with +1 + * + * @param[in] ys Yang statement + * @retval 0 + */ +int +yang_ref_inc(yang_stmt *ys) +{ + ys->ys_ref++; + return 0; +} + +/*! Decrement yang object reference count with -1 + * + * @param[in] ys Yang statement + * @retval 0 Ok + * @retval -1 Error + */ +int +yang_ref_dec(yang_stmt *ys) +{ + int retval = -1; + + if (ys->ys_ref > 0) + ys->ys_ref--; + retval = 0; + // done: + return retval; +} + /*! Get yang stmt flags, used for internal algorithms * * @param[in] ys Yang statement @@ -1154,8 +1195,13 @@ ys_freechildren(yang_stmt *ys) int ys_free(yang_stmt *ys) { - ys_freechildren(ys); - ys_free1(ys, 1); + if (yang_ref_get(ys) > 0){ + yang_ref_dec(ys); + } + else { + ys_freechildren(ys); + ys_free1(ys, 1); + } return 0; } diff --git a/lib/src/clixon_yang_internal.h b/lib/src/clixon_yang_internal.h index 0d239a87..7e8b4080 100644 --- a/lib/src/clixon_yang_internal.h +++ b/lib/src/clixon_yang_internal.h @@ -68,7 +68,9 @@ typedef struct yang_type_cache yang_type_cache; */ struct yang_stmt { /* On x86_64, the following three fields take 8 bytes */ - enum rfc_6020 ys_keyword:16; /* YANG keyword */ + enum rfc_6020 ys_keyword:8; /* YANG keyword */ + uint8_t ys_ref; /* Reference count for free: 0 means + * no sharing, 1: two references */ uint16_t ys_flags; /* Flags according to YANG_FLAG_MARK and others */ uint32_t ys_len; /* Number of children */ #ifdef YANG_SPEC_LINENR @@ -112,6 +114,7 @@ struct yang_stmt { rpc_callback_t *ysu_action_cb; /* Y_ACTION: Action callback list*/ char *ysu_filename; /* Y_MODULE/Y_SUBMODULE: For debug/errors: filename */ yang_type_cache *ysu_typecache; /* Y_TYPE: cache all typedef data except unions */ + } u; }; diff --git a/test/test_confirmed_commit.sh b/test/test_confirmed_commit.sh index b8a2af10..f6ab7a24 100755 --- a/test/test_confirmed_commit.sh +++ b/test/test_confirmed_commit.sh @@ -184,9 +184,10 @@ rpc "ab" "" new "6. netconf persistent confirmed-commit with timeout" reset edit_config "candidate" "$CONFIGB" -commit "3abcd" +# need 5 for valgrind netconf that takes a couple of seconds to finish +commit "5abcd" assert_config_equals "running" "$CONFIGB" -sleep 3 +sleep 5 assert_config_equals "running" "" ################################################################################