bind9/bin/tests/system/dyndb/driver/lock.c
Evan Hunt a00f9e2f50 [master] merge dyndb
4224.	[func]		Added support for "dyndb", a new interface for loading
			zone data from an external database, developed by
			Red Hat for the FreeIPA project.

			DynDB drivers fully implement the BIND database
			API, and are capable of significantly better
			performance and functionality than DLZ drivers,
			while taking advantage of advanced database
			features not available in BIND such as multi-master
			replication.

			Thanks to Adam Tkac and Petr Spacek of Red Hat.
			[RT #35271]
2015-09-28 23:12:35 -07:00

56 lines
1.7 KiB
C

/*
* Copyright (C) 2014-2015 Red Hat ; see COPYRIGHT for license
*/
#include <config.h>
#include <isc/task.h>
#include <isc/util.h>
#include "lock.h"
/*
* Lock BIND dispatcher and allow only single task to run.
*
* @warning
* All calls to isc_task_beginexclusive() have to operate on the same task
* otherwise it would not be possible to distinguish recursive locking
* from real conflict on the dispatcher lock.
* For this reason this wrapper function always works with inst->task.
* As a result, this function have to be be called only from inst->task.
*
* Recursive locking is allowed. Auxiliary variable pointed to by "statep"
* stores information if last run_exclusive_enter() operation really locked
* something or if the lock was called recursively and was no-op.
*
* The pair (inst, state) used for run_exclusive_enter() has to be
* used for run_exclusive_exit().
*
* @param[in] inst The instance with the only task which is allowed to run.
* @param[in,out] statep Lock state: ISC_R_SUCCESS or ISC_R_LOCKBUSY
*/
void
run_exclusive_enter(sample_instance_t *inst, isc_result_t *statep) {
REQUIRE(statep != NULL);
REQUIRE(*statep == ISC_R_IGNORE);
*statep = isc_task_beginexclusive(inst->task);
RUNTIME_CHECK(*statep == ISC_R_SUCCESS || *statep == ISC_R_LOCKBUSY);
}
/*
* Exit task-exclusive mode.
*
* @param[in] inst The instance used for previous run_exclusive_enter() call.
* @param[in] state Lock state as returned by run_exclusive_enter().
*/
void
run_exclusive_exit(sample_instance_t *inst, isc_result_t state) {
if (state == ISC_R_SUCCESS)
isc_task_endexclusive(inst->task);
else
/* Unlocking recursive lock or the lock was never locked. */
INSIST(state == ISC_R_LOCKBUSY || state == ISC_R_IGNORE);
return;
}