diff --git a/lib/isc/cfgmgr.c b/lib/isc/cfgmgr.c index a1f64721b6..e1d867a0f1 100644 --- a/lib/isc/cfgmgr.c +++ b/lib/isc/cfgmgr.c @@ -304,6 +304,13 @@ static isc_result_t isc__cfgmgr_starttransaction(bool readonly) { MDB_dbi dbi; + REQUIRE(isc__cfgmgr_env != NULL); + REQUIRE(ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses)); + REQUIRE(isc__cfgmgr_ctx.prefix == NULL); + REQUIRE(isc__cfgmgr_ctx.buffer == NULL); + REQUIRE(isc__cfgmgr_ctx.txn == NULL); + REQUIRE(isc__cfgmgr_ctx.cursor == NULL); + if (mdb_txn_begin(isc__cfgmgr_env, NULL, readonly ? MDB_RDONLY : 0, &isc__cfgmgr_ctx.txn) != 0) { @@ -340,90 +347,14 @@ failure: return ISC_R_FAILURE; } -static isc_result_t -isc__cfgmgr_opentoplevel(const char *name, bool readonly) { - isc_result_t result = ISC_R_SUCCESS; - unsigned long id = 0; - - REQUIRE(isc__cfgmgr_env != NULL); - REQUIRE(name != NULL); - REQUIRE(ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses)); - REQUIRE(isc__cfgmgr_ctx.prefix == NULL); - REQUIRE(isc__cfgmgr_ctx.buffer == NULL); - REQUIRE(isc__cfgmgr_ctx.txn == NULL); - REQUIRE(isc__cfgmgr_ctx.cursor == NULL); - - /* - * We're opening a clause at top-level, so let's start a - * transaction - */ - result = isc__cfgmgr_starttransaction(readonly); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - - /* - * Now let's try to find the clause... - */ - result = isc__cfgmgr_findclause(name, &id); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - - /* - * The clause is found, let's enqueue the clause in - * context. the clause is now opened - */ - isc__cfgmgr_pushclause(name, id); - goto out; - -cleanup: - if (isc__cfgmgr_ctx.txn) { - mdb_cursor_close(isc__cfgmgr_ctx.cursor); - mdb_txn_abort(isc__cfgmgr_ctx.txn); - isc__cfgmgr_freectx(); - } - -out: - return result; -} - -static isc_result_t -isc__cfgmgr_opennested(const char *name) { - isc_result_t result = ISC_R_SUCCESS; - unsigned long id = 0; - - REQUIRE(isc__cfgmgr_env != NULL); - REQUIRE(name != NULL); - REQUIRE(ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses) == false); - REQUIRE(isc__cfgmgr_ctx.prefix != NULL); - REQUIRE(isc__cfgmgr_ctx.buffer != NULL); - REQUIRE(isc__cfgmgr_ctx.txn != NULL); - REQUIRE(isc__cfgmgr_ctx.cursor != NULL); - - result = isc__cfgmgr_findclause(name, &id); - if (result != ISC_R_SUCCESS) { - goto out; - } - - isc__cfgmgr_pushclause(name, id); - -out: - return result; +isc_result_t +isc_cfgmgr_transaction(void) { + return isc__cfgmgr_starttransaction(true); } isc_result_t -isc_cfgmgr_openrw(const char *name) { - return isc__cfgmgr_opentoplevel(name, false); -} - -isc_result_t -isc_cfgmgr_open(const char *name) { - if (ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses)) { - return isc__cfgmgr_opentoplevel(name, true); - } - - return isc__cfgmgr_opennested(name); +isc_cfgmgr_rwtransaction(void) { + return isc__cfgmgr_starttransaction(false); } static void @@ -437,9 +368,61 @@ popclause(void) { } isc_result_t -isc_cfgmgr_close(void) { +isc_cfgmgr_commit(void) { isc_result_t result = ISC_R_SUCCESS; + REQUIRE(isc__cfgmgr_env != NULL); + REQUIRE(isc__cfgmgr_ctx.txn != NULL); + REQUIRE(isc__cfgmgr_ctx.cursor != NULL); + + while (ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses) == false) { + popclause(); + } + + mdb_cursor_close(isc__cfgmgr_ctx.cursor); + if (mdb_txn_commit(isc__cfgmgr_ctx.txn) != 0) { + result = ISC_R_FAILURE; + } + isc__cfgmgr_freectx(); + + return result; +} + +void +isc_cfgmgr_rollback(void) { + REQUIRE(isc__cfgmgr_env != NULL); + REQUIRE(isc__cfgmgr_ctx.txn != NULL); + REQUIRE(isc__cfgmgr_ctx.cursor != NULL); + + while (ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses) == false) { + popclause(); + } + + mdb_cursor_close(isc__cfgmgr_ctx.cursor); + mdb_txn_abort(isc__cfgmgr_ctx.txn); + isc__cfgmgr_freectx(); +} + +isc_result_t +isc_cfgmgr_open(const char *name) { + isc_result_t result = ISC_R_SUCCESS; + unsigned long id = 0; + + REQUIRE(isc__cfgmgr_env != NULL); + REQUIRE(name != NULL); + REQUIRE(isc__cfgmgr_ctx.txn != NULL); + REQUIRE(isc__cfgmgr_ctx.cursor != NULL); + + result = isc__cfgmgr_findclause(name, &id); + if (result == ISC_R_SUCCESS) { + isc__cfgmgr_pushclause(name, id); + } + + return result; +} + +void +isc_cfgmgr_close(void) { REQUIRE(isc__cfgmgr_env != NULL); REQUIRE(ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses) == false); REQUIRE(isc__cfgmgr_ctx.prefix != NULL); @@ -448,18 +431,9 @@ isc_cfgmgr_close(void) { REQUIRE(isc__cfgmgr_ctx.cursor != NULL); popclause(); - if (ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses)) { - mdb_cursor_close(isc__cfgmgr_ctx.cursor); - if (mdb_txn_commit(isc__cfgmgr_ctx.txn) != 0) { - result = ISC_R_FAILURE; - } - isc__cfgmgr_freectx(); - } - - return result; } -isc_result_t +void isc_cfgmgr_delclause(void) { MDB_val dbkey; @@ -502,34 +476,19 @@ isc_cfgmgr_delclause(void) { 0); } while (1); - return isc_cfgmgr_close(); + isc_cfgmgr_close(); } -isc_result_t +void isc_cfgmgr_newclause(const char *name) { - isc_result_t result = ISC_R_SUCCESS; - - REQUIRE(name != NULL); REQUIRE(isc__cfgmgr_env != NULL); + REQUIRE(name != NULL); + REQUIRE(isc__cfgmgr_ctx.txn != NULL); + REQUIRE(isc__cfgmgr_ctx.cursor != NULL); + INSIST(isc__cfgmgr_ctx.readonly == false); - if (isc__cfgmgr_ctx.txn == NULL || isc__cfgmgr_ctx.cursor == NULL) { - REQUIRE(isc__cfgmgr_ctx.prefix == NULL); - REQUIRE(isc__cfgmgr_ctx.buffer == NULL); - REQUIRE(isc__cfgmgr_ctx.txn == NULL); - REQUIRE(isc__cfgmgr_ctx.cursor == NULL); - result = isc__cfgmgr_starttransaction(false); - } - - if (result == ISC_R_SUCCESS) { - INSIST(isc__cfgmgr_ctx.txn != NULL); - INSIST(isc__cfgmgr_ctx.buffer != NULL); - INSIST(isc__cfgmgr_ctx.cursor != NULL); - INSIST(isc__cfgmgr_ctx.readonly == false); - isc__cfgmgr_pushclause(name, isc_random32()); - INSIST(isc__cfgmgr_ctx.prefix != NULL); - } - - return result; + isc__cfgmgr_pushclause(name, isc_random32()); + INSIST(isc__cfgmgr_ctx.prefix != NULL); } isc_result_t diff --git a/lib/isc/include/isc/cfgmgr.h b/lib/isc/include/isc/cfgmgr.h index db0650d691..424000735d 100644 --- a/lib/isc/include/isc/cfgmgr.h +++ b/lib/isc/include/isc/cfgmgr.h @@ -47,10 +47,8 @@ typedef struct isc_cfgmgr_val { /* * Get the property "name" in the opened clause into the caller * allocated "value" and returns ISC_R_SUCCESS. Returns ISC_R_NOTFOUND - * and "*value" is not mutated if "name" is not found. Changes being - * made by other threads aren't visible until the clause (and its - * parent, if nested) is closed. If "name" is a list property, get its - * head. + * and "*value" is not mutated if "name" is not found. If "name" is a list + * property, get its head. */ isc_result_t isc_cfgmgr_getval(const char *name, isc_cfgmgr_val_t *value); @@ -60,9 +58,7 @@ isc_cfgmgr_getval(const char *name, isc_cfgmgr_val_t *value); * returns ISC_R_SUCCESS. If the property already exists, it is * overridden and even if the type is different. If "value" is NULL * and the property exists, it will be deleted (applies for list - * properties as well), otherwise, it returns ISC_R_NOTFOUND. Changes - * being made can be visible only by the current thread until the - * clause (and its parent, if nested) is closed. + * properties as well), otherwise, it returns ISC_R_NOTFOUND. */ isc_result_t isc_cfgmgr_setval(const char *name, const isc_cfgmgr_val_t *value); @@ -101,66 +97,75 @@ isc_result_t isc_cfgmgr_nextclause(void); /* - * If used at top-level, create and open as read-write a new clause - * "name". If used inside an opened parent clause, then the parent (or - * parent or the parent, recursively) clause must have been opened - * read-write (so using isc_cfgmgr_openrw or isc_cfgmgr_newclause). - * - * Returns ISC_R_SUCCESS or ISC_R_FAILURE if there is no transaction - * and it fails creating one. Note that in order to have the new - * clause actually written in cfgmgr, at least one property needs to - * be set to that clause. + * Create and open a new clause. If not clause is currently opened, the newly + * created clause is a top-level one. Otherwise, it is nested in the clause + * opened when this function is called. Note that in order to have the new + * clause actually written in cfgmgr, at least one property needs to be set to + * that clause. */ -isc_result_t +void isc_cfgmgr_newclause(const char *name); /* * Delete and close the opened clause. (And thus all its properties, * including nested clauses). If the clause was nested, the currently * opened clause is now the parent clause. Otherwise, no clause is - * opened. Returns ISC_R_SUCCESS. + * opened. + */ +void +isc_cfgmgr_delclause(void); + +/* + * Open the clause "name" and returns ISC_R_SUCCES or ISC_R_NOTFOUND + * is the clause is not found. Must be called under a transaction. */ isc_result_t -isc_cfgmgr_delclause(void); +isc_cfgmgr_open(const char *name); /* * Close the currently opened clause and returns ISC_R_SUCCESS. If the * closed clause was nested, the currently opened clause is now the - * parent clause. If top-level clause was opened with - * isc_cfgmgr_openrw or isc_cfgmgr_newclause, closing the top-level - * clause will applies all modifications done inside the clause (and - * inside the nested clauses). If something is going wrong while - * writing the modifications ISC_R_FAILURE is returned and all - * modification made are discarded. + * parent clause. Must be called under a transaction. */ -isc_result_t +void isc_cfgmgr_close(void); /* - * Open the top-level clause "name" for reading and writing and - * returns ISC_R_SUCCESS. If the clause "name" is not found, returns - * ISC_R_NOTFOUND. If there is an issue creating a transaction, it - * returns ISC_R_FAILURE. - * - * This call will block if another thread has already a clause opened - * for reading and writting. Use isc_cfgmgr_openro for reading only. + * Starts a read-only transaction and returns ISC_R_SUCCESS. If there is an + * issue creating a transaction, ISC_R_FAILURE is returned. Prior callimg this + * function, there must be no currently transaction started from the current + * thread. */ isc_result_t -isc_cfgmgr_openrw(const char *name); +isc_cfgmgr_transaction(void); /* - * Open the clause "name" and returns ISC_R_SUCCES or ISC_R_NOTFOUND - * is the clause is not found. Two possible cases: - * - * - if called at top-level, it open the top-level clause as read - * only. Returns ISC_R_FAILURE if there is an issue creating the - * transaction. - * - * - if called form within an opened clause, it open it with the same - * access than the already opened clause. + * Starts a read-write transaction and returns ISC_R_SUCCESS. If there is an + * issue creating a transaction, ISC_R_FAILURE is returned. Prior callimg this + * function, there must be no currently transaction started from the current + * thread. If another thread already started a read-write transaction, + * this call will block until the other transaction is terminated. */ isc_result_t -isc_cfgmgr_open(const char *name); +isc_cfgmgr_rwtransaction(void); + +/* + * Makes all changes applied during this transaction visible to all transaction + * started after this call returns. If something goes wrong while applying the + * changes, ISC_R_FAILURE is returned and the changes made during the + * transaction are discareded. ISC_R_SUCCESS is returned otherwise. If a clause + * is opened when this function is called, it is automatically closed. + */ +isc_result_t +isc_cfgmgr_commit(void); + +/* + * Discard all the changes made during transaction and terminate the + * transaction. If a clause is opened when this function is called, it is + * automatically closed. + */ +void +isc_cfgmgr_rollback(void); /* * Initialize cfgmgr. Must be called before any other function. It is diff --git a/tests/isc/cfgmgr_test.c b/tests/isc/cfgmgr_test.c index c39cbc0e74..b3619525db 100644 --- a/tests/isc/cfgmgr_test.c +++ b/tests/isc/cfgmgr_test.c @@ -42,8 +42,11 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_assertions) { expect_assert_failure(isc_cfgmgr_setval("foo", &dummyval)); expect_assert_failure(isc_cfgmgr_setnextlistval("foo", &dummyval)); expect_assert_failure(isc_cfgmgr_nextclause()); + expect_assert_failure(isc_cfgmgr_transaction()); + expect_assert_failure(isc_cfgmgr_rwtransaction()); + expect_assert_failure(isc_cfgmgr_commit()); + expect_assert_failure(isc_cfgmgr_rollback()); expect_assert_failure(isc_cfgmgr_open("foo")); - expect_assert_failure(isc_cfgmgr_openrw("foo")); expect_assert_failure(isc_cfgmgr_newclause("foo")); expect_assert_failure(isc_cfgmgr_delclause()); expect_assert_failure(isc_cfgmgr_deinit()); @@ -52,41 +55,68 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_assertions) { * operations which must be used under transaction */ (void)isc_cfgmgr_init(mctx, TEST_DBPATH); - (void)isc_cfgmgr_newclause("foo"); - (void)isc_cfgmgr_setval("bar", - &(isc_cfgmgr_val_t){ .type = ISC_CFGMGR_NONE }); - (void)isc_cfgmgr_close(); expect_assert_failure(isc_cfgmgr_delclause()); expect_assert_failure(isc_cfgmgr_getval("foo", &dummyval)); expect_assert_failure(isc_cfgmgr_getnextlistval(&dummyval)); expect_assert_failure(isc_cfgmgr_setval("foo", &dummyval)); expect_assert_failure(isc_cfgmgr_setnextlistval("foo", &dummyval)); expect_assert_failure(isc_cfgmgr_nextclause()); + expect_assert_failure(isc_cfgmgr_commit()); + expect_assert_failure(isc_cfgmgr_rollback()); + expect_assert_failure(isc_cfgmgr_open("foo")); + expect_assert_failure(isc_cfgmgr_newclause("foo")); + expect_assert_failure(isc_cfgmgr_close()); + + assert_int_equal(isc_cfgmgr_transaction(), ISC_R_SUCCESS); + expect_assert_failure(isc_cfgmgr_transaction()); + expect_assert_failure(isc_cfgmgr_rwtransaction()); + isc_cfgmgr_rollback(); + + assert_int_equal(isc_cfgmgr_rwtransaction(), ISC_R_SUCCESS); + expect_assert_failure(isc_cfgmgr_transaction()); + expect_assert_failure(isc_cfgmgr_rwtransaction()); + isc_cfgmgr_rollback(); + isc_cfgmgr_deinit(); /* * One close for one open */ (void)isc_cfgmgr_init(mctx, TEST_DBPATH); - (void)isc_cfgmgr_newclause("foo"); - (void)isc_cfgmgr_close(); + assert_int_equal(isc_cfgmgr_rwtransaction(), ISC_R_SUCCESS); + isc_cfgmgr_newclause("foo"); + isc_cfgmgr_close(); expect_assert_failure(isc_cfgmgr_close()); + assert_int_equal(isc_cfgmgr_commit(), ISC_R_SUCCESS); isc_cfgmgr_deinit(); /* - * nothing is open in case of top-level open failure + * One close for one open (and failed open as not existent) */ (void)isc_cfgmgr_init(mctx, TEST_DBPATH); - (void)isc_cfgmgr_open("foo"); - expect_assert_failure(isc_cfgmgr_close()); - (void)isc_cfgmgr_openrw("foo"); + assert_int_equal(isc_cfgmgr_rwtransaction(), ISC_R_SUCCESS); + isc_cfgmgr_newclause("foo"); + assert_int_equal(isc_cfgmgr_open("bar"), ISC_R_NOTFOUND); + isc_cfgmgr_close(); expect_assert_failure(isc_cfgmgr_close()); + assert_int_equal(isc_cfgmgr_commit(), ISC_R_SUCCESS); + isc_cfgmgr_deinit(); + + /* + * (Implicit) two closes for two open + */ + (void)isc_cfgmgr_init(mctx, TEST_DBPATH); + assert_int_equal(isc_cfgmgr_rwtransaction(), ISC_R_SUCCESS); + isc_cfgmgr_newclause("foo"); + isc_cfgmgr_newclause("bar"); + assert_int_equal(isc_cfgmgr_commit(), ISC_R_SUCCESS); isc_cfgmgr_deinit(); /* * can't write on non-write open clause nor open a subclause as write */ (void)isc_cfgmgr_init(mctx, TEST_DBPATH); + assert_int_equal(isc_cfgmgr_rwtransaction(), ISC_R_SUCCESS); (void)isc_cfgmgr_newclause("foo"); (void)isc_cfgmgr_setval("bar", &(isc_cfgmgr_val_t){ .type = ISC_CFGMGR_NONE }); @@ -95,6 +125,9 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_assertions) { &(isc_cfgmgr_val_t){ .type = ISC_CFGMGR_NONE }); (void)isc_cfgmgr_close(); (void)isc_cfgmgr_close(); + assert_int_equal(isc_cfgmgr_commit(), ISC_R_SUCCESS); + + assert_int_equal(isc_cfgmgr_transaction(), ISC_R_SUCCESS); (void)isc_cfgmgr_open("foo"); expect_assert_failure(isc_cfgmgr_setval( "bar", &(isc_cfgmgr_val_t){ .type = ISC_CFGMGR_NONE })); @@ -102,28 +135,29 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_assertions) { "baz", &(isc_cfgmgr_val_t){ .type = ISC_CFGMGR_NONE })); expect_assert_failure(isc_cfgmgr_newclause("gee")); expect_assert_failure(isc_cfgmgr_delclause()); - expect_assert_failure(isc_cfgmgr_openrw("subfoo")); - (void)isc_cfgmgr_close(); + assert_int_equal(isc_cfgmgr_commit(), ISC_R_SUCCESS); isc_cfgmgr_deinit(); /* * reading values parameters */ (void)isc_cfgmgr_init(mctx, TEST_DBPATH); - (void)isc_cfgmgr_newclause("foo"); + assert_int_equal(isc_cfgmgr_rwtransaction(), ISC_R_SUCCESS); + isc_cfgmgr_newclause("foo"); (void)isc_cfgmgr_setval("bar", &(isc_cfgmgr_val_t){ .type = ISC_CFGMGR_NONE }); expect_assert_failure(isc_cfgmgr_getval("bar", NULL)); - (void)isc_cfgmgr_close(); + assert_int_equal(isc_cfgmgr_commit(), ISC_R_SUCCESS); isc_cfgmgr_deinit(); /* - * can't de-init while having opened clause + * can't de-init while having opened transaction */ (void)isc_cfgmgr_init(mctx, TEST_DBPATH); - (void)isc_cfgmgr_newclause("foo"); + assert_int_equal(isc_cfgmgr_rwtransaction(), ISC_R_SUCCESS); + isc_cfgmgr_newclause("foo"); expect_assert_failure(isc_cfgmgr_deinit()); - (void)isc_cfgmgr_close(); + assert_int_equal(isc_cfgmgr_commit(), ISC_R_SUCCESS); (void)isc_cfgmgr_deinit(); /* @@ -140,11 +174,13 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_rw) { result = isc_cfgmgr_init(mctx, TEST_DBPATH); assert_int_equal(result, ISC_R_SUCCESS); + result = isc_cfgmgr_rwtransaction(); + assert_int_equal(result, ISC_R_SUCCESS); + result = isc_cfgmgr_open("foo"); assert_int_equal(result, ISC_R_NOTFOUND); - result = isc_cfgmgr_newclause("foo"); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("foo"); val1 = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 4058304 }; @@ -216,7 +252,10 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_rw) { assert_int_equal(val2.type, ISC_CFGMGR_BOOLEAN); assert_int_equal(val2.boolean, true); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); + assert_int_equal(result, ISC_R_SUCCESS); + + result = isc_cfgmgr_transaction(); assert_int_equal(result, ISC_R_SUCCESS); result = isc_cfgmgr_open("foo"); @@ -240,7 +279,7 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_rw) { assert_int_equal(val2.type, ISC_CFGMGR_BOOLEAN); assert_int_equal(val2.boolean, true); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); /* @@ -248,9 +287,11 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_rw) { * but a common prefix in the name - those are still different * clauses */ - result = isc_cfgmgr_newclause("foo1"); + result = isc_cfgmgr_rwtransaction(); assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("foo1"); + val1 = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 1234 }; result = isc_cfgmgr_setval("prop1", &val1); assert_int_equal(result, ISC_R_SUCCESS); @@ -277,13 +318,16 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_rw) { result = isc_cfgmgr_getval("prop3", &val2); assert_int_equal(result, ISC_R_NOTFOUND); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); /* * let's reopen rw this time */ - result = isc_cfgmgr_openrw("foo"); + result = isc_cfgmgr_rwtransaction(); + assert_int_equal(result, ISC_R_SUCCESS); + + result = isc_cfgmgr_open("foo"); assert_int_equal(result, ISC_R_SUCCESS); result = isc_cfgmgr_getval("prop1", &val2); @@ -296,10 +340,13 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_rw) { assert_int_equal(val2.type, ISC_CFGMGR_BOOLEAN); assert_int_equal(val2.boolean, true); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_openrw("foo1"); + result = isc_cfgmgr_rwtransaction(); + assert_int_equal(result, ISC_R_SUCCESS); + + result = isc_cfgmgr_open("foo1"); assert_int_equal(result, ISC_R_SUCCESS); result = isc_cfgmgr_getval("prop1", &val2); @@ -323,12 +370,49 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_rw) { assert_int_equal(val2.type, ISC_CFGMGR_UINT32); assert_int_equal(val2.uint32, 999); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); isc_cfgmgr_deinit(); } +ISC_RUN_TEST_IMPL(isc_cfgmgr_rollback) { + isc_cfgmgr_val_t val; + + assert_int_equal(isc_cfgmgr_init(mctx, TEST_DBPATH), ISC_R_SUCCESS); + + assert_int_equal(isc_cfgmgr_rwtransaction(), ISC_R_SUCCESS); + isc_cfgmgr_newclause("foo"); + val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 42 }; + assert_int_equal(isc_cfgmgr_setval("prop", &val), ISC_R_SUCCESS); + assert_int_equal(isc_cfgmgr_commit(), ISC_R_SUCCESS); + + assert_int_equal(isc_cfgmgr_rwtransaction(), ISC_R_SUCCESS); + assert_int_equal(isc_cfgmgr_open("foo"), ISC_R_SUCCESS); + val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 9999 }; + assert_int_equal(isc_cfgmgr_setval("prop", &val), ISC_R_SUCCESS); + val.uint32 = 0; + assert_int_equal(isc_cfgmgr_getval("prop", &val), ISC_R_SUCCESS); + assert_int_equal(val.type, ISC_CFGMGR_UINT32); + /* + * value is 9999 as newly updated in this transaction + */ + assert_int_equal(val.uint32, 9999); + isc_cfgmgr_rollback(); + + assert_int_equal(isc_cfgmgr_transaction(), ISC_R_SUCCESS); + assert_int_equal(isc_cfgmgr_open("foo"), ISC_R_SUCCESS); + assert_int_equal(isc_cfgmgr_getval("prop", &val), ISC_R_SUCCESS); + assert_int_equal(val.type, ISC_CFGMGR_UINT32); + /* + * value is not 9999 anymore, because previous transaction been reverted + */ + assert_int_equal(val.uint32, 42); + assert_int_equal(isc_cfgmgr_commit(), ISC_R_SUCCESS); + + isc_cfgmgr_deinit(); +} + ISC_RUN_TEST_IMPL(isc_cfgmgr_parseid) { isc_result_t result; isc_cfgmgr_val_t val; @@ -343,38 +427,39 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_parseid) { result = isc_cfgmgr_init(mctx, TEST_DBPATH); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_newclause("123"); + result = isc_cfgmgr_rwtransaction(); assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("123"); + val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 666666 }; result = isc_cfgmgr_setval("123123", &val); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_newclause("456"); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("456"); val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 777777 }; result = isc_cfgmgr_setval("456456", &val); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_close(); - result = isc_cfgmgr_newclause("456"); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("456"); val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 888888 }; result = isc_cfgmgr_setval("456456", &val); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_close(); val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 9999 }; result = isc_cfgmgr_setval("456456", &val); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); + assert_int_equal(result, ISC_R_SUCCESS); + + result = isc_cfgmgr_transaction(); assert_int_equal(result, ISC_R_SUCCESS); result = isc_cfgmgr_open("123"); @@ -430,11 +515,10 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_parseid) { assert_true(found_777777); assert_true(found_888888); - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); + /* + * or _commit, whatever, it's not a rwtransaction anyway... + */ + isc_cfgmgr_rollback(); isc_cfgmgr_deinit(); } @@ -447,9 +531,11 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_override) { result = isc_cfgmgr_init(mctx, TEST_DBPATH); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_newclause("foo"); + result = isc_cfgmgr_rwtransaction(); assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("foo"); + val1 = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 4058304 }; result = isc_cfgmgr_setval("prop1", &val1); @@ -490,7 +576,7 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_override) { assert_int_equal(val2.type, ISC_CFGMGR_BOOLEAN); assert_int_equal(val2.boolean, true); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); isc_cfgmgr_deinit(); @@ -504,9 +590,11 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_rw_string) { result = isc_cfgmgr_init(mctx, TEST_DBPATH); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_newclause("foo"); + result = isc_cfgmgr_rwtransaction(); assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("foo"); + val1 = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_STRING, .string = "hey there!" }; result = isc_cfgmgr_setval("prop1", &val1); @@ -555,7 +643,7 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_rw_string) { assert_int_equal(val2.type, ISC_CFGMGR_STRING); assert_string_equal(val2.string, "foobarbaz stuff"); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); isc_cfgmgr_deinit(); @@ -568,9 +656,11 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_list) { result = isc_cfgmgr_init(mctx, TEST_DBPATH); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_newclause("foo"); + result = isc_cfgmgr_rwtransaction(); assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("foo"); + val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_STRING, .string = "lst1" }; result = isc_cfgmgr_setnextlistval("proplist", &val); assert_int_equal(result, ISC_R_SUCCESS); @@ -595,7 +685,10 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_list) { result = isc_cfgmgr_setval("zzz", &val); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); + assert_int_equal(result, ISC_R_SUCCESS); + + result = isc_cfgmgr_transaction(); assert_int_equal(result, ISC_R_SUCCESS); result = isc_cfgmgr_open("foo"); @@ -668,7 +761,7 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_list) { result = isc_cfgmgr_getnextlistval(&val); assert_int_equal(result, ISC_R_NOMORE); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); isc_cfgmgr_deinit(); @@ -682,9 +775,11 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_repeatable_clauses) { result = isc_cfgmgr_init(mctx, TEST_DBPATH); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_newclause("view"); + result = isc_cfgmgr_rwtransaction(); assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("view"); + val1 = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_STRING, .string = "view1 p1 val" }; result = isc_cfgmgr_setval("p1", &val1); @@ -695,12 +790,14 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_repeatable_clauses) { result = isc_cfgmgr_setval("p2", &val1); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_newclause("view"); + result = isc_cfgmgr_rwtransaction(); assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("view"); + val1 = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_STRING, .string = "view2 p2 val" }; result = isc_cfgmgr_setval("p1", &val1); @@ -711,7 +808,10 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_repeatable_clauses) { result = isc_cfgmgr_setval("p2", &val1); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); + assert_int_equal(result, ISC_R_SUCCESS); + + result = isc_cfgmgr_transaction(); assert_int_equal(result, ISC_R_SUCCESS); result = isc_cfgmgr_open("view"); @@ -757,7 +857,7 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_repeatable_clauses) { result = isc_cfgmgr_nextclause(); assert_int_equal(result, ISC_R_NOMORE); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); isc_cfgmgr_deinit(); @@ -774,26 +874,21 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_nested_clauses) { result = isc_cfgmgr_init(mctx, TEST_DBPATH); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_newclause("foo"); + result = isc_cfgmgr_rwtransaction(); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_newclause("bar"); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_cfgmgr_newclause("baz"); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("foo"); + isc_cfgmgr_newclause("bar"); + isc_cfgmgr_newclause("baz"); val.type = ISC_CFGMGR_NONE; result = isc_cfgmgr_setval("gee", &val); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_cfgmgr_close(); + result = isc_cfgmgr_transaction(); assert_int_equal(result, ISC_R_SUCCESS); result = isc_cfgmgr_open("foo"); @@ -810,44 +905,41 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_nested_clauses) { assert_int_equal(result, ISC_R_SUCCESS); assert_int_equal(val.type, ISC_CFGMGR_NONE); - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); /* * then let's delete bar and add some properties in foo and * another nested clause */ - result = isc_cfgmgr_openrw("foo"); + result = isc_cfgmgr_rwtransaction(); + assert_int_equal(result, ISC_R_SUCCESS); + + result = isc_cfgmgr_open("foo"); assert_int_equal(result, ISC_R_SUCCESS); result = isc_cfgmgr_open("bar"); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_delclause(); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_delclause(); - result = isc_cfgmgr_newclause("foonewsubclause"); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("foonewsubclause"); val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_STRING, .string = "abc" }; result = isc_cfgmgr_setval("propsubclause", &val); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_close(); val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_STRING, .string = "propfooval" }; result = isc_cfgmgr_setval("propfoo", &val); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); + assert_int_equal(result, ISC_R_SUCCESS); + + result = isc_cfgmgr_transaction(); assert_int_equal(result, ISC_R_SUCCESS); result = isc_cfgmgr_open("foo"); @@ -870,21 +962,20 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_nested_clauses) { assert_int_equal(val.type, ISC_CFGMGR_STRING); assert_string_equal(val.string, "abc"); - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); /* * Let's mix nested and repeatable clauses */ - result = isc_cfgmgr_openrw("foo"); + result = isc_cfgmgr_rwtransaction(); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_newclause("foonewsubclause"); + result = isc_cfgmgr_open("foo"); assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("foonewsubclause"); + bool abc_found = false; bool def_found = false; @@ -892,10 +983,10 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_nested_clauses) { result = isc_cfgmgr_setval("propsubclause", &val); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_transaction(); assert_int_equal(result, ISC_R_SUCCESS); val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UNDEFINED, @@ -936,10 +1027,7 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_nested_clauses) { assert_true(abc_found); assert_true(def_found); - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); - - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); isc_cfgmgr_deinit(); @@ -952,21 +1040,25 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_delete) { result = isc_cfgmgr_init(mctx, TEST_DBPATH); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_newclause("foo"); + result = isc_cfgmgr_rwtransaction(); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); + isc_cfgmgr_newclause("foo"); + + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); /* * foo is not found because properties has been written in the * clause. */ + result = isc_cfgmgr_rwtransaction(); + assert_int_equal(result, ISC_R_SUCCESS); + result = isc_cfgmgr_open("foo"); assert_int_equal(result, ISC_R_NOTFOUND); - result = isc_cfgmgr_newclause("foo"); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("foo"); val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_NONE }; result = isc_cfgmgr_setval("prop1", &val); @@ -977,8 +1069,7 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_delete) { result = isc_cfgmgr_setval("prop2", &val); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_close(); result = isc_cfgmgr_open("foo"); assert_int_equal(result, ISC_R_SUCCESS); @@ -989,13 +1080,12 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_delete) { result = isc_cfgmgr_getval("prop2", &val); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_close(); /* * let's delete prop1 and add a list as prop3 */ - result = isc_cfgmgr_openrw("foo"); + result = isc_cfgmgr_open("foo"); assert_int_equal(result, ISC_R_SUCCESS); result = isc_cfgmgr_setval("prop1", NULL); @@ -1009,8 +1099,7 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_delete) { result = isc_cfgmgr_setnextlistval("prop3", &val); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_close(); result = isc_cfgmgr_open("foo"); assert_int_equal(result, ISC_R_SUCCESS); @@ -1034,13 +1123,12 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_delete) { assert_int_equal(val.type, ISC_CFGMGR_UINT32); assert_int_equal(val.uint32, 456); - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_close(); /* * let's delete prop2 and prop3, the whole close disappears */ - result = isc_cfgmgr_openrw("foo"); + result = isc_cfgmgr_open("foo"); assert_int_equal(result, ISC_R_SUCCESS); result = isc_cfgmgr_setval("prop2", NULL); @@ -1049,8 +1137,7 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_delete) { result = isc_cfgmgr_setval("prop3", NULL); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_close(); result = isc_cfgmgr_open("foo"); assert_int_equal(result, ISC_R_NOTFOUND); @@ -1060,8 +1147,7 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_delete) { * deleting its properties. Another clause exists as well, it * is not deleted. */ - result = isc_cfgmgr_newclause("foo"); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("foo"); val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_NONE }; result = isc_cfgmgr_setval("prop1", &val); @@ -1080,11 +1166,9 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_delete) { result = isc_cfgmgr_setnextlistval("prop3", &val); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_close(); - result = isc_cfgmgr_newclause("fooo"); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("fooo"); val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_NONE }; result = isc_cfgmgr_setval("prop1", &val); @@ -1103,10 +1187,9 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_delete) { result = isc_cfgmgr_setnextlistval("prop3", &val); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_close(); - result = isc_cfgmgr_openrw("foo"); + result = isc_cfgmgr_open("foo"); assert_int_equal(result, ISC_R_SUCCESS); result = isc_cfgmgr_getval("prop1", &val); @@ -1118,8 +1201,7 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_delete) { result = isc_cfgmgr_getval("prop3", &val); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_delclause(); - assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_delclause(); result = isc_cfgmgr_open("foo"); assert_int_equal(result, ISC_R_NOTFOUND); @@ -1146,7 +1228,7 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_delete) { result = isc_cfgmgr_getnextlistval(&val); assert_int_equal(result, ISC_R_NOMORE); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); isc_cfgmgr_deinit(); @@ -1160,13 +1242,16 @@ cfgmgr_threads_worker(void *arg) { /* * This one open ro, so won't block */ + result = isc_cfgmgr_transaction(); + assert_int_equal(result, ISC_R_SUCCESS); + result = isc_cfgmgr_open("foo"); assert_int_equal(result, ISC_R_SUCCESS); sem_wait(&sems[0]); sem_post(&sems[1]); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); return NULL; @@ -1183,25 +1268,30 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_threads) { REQUIRE(sem_init(&sems[0], 0, 0) == 0); REQUIRE(sem_init(&sems[1], 0, 0) == 0); - result = isc_cfgmgr_newclause("foo"); + result = isc_cfgmgr_rwtransaction(); assert_int_equal(result, ISC_R_SUCCESS); + isc_cfgmgr_newclause("foo"); + result = isc_cfgmgr_setval( "p", &(isc_cfgmgr_val_t){ .type = ISC_CFGMGR_NONE }); assert_int_equal(result, ISC_R_SUCCESS); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); REQUIRE(pthread_create(&thread, 0, cfgmgr_threads_worker, &sems) == 0); - result = isc_cfgmgr_openrw("foo"); + result = isc_cfgmgr_rwtransaction(); + assert_int_equal(result, ISC_R_SUCCESS); + + result = isc_cfgmgr_open("foo"); assert_int_equal(result, ISC_R_SUCCESS); REQUIRE(sem_post(&sems[0]) == 0); REQUIRE(sem_wait(&sems[1]) == 0); - result = isc_cfgmgr_close(); + result = isc_cfgmgr_commit(); assert_int_equal(result, ISC_R_SUCCESS); REQUIRE(pthread_join(thread, NULL) == 0); @@ -1212,6 +1302,7 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_threads) { ISC_TEST_LIST_START ISC_TEST_ENTRY(isc_cfgmgr_assertions) ISC_TEST_ENTRY(isc_cfgmgr_rw) +ISC_TEST_ENTRY(isc_cfgmgr_rollback) ISC_TEST_ENTRY(isc_cfgmgr_override) ISC_TEST_ENTRY(isc_cfgmgr_rw_string) ISC_TEST_ENTRY(isc_cfgmgr_list)