explicit transaction commit and rollback API

This commit is contained in:
Colin Vidal
2025-02-24 10:35:39 +01:00
parent 26fa21865c
commit 349103f89c
3 changed files with 340 additions and 285 deletions
+74 -115
View File
@@ -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
+49 -44
View File
@@ -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
+217 -126
View File
@@ -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)