Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be16142ea5 |
@@ -1,6 +1,5 @@
|
|||||||
4951. [protocol] Add "HOME.ARPA" to list of built in empty zones as
|
4951. [protocol] Add "HOME.ARPA" to list of built in empty zones as
|
||||||
per RFC 8375. [GL #273]
|
per RFC 8375. [GL #273]
|
||||||
|
|
||||||
--- 9.13.0 released ---
|
--- 9.13.0 released ---
|
||||||
|
|
||||||
4950. [bug] ISC_SOCKEVENTATTR_TRUNC was not be set. [GL #238]
|
4950. [bug] ISC_SOCKEVENTATTR_TRUNC was not be set. [GL #238]
|
||||||
|
|||||||
+1
-1
@@ -1933,7 +1933,7 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only,
|
|||||||
{
|
{
|
||||||
debug("config line %s", batchline);
|
debug("config line %s", batchline);
|
||||||
bargc = split_batchline(batchline, bargv, 62,
|
bargc = split_batchline(batchline, bargv, 62,
|
||||||
".digrc argv");
|
".digrc argv");
|
||||||
bargv[0] = argv[0];
|
bargv[0] = argv[0];
|
||||||
argv0 = argv[0];
|
argv0 = argv[0];
|
||||||
parse_args(ISC_TRUE, ISC_TRUE,
|
parse_args(ISC_TRUE, ISC_TRUE,
|
||||||
|
|||||||
+7
-7
@@ -8984,7 +8984,7 @@ view_loaded(void *arg) {
|
|||||||
ns_zoneload_t *zl = (ns_zoneload_t *) arg;
|
ns_zoneload_t *zl = (ns_zoneload_t *) arg;
|
||||||
named_server_t *server = zl->server;
|
named_server_t *server = zl->server;
|
||||||
isc_boolean_t reconfig = zl->reconfig;
|
isc_boolean_t reconfig = zl->reconfig;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -8995,8 +8995,8 @@ view_loaded(void *arg) {
|
|||||||
* We use the zoneload reference counter to let us
|
* We use the zoneload reference counter to let us
|
||||||
* know when all views are finished.
|
* know when all views are finished.
|
||||||
*/
|
*/
|
||||||
refs = isc_refcount_decrement(&zl->refs);
|
isc_refcount_decrement(&zl->refs, &refs);
|
||||||
if (refs > 1)
|
if (refs != 0)
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
|
||||||
isc_refcount_destroy(&zl->refs);
|
isc_refcount_destroy(&zl->refs);
|
||||||
@@ -9032,7 +9032,7 @@ load_zones(named_server_t *server, isc_boolean_t init, isc_boolean_t reconfig) {
|
|||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
dns_view_t *view;
|
dns_view_t *view;
|
||||||
ns_zoneload_t *zl;
|
ns_zoneload_t *zl;
|
||||||
int_fast32_t refs;
|
unsigned int refs = 0;
|
||||||
|
|
||||||
zl = isc_mem_get(server->mctx, sizeof (*zl));
|
zl = isc_mem_get(server->mctx, sizeof (*zl));
|
||||||
if (zl == NULL)
|
if (zl == NULL)
|
||||||
@@ -9071,13 +9071,13 @@ load_zones(named_server_t *server, isc_boolean_t init, isc_boolean_t reconfig) {
|
|||||||
* 'dns_view_asyncload' calls view_loaded if there are no
|
* 'dns_view_asyncload' calls view_loaded if there are no
|
||||||
* zones.
|
* zones.
|
||||||
*/
|
*/
|
||||||
isc_refcount_increment(&zl->refs);
|
isc_refcount_increment(&zl->refs, NULL);
|
||||||
CHECK(dns_view_asyncload(view, view_loaded, zl));
|
CHECK(dns_view_asyncload(view, view_loaded, zl));
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
refs = isc_refcount_decrement(&zl->refs);
|
isc_refcount_decrement(&zl->refs, &refs);
|
||||||
if (refs == 1) {
|
if (refs == 0) {
|
||||||
isc_refcount_destroy(&zl->refs);
|
isc_refcount_destroy(&zl->refs);
|
||||||
isc_mem_put(server->mctx, zl, sizeof (*zl));
|
isc_mem_put(server->mctx, zl, sizeof (*zl));
|
||||||
} else if (init) {
|
} else if (init) {
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ attach(dns_db_t *source, dns_db_t **targetp) {
|
|||||||
|
|
||||||
REQUIRE(VALID_SAMPLEDB(sampledb));
|
REQUIRE(VALID_SAMPLEDB(sampledb));
|
||||||
|
|
||||||
isc_refcount_increment(&sampledb->refs);
|
isc_refcount_increment(&sampledb->refs, NULL);
|
||||||
*targetp = source;
|
*targetp = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,14 +85,13 @@ free_sampledb(sampledb_t *sampledb) {
|
|||||||
static void
|
static void
|
||||||
detach(dns_db_t **dbp) {
|
detach(dns_db_t **dbp) {
|
||||||
sampledb_t *sampledb = (sampledb_t *)(*dbp);
|
sampledb_t *sampledb = (sampledb_t *)(*dbp);
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
|
|
||||||
REQUIRE(VALID_SAMPLEDB(sampledb));
|
REQUIRE(VALID_SAMPLEDB(sampledb));
|
||||||
|
|
||||||
refs = isc_refcount_decrement(&sampledb->refs);
|
isc_refcount_decrement(&sampledb->refs, &refs);
|
||||||
if (refs == 1) {
|
if (refs == 0)
|
||||||
free_sampledb(sampledb);
|
free_sampledb(sampledb);
|
||||||
}
|
|
||||||
*dbp = NULL;
|
*dbp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,2 @@
|
|||||||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
|
||||||
;
|
|
||||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
;
|
|
||||||
; See the COPYRIGHT file distributed with this work for additional
|
|
||||||
; information regarding copyright ownership.
|
|
||||||
|
|
||||||
. NS a.root-servers.nil.
|
. NS a.root-servers.nil.
|
||||||
a.root-servers.nil. A 10.53.0.1
|
a.root-servers.nil. A 10.53.0.1
|
||||||
|
|||||||
@@ -1,11 +1,2 @@
|
|||||||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
|
||||||
;
|
|
||||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
;
|
|
||||||
; See the COPYRIGHT file distributed with this work for additional
|
|
||||||
; information regarding copyright ownership.
|
|
||||||
|
|
||||||
. NS a.root-servers.nil.
|
. NS a.root-servers.nil.
|
||||||
a.root-servers.nil. A 10.53.0.1
|
a.root-servers.nil. A 10.53.0.1
|
||||||
|
|||||||
@@ -595,6 +595,9 @@ int sigwait(const unsigned int *set, int *sig);
|
|||||||
/* Define if GOST private keys are encoded in ASN.1. */
|
/* Define if GOST private keys are encoded in ASN.1. */
|
||||||
#undef PREFER_GOSTASN1
|
#undef PREFER_GOSTASN1
|
||||||
|
|
||||||
|
/* The size of `void *', as computed by sizeof. */
|
||||||
|
#undef SIZEOF_VOID_P
|
||||||
|
|
||||||
/* Define to 1 if you have the ANSI C header files. */
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
#undef STDC_HEADERS
|
#undef STDC_HEADERS
|
||||||
|
|
||||||
|
|||||||
+231
-22
@@ -22,10 +22,6 @@ AC_CANONICAL_HOST
|
|||||||
|
|
||||||
AC_PROG_MAKE_SET
|
AC_PROG_MAKE_SET
|
||||||
|
|
||||||
# Set compiler compatibility flags
|
|
||||||
AC_PROG_CC_C99
|
|
||||||
AC_PROG_CPP_WERROR
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# GNU libtool support
|
# GNU libtool support
|
||||||
#
|
#
|
||||||
@@ -418,6 +414,8 @@ if test "X$CC" = "X" ; then
|
|||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_PROG_CC
|
||||||
|
|
||||||
#
|
#
|
||||||
# gcc's optimiser is broken at -02 for ultrasparc
|
# gcc's optimiser is broken at -02 for ultrasparc
|
||||||
#
|
#
|
||||||
@@ -3888,26 +3886,237 @@ AC_CHECK_FUNCS(nanosleep usleep explicit_bzero)
|
|||||||
#
|
#
|
||||||
# Machine architecture dependent features
|
# Machine architecture dependent features
|
||||||
#
|
#
|
||||||
|
have_stdatomic=no
|
||||||
|
AC_MSG_CHECKING(for usable stdatomic.h)
|
||||||
|
AC_TRY_COMPILE([
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
|
],
|
||||||
|
[
|
||||||
|
atomic_int_fast32_t val = 0; atomic_fetch_add_explicit(&val, 1, memory_order_relaxed);
|
||||||
|
],
|
||||||
|
[AC_MSG_RESULT(yes)
|
||||||
|
have_stdatomic=yes
|
||||||
|
ISC_PLATFORM_HAVESTDATOMIC="#define ISC_PLATFORM_HAVESTDATOMIC 1"],
|
||||||
|
[AC_MSG_RESULT(no)
|
||||||
|
have_stdatomic=no
|
||||||
|
ISC_PLATFORM_HAVESTDATOMIC="#undef ISC_PLATFORM_HAVESTDATOMIC"])
|
||||||
|
|
||||||
ISC_ATOMIC_LIBS=
|
AC_ARG_ENABLE(atomic,
|
||||||
if test "$use_threads" = "yes"; then
|
AS_HELP_STRING([--enable-atomic],
|
||||||
AC_MSG_CHECKING(for usable stdatomic.h)
|
[enable machine specific atomic operations [default=autodetect]]),
|
||||||
AC_TRY_COMPILE([#include <stdatomic.h>],
|
enable_atomic="$enableval",
|
||||||
[atomic_int_fast32_t val = 0; atomic_fetch_add_explicit(&val, 1, memory_order_relaxed);],
|
enable_atomic="autodetect")
|
||||||
[AC_MSG_RESULT(yes)],
|
case "$enable_atomic" in
|
||||||
[AC_MSG_ERROR([a compiler with atomics support is required])])
|
yes|''|autodetect)
|
||||||
|
case "$host" in
|
||||||
|
powerpc-ibm-aix*)
|
||||||
|
if test "X$GCC" = "Xyes"; then
|
||||||
|
AC_MSG_CHECKING([if asm("ics"); works])
|
||||||
|
AC_TRY_COMPILE(,[
|
||||||
|
main() { asm("ics"); exit(0); }
|
||||||
|
],
|
||||||
|
[AC_MSG_RESULT(yes)
|
||||||
|
use_atomic=yes],
|
||||||
|
[
|
||||||
|
saved_cflags="$CFLAGS"
|
||||||
|
CFLAGS="$CFLAGS -Wa,-many"
|
||||||
|
AC_TRY_RUN([
|
||||||
|
main() { asm("ics"); exit(0); }
|
||||||
|
],
|
||||||
|
[AC_MSG_RESULT([yes, required -Wa,-many])
|
||||||
|
use_atomic=yes],
|
||||||
|
[AC_MSG_RESULT([no, use_atomic disabled])
|
||||||
|
CFLAGS="$saved_cflags"
|
||||||
|
use_atomic=no],
|
||||||
|
[AC_MSG_RESULT([cross compile, assume yes])
|
||||||
|
CFLAGS="$saved_cflags"
|
||||||
|
use_atomic=yes])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
else
|
||||||
|
use_atomic=yes
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
use_atomic=yes
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
no)
|
||||||
|
have_stdatomic=no
|
||||||
|
ISC_PLATFORM_HAVESTDATOMIC="#undef ISC_PLATFORM_HAVESTDATOMIC"
|
||||||
|
use_atomic=no
|
||||||
|
arch=noatomic
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
AC_MSG_CHECKING(if -latomic is needed to use 64-bit stdatomic.h primitives)
|
if test "X$have_stdatomic" = "Xyes"; then
|
||||||
AC_LINK_IFELSE(
|
AC_MSG_CHECKING(if -latomic is needed to use 64-bit stdatomic.h primitives)
|
||||||
[AC_LANG_PROGRAM([#include <stdatomic.h>],
|
AC_LINK_IFELSE(
|
||||||
[atomic_int_fast64_t val = 0; atomic_fetch_add_explicit(&val, 1, memory_order_relaxed);])],
|
[AC_LANG_PROGRAM([#include <stdatomic.h>],
|
||||||
[AC_MSG_RESULT(no)
|
[atomic_int_fast64_t val = 0; atomic_fetch_add_explicit(&val, 1, memory_order_relaxed);])],
|
||||||
ISC_ATOMIC_LIBS=""],
|
[AC_MSG_RESULT(no)
|
||||||
[AC_MSG_RESULT(yes)
|
ISC_ATOMIC_LIBS=""],
|
||||||
ISC_ATOMIC_LIBS="-latomic"]
|
[AC_MSG_RESULT(yes)
|
||||||
)
|
ISC_ATOMIC_LIBS="-latomic"]
|
||||||
fi # use_threads
|
)
|
||||||
AC_SUBST([ISC_ATOMIC_LIBS])
|
LIBS="$LIBS $ISC_ATOMIC_LIBS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(ISC_PLATFORM_HAVESTDATOMIC)
|
||||||
|
|
||||||
|
ISC_PLATFORM_USEOSFASM="#undef ISC_PLATFORM_USEOSFASM"
|
||||||
|
ISC_PLATFORM_USEGCCASM="#undef ISC_PLATFORM_USEGCCASM"
|
||||||
|
ISC_PLATFORM_USESTDASM="#undef ISC_PLATFORM_USESTDASM"
|
||||||
|
ISC_PLATFORM_USEMACASM="#undef ISC_PLATFORM_USEMACASM"
|
||||||
|
if test "yes" = "$use_atomic"; then
|
||||||
|
AC_CHECK_SIZEOF([void *])
|
||||||
|
have_atomic=yes # set default
|
||||||
|
case "$host" in
|
||||||
|
[i[3456]86-*])
|
||||||
|
# XXX: some old x86 architectures actually do not support
|
||||||
|
# (some of) these operations. Do we need stricter checks?
|
||||||
|
if test $ac_cv_sizeof_void_p = 8; then
|
||||||
|
arch=x86_64
|
||||||
|
have_xaddq=yes
|
||||||
|
else
|
||||||
|
arch=x86_32
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
x86_64-*|amd64-*)
|
||||||
|
if test $ac_cv_sizeof_void_p = 8; then
|
||||||
|
arch=x86_64
|
||||||
|
have_xaddq=yes
|
||||||
|
else
|
||||||
|
arch=x86_32
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
alpha*-*)
|
||||||
|
arch=alpha
|
||||||
|
;;
|
||||||
|
powerpc-*|powerpc64-*)
|
||||||
|
arch=powerpc
|
||||||
|
;;
|
||||||
|
mips-*|mipsel-*|mips64-*|mips64el-*)
|
||||||
|
arch=mips
|
||||||
|
;;
|
||||||
|
ia64-*)
|
||||||
|
arch=ia64
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
have_atomic=no
|
||||||
|
arch=noatomic
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
AC_MSG_CHECKING([architecture type for atomic operations])
|
||||||
|
AC_MSG_RESULT($arch)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "yes" = "$have_atomic"; then
|
||||||
|
AC_MSG_CHECKING([compiler support for inline assembly code])
|
||||||
|
|
||||||
|
compiler=generic
|
||||||
|
# Check whether the compiler supports the assembly syntax we provide.
|
||||||
|
if test "X$GCC" = "Xyes"; then
|
||||||
|
# GCC's ASM extension always works
|
||||||
|
compiler=gcc
|
||||||
|
if test $arch = "x86_64"; then
|
||||||
|
# We can share the same code for gcc with x86_32
|
||||||
|
arch=x86_32
|
||||||
|
fi
|
||||||
|
if test $arch = "powerpc"; then
|
||||||
|
#
|
||||||
|
# The MacOS (and maybe others) uses "r0" for register
|
||||||
|
# zero. Under linux/ibm it is "0" for register 0.
|
||||||
|
# Probe to see if we have a MacOS style assembler.
|
||||||
|
#
|
||||||
|
AC_MSG_CHECKING([Checking for MacOS style assembler syntax])
|
||||||
|
AC_TRY_COMPILE(, [
|
||||||
|
__asm__ volatile ("li r0, 0x0\n"::);
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
compiler="mac"
|
||||||
|
ISC_PLATFORM_USEMACASM="#define ISC_PLATFORM_USEMACASM 1"
|
||||||
|
], [AC_MSG_RESULT(no)])
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
case "$host" in
|
||||||
|
alpha*-dec-osf*)
|
||||||
|
# Tru64 compiler has its own syntax for inline
|
||||||
|
# assembly.
|
||||||
|
AC_TRY_COMPILE(, [
|
||||||
|
#ifndef __DECC
|
||||||
|
#error "unexpected compiler"
|
||||||
|
#endif
|
||||||
|
return (0);],
|
||||||
|
[compiler=osf],)
|
||||||
|
;;
|
||||||
|
powerpc-ibm-aix*)
|
||||||
|
compiler=aix
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
case "$compiler" in
|
||||||
|
gcc)
|
||||||
|
ISC_PLATFORM_USEGCCASM="#define ISC_PLATFORM_USEGCCASM 1"
|
||||||
|
;;
|
||||||
|
osf)
|
||||||
|
ISC_PLATFORM_USEOSFASM="#define ISC_PLATFORM_USEOSFASM 1"
|
||||||
|
;;
|
||||||
|
aix)
|
||||||
|
;;
|
||||||
|
mac)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# See if the generic __asm function works. If not,
|
||||||
|
# we need to disable the atomic operations.
|
||||||
|
AC_TRY_LINK(, [
|
||||||
|
__asm("nop")
|
||||||
|
],
|
||||||
|
[compiler="standard"
|
||||||
|
ISC_PLATFORM_USESTDASM="#define ISC_PLATFORM_USESTDASM 1"],
|
||||||
|
[compiler="not supported (atomic operations disabled)"
|
||||||
|
have_atomic=no
|
||||||
|
arch=noatomic ]);
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
AC_MSG_RESULT($compiler)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "yes" = "$have_atomic"; then
|
||||||
|
ISC_PLATFORM_HAVEXADD="#define ISC_PLATFORM_HAVEXADD 1"
|
||||||
|
ISC_PLATFORM_HAVECMPXCHG="#define ISC_PLATFORM_HAVECMPXCHG 1"
|
||||||
|
ISC_PLATFORM_HAVEATOMICSTORE="#define ISC_PLATFORM_HAVEATOMICSTORE 1"
|
||||||
|
if test "yes" = "$have_xaddq"; then
|
||||||
|
ISC_PLATFORM_HAVEXADDQ="#define ISC_PLATFORM_HAVEXADDQ 1"
|
||||||
|
ISC_PLATFORM_HAVEATOMICSTOREQ="#define ISC_PLATFORM_HAVEATOMICSTOREQ 1"
|
||||||
|
else
|
||||||
|
ISC_PLATFORM_HAVEXADDQ="#undef ISC_PLATFORM_HAVEXADDQ"
|
||||||
|
ISC_PLATFORM_HAVEATOMICSTOREQ="#undef ISC_PLATFORM_HAVEATOMICSTOREQ"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
ISC_PLATFORM_HAVEXADD="#undef ISC_PLATFORM_HAVEXADD"
|
||||||
|
ISC_PLATFORM_HAVECMPXCHG="#undef ISC_PLATFORM_HAVECMPXCHG"
|
||||||
|
ISC_PLATFORM_HAVEATOMICSTORE="#undef ISC_PLATFORM_HAVEATOMICSTORE"
|
||||||
|
ISC_PLATFORM_HAVEXADDQ="#undef ISC_PLATFORM_HAVEXADDQ"
|
||||||
|
ISC_PLATFORM_HAVEATOMICSTOREQ="#undef ISC_PLATFORM_HAVEATOMICSTOREQ"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(ISC_PLATFORM_HAVEXADD)
|
||||||
|
AC_SUBST(ISC_PLATFORM_HAVEXADDQ)
|
||||||
|
AC_SUBST(ISC_PLATFORM_HAVECMPXCHG)
|
||||||
|
AC_SUBST(ISC_PLATFORM_HAVEATOMICSTORE)
|
||||||
|
AC_SUBST(ISC_PLATFORM_HAVEATOMICSTOREQ)
|
||||||
|
|
||||||
|
AC_SUBST(ISC_PLATFORM_USEGCCASM)
|
||||||
|
AC_SUBST(ISC_PLATFORM_USEOSFASM)
|
||||||
|
AC_SUBST(ISC_PLATFORM_USESTDASM)
|
||||||
|
AC_SUBST(ISC_PLATFORM_USEMACASM)
|
||||||
|
|
||||||
|
ISC_ARCH_DIR=$arch
|
||||||
|
AC_SUBST(ISC_ARCH_DIR)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check for __builtin_expect
|
# Check for __builtin_expect
|
||||||
|
|||||||
+1
-8
@@ -15,11 +15,9 @@ top_srcdir = @top_srcdir@
|
|||||||
|
|
||||||
MANOBJS = Bv9ARM.html notes.html
|
MANOBJS = Bv9ARM.html notes.html
|
||||||
|
|
||||||
TXTOBJS = notes.txt
|
|
||||||
|
|
||||||
PDFOBJS = Bv9ARM.pdf notes.pdf
|
PDFOBJS = Bv9ARM.pdf notes.pdf
|
||||||
|
|
||||||
doc man:: ${MANOBJS} ${TXTOBJS} ${PDFOBJS}
|
doc man:: ${MANOBJS} ${PDFOBJS}
|
||||||
|
|
||||||
clean::
|
clean::
|
||||||
rm -f Bv9ARM.aux Bv9ARM.brf Bv9ARM.glo Bv9ARM.idx Bv9ARM.toc
|
rm -f Bv9ARM.aux Bv9ARM.brf Bv9ARM.glo Bv9ARM.idx Bv9ARM.toc
|
||||||
@@ -44,11 +42,6 @@ notes.pdf: notes-wrapper.xml notes.xml releaseinfo.xml pkgversion.xml noteversio
|
|||||||
${XSLTPROC} ${top_srcdir}/doc/xsl/pre-latex.xsl notes-wrapper.xml | \
|
${XSLTPROC} ${top_srcdir}/doc/xsl/pre-latex.xsl notes-wrapper.xml | \
|
||||||
${DBLATEX} -c notes.conf -Pdoc.layout="mainmatter" -o notes.pdf -
|
${DBLATEX} -c notes.conf -Pdoc.layout="mainmatter" -o notes.pdf -
|
||||||
|
|
||||||
notes.txt: notes.html
|
|
||||||
${W3M} -dump -cols 75 -O ascii -T text/html < notes.html | \
|
|
||||||
sed 's/ *$$//' | \
|
|
||||||
sed -e :a -e '/^\n*$$/{$$d;N;};/\n$$/ba' > notes.txt
|
|
||||||
|
|
||||||
# use xmllint to process include
|
# use xmllint to process include
|
||||||
Bv9ARM.html: Bv9ARM-book.xml releaseinfo.xml pkgversion.xml noteversion.xml
|
Bv9ARM.html: Bv9ARM-book.xml releaseinfo.xml pkgversion.xml noteversion.xml
|
||||||
expand Bv9ARM-book.xml | ${XMLLINT} --xinclude - | \
|
expand Bv9ARM-book.xml | ${XMLLINT} --xinclude - | \
|
||||||
|
|||||||
@@ -1,148 +0,0 @@
|
|||||||
Release Notes for BIND Version 9.13.0
|
|
||||||
|
|
||||||
Introduction
|
|
||||||
|
|
||||||
BIND 9.13 is an unstable development release of BIND. This document
|
|
||||||
summarizes new features and functional changes that have been introduced
|
|
||||||
on this branch. With each development release leading up to the stable
|
|
||||||
BIND 9.14 release, this document will be updated with additional features
|
|
||||||
added and bugs fixed.
|
|
||||||
|
|
||||||
Note on Version Numbering
|
|
||||||
|
|
||||||
Prior to BIND 9.13, new feature development releases were tagged as
|
|
||||||
"alpha" and "beta", leading up to the first stable release for a given
|
|
||||||
development branch, which always ended in ".0".
|
|
||||||
|
|
||||||
Now, however, BIND has adopted the "odd-unstable/even-stable" release
|
|
||||||
numbering convention. There will be no "alpha" or "beta" releases in the
|
|
||||||
9.13 branch, only increasing version numbers. So, for example, what would
|
|
||||||
previously have been called 9.13.0a1, 9.13.0a2, 9.13.0b1, and so on, will
|
|
||||||
instead be called 9.13.0, 9.13.1, 9.13.2, etc.
|
|
||||||
|
|
||||||
The first stable release from this development branch will be renamed as
|
|
||||||
9.14.0. Thereafter, maintenance releases will continue on the 9.14 branch,
|
|
||||||
while unstable feature development proceeds in 9.15.
|
|
||||||
|
|
||||||
Download
|
|
||||||
|
|
||||||
The latest versions of BIND 9 software can always be found at http://
|
|
||||||
www.isc.org/downloads/. There you will find additional information about
|
|
||||||
each release, source code, and pre-compiled versions for Microsoft Windows
|
|
||||||
operating systems.
|
|
||||||
|
|
||||||
Security Fixes
|
|
||||||
|
|
||||||
* None.
|
|
||||||
|
|
||||||
New Features
|
|
||||||
|
|
||||||
* BIND now can be compiled against the libidn2 library to add IDNA2008
|
|
||||||
support. Previously, BIND supported IDNA2003 using the (now obsolete
|
|
||||||
and unsupported) idnkit-1 library.
|
|
||||||
|
|
||||||
* named now supports the "root key sentinel" mechanism. This enables
|
|
||||||
validating resolvers to indicate to which trust anchors are configured
|
|
||||||
for the root, so that information about root key rollover status can
|
|
||||||
be gathered. To disable this feature, add root-key-sentinel no; to
|
|
||||||
named.conf.
|
|
||||||
|
|
||||||
* The dnskey-sig-validity option allows the sig-validity-interval to be
|
|
||||||
overriden for signatures covering DNSKEY RRsets. [GL #145]
|
|
||||||
|
|
||||||
Removed Features
|
|
||||||
|
|
||||||
* dnssec-keygen can no longer generate HMAC keys for TSIG
|
|
||||||
authentication. Use tsig-keygen to generate these keys. [RT #46404]
|
|
||||||
|
|
||||||
* Support for OpenSSL 0.9.x has been removed. OpenSSL version 1.0.0 or
|
|
||||||
greater, or LibreSSL is now required.
|
|
||||||
|
|
||||||
* The configure --enable-seccomp option, which formerly turned on
|
|
||||||
system-call filtering on Linux, has been removed. [GL #93]
|
|
||||||
|
|
||||||
* IPv4 addresses in forms other than dotted-quad are no longer accepted
|
|
||||||
in master files. [GL #13] [GL #56]
|
|
||||||
|
|
||||||
* IDNA2003 support via (bundled) idnkit-1.0 has been removed.
|
|
||||||
|
|
||||||
* The "rbtdb64" database implementation (a parallel implementation of
|
|
||||||
"rbt") has been removed. [GL #217]
|
|
||||||
|
|
||||||
* The -r randomdev option to explicitly select random device has been
|
|
||||||
removed from the ddns-confgen, rndc-confgen, nsupdate, dnssec-confgen,
|
|
||||||
and dnssec-signzone commands.
|
|
||||||
|
|
||||||
The -p option to use pseudo-random data has been removed from the
|
|
||||||
dnssec-signzone command.
|
|
||||||
|
|
||||||
Feature Changes
|
|
||||||
|
|
||||||
* BIND will now always use the best CSPRNG (cryptographically-secure
|
|
||||||
pseudo-random number generator) available on the platform where it is
|
|
||||||
compiled. It will use arc4random() family of functions on BSD
|
|
||||||
operating systems, getrandom() on Linux and Solaris, CryptGenRandom on
|
|
||||||
Windows, and the selected cryptography provider library (OpenSSL or
|
|
||||||
PKCS#11) as the last resort. [GL #221]
|
|
||||||
|
|
||||||
* BIND can no longer be built without DNSSEC support. A cryptography
|
|
||||||
provder (i.e., OpenSSL or a hardware service module with PKCS#11
|
|
||||||
support) must be available. [GL #244]
|
|
||||||
|
|
||||||
* Zone types primary and secondary are now available as synonyms for
|
|
||||||
master and slave, respectively, in named.conf.
|
|
||||||
|
|
||||||
* named will now log a warning if the old root DNSSEC key is explicitly
|
|
||||||
configured and has not been updated. [RT #43670]
|
|
||||||
|
|
||||||
* dig +nssearch will now list name servers that have timed out, in
|
|
||||||
addition to those that respond. [GL #64]
|
|
||||||
|
|
||||||
* dig +noidnin can be used to disable IDN processing on the input domain
|
|
||||||
name, when BIND is compiled with IDN support.
|
|
||||||
|
|
||||||
* Up to 64 response-policy zones are now supported by default;
|
|
||||||
previously the limit was 32. [GL #123]
|
|
||||||
|
|
||||||
* Several configuration options for time periods can now use TTL value
|
|
||||||
suffixes (for example, 2h or 1d) in addition to an integer number of
|
|
||||||
seconds. These include fstrm-set-reopen-interval, interface-interval,
|
|
||||||
max-cache-ttl, max-ncache-ttl, max-policy-ttl, and min-update-interval
|
|
||||||
. [GL #203]
|
|
||||||
|
|
||||||
Bug Fixes
|
|
||||||
|
|
||||||
* None.
|
|
||||||
|
|
||||||
License
|
|
||||||
|
|
||||||
BIND is open source software licenced under the terms of the Mozilla
|
|
||||||
Public License, version 2.0 (see the LICENSE file for the full text).
|
|
||||||
|
|
||||||
The license requires that if you make changes to BIND and distribute them
|
|
||||||
outside your organization, those changes must be published under the same
|
|
||||||
license. It does not require that you publish or disclose anything other
|
|
||||||
than the changes you have made to our software. This requirement does not
|
|
||||||
affect anyone who is using BIND, with or without modifications, without
|
|
||||||
redistributing it, nor anyone redistributing BIND without changes.
|
|
||||||
|
|
||||||
Those wishing to discuss license compliance may contact ISC at https://
|
|
||||||
www.isc.org/mission/contact/.
|
|
||||||
|
|
||||||
End of Life
|
|
||||||
|
|
||||||
BIND 9.13 is an unstable development branch. When its development is
|
|
||||||
complete, it will be renamed to BIND 9.14, which will be a stable branch.
|
|
||||||
|
|
||||||
The end of life date for BIND 9.14 has not yet been determined. For those
|
|
||||||
needing long term support, the current Extended Support Version (ESV) is
|
|
||||||
BIND 9.11, which will be supported until at least December 2021. See
|
|
||||||
https://www.isc.org/downloads/software-support-policy/ for details of
|
|
||||||
ISC's software support policy.
|
|
||||||
|
|
||||||
Thank You
|
|
||||||
|
|
||||||
Thank you to everyone who assisted us in making this release possible. If
|
|
||||||
you would like to contribute to ISC to assist us in continuing to make
|
|
||||||
quality open source software, please visit our donations page at http://
|
|
||||||
www.isc.org/donate/.
|
|
||||||
@@ -6,6 +6,7 @@ Here is a more formal statement of the important database design
|
|||||||
rules. Each rule has a 5 character mnemonic, for use in source code
|
rules. Each rule has a 5 character mnemonic, for use in source code
|
||||||
comments.
|
comments.
|
||||||
|
|
||||||
|
|
||||||
Reference Safety [DBREF]
|
Reference Safety [DBREF]
|
||||||
|
|
||||||
1) Any node reference retrieved from the database shall remain
|
1) Any node reference retrieved from the database shall remain
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ See COPYRIGHT in the source root or http://isc.org/copyright.html for terms.
|
|||||||
We do hourly test builds of the bind9 tree. This is an attempt to
|
We do hourly test builds of the bind9 tree. This is an attempt to
|
||||||
document how they work.
|
document how they work.
|
||||||
|
|
||||||
|
|
||||||
* How things work
|
* How things work
|
||||||
|
|
||||||
The scripts driving the build system are in ~wpk/b9t. They are now
|
The scripts driving the build system are in ~wpk/b9t. They are now
|
||||||
|
|||||||
+4
-5
@@ -503,7 +503,7 @@ void
|
|||||||
dns_acl_attach(dns_acl_t *source, dns_acl_t **target) {
|
dns_acl_attach(dns_acl_t *source, dns_acl_t **target) {
|
||||||
REQUIRE(DNS_ACL_VALID(source));
|
REQUIRE(DNS_ACL_VALID(source));
|
||||||
|
|
||||||
isc_refcount_increment(&source->refcount);
|
isc_refcount_increment(&source->refcount, NULL);
|
||||||
*target = source;
|
*target = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,14 +536,13 @@ destroy(dns_acl_t *dacl) {
|
|||||||
void
|
void
|
||||||
dns_acl_detach(dns_acl_t **aclp) {
|
dns_acl_detach(dns_acl_t **aclp) {
|
||||||
dns_acl_t *acl = *aclp;
|
dns_acl_t *acl = *aclp;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
|
|
||||||
REQUIRE(DNS_ACL_VALID(acl));
|
REQUIRE(DNS_ACL_VALID(acl));
|
||||||
|
|
||||||
refs = isc_refcount_decrement(&acl->refcount);
|
isc_refcount_decrement(&acl->refcount, &refs);
|
||||||
if (refs == 1) {
|
if (refs == 0)
|
||||||
destroy(acl);
|
destroy(acl);
|
||||||
}
|
|
||||||
*aclp = NULL;
|
*aclp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-12
@@ -230,7 +230,7 @@ dns_catz_entry_copy(dns_catz_zone_t *zone, const dns_catz_entry_t *entry,
|
|||||||
void
|
void
|
||||||
dns_catz_entry_attach(dns_catz_entry_t *entry, dns_catz_entry_t **entryp) {
|
dns_catz_entry_attach(dns_catz_entry_t *entry, dns_catz_entry_t **entryp) {
|
||||||
REQUIRE(entryp != NULL && *entryp == NULL);
|
REQUIRE(entryp != NULL && *entryp == NULL);
|
||||||
isc_refcount_increment(&entry->refs);
|
isc_refcount_increment(&entry->refs, NULL);
|
||||||
*entryp = entry;
|
*entryp = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ void
|
|||||||
dns_catz_entry_detach(dns_catz_zone_t *zone, dns_catz_entry_t **entryp) {
|
dns_catz_entry_detach(dns_catz_zone_t *zone, dns_catz_entry_t **entryp) {
|
||||||
dns_catz_entry_t *entry;
|
dns_catz_entry_t *entry;
|
||||||
isc_mem_t *mctx;
|
isc_mem_t *mctx;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
|
|
||||||
REQUIRE(entryp != NULL && *entryp != NULL);
|
REQUIRE(entryp != NULL && *entryp != NULL);
|
||||||
|
|
||||||
@@ -247,8 +247,8 @@ dns_catz_entry_detach(dns_catz_zone_t *zone, dns_catz_entry_t **entryp) {
|
|||||||
|
|
||||||
mctx = zone->catzs->mctx;
|
mctx = zone->catzs->mctx;
|
||||||
|
|
||||||
refs = isc_refcount_decrement(&entry->refs);
|
isc_refcount_decrement(&entry->refs, &refs);
|
||||||
if (refs == 1) {
|
if (refs == 0) {
|
||||||
dns_catz_options_free(&entry->opts, mctx);
|
dns_catz_options_free(&entry->opts, mctx);
|
||||||
if (dns_name_dynamic(&entry->name))
|
if (dns_name_dynamic(&entry->name))
|
||||||
dns_name_free(&entry->name, mctx);
|
dns_name_free(&entry->name, mctx);
|
||||||
@@ -728,7 +728,7 @@ void
|
|||||||
dns_catz_catzs_attach(dns_catz_zones_t *catzs, dns_catz_zones_t **catzsp) {
|
dns_catz_catzs_attach(dns_catz_zones_t *catzs, dns_catz_zones_t **catzsp) {
|
||||||
REQUIRE(catzsp != NULL && *catzsp == NULL);
|
REQUIRE(catzsp != NULL && *catzsp == NULL);
|
||||||
|
|
||||||
isc_refcount_increment(&catzs->refs);
|
isc_refcount_increment(&catzs->refs, NULL);
|
||||||
*catzsp = catzs;
|
*catzsp = catzs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -736,7 +736,7 @@ void
|
|||||||
dns_catz_zone_attach(dns_catz_zone_t *zone, dns_catz_zone_t **zonep) {
|
dns_catz_zone_attach(dns_catz_zone_t *zone, dns_catz_zone_t **zonep) {
|
||||||
REQUIRE(zonep != NULL && *zonep == NULL);
|
REQUIRE(zonep != NULL && *zonep == NULL);
|
||||||
|
|
||||||
isc_refcount_increment(&zone->refs);
|
isc_refcount_increment(&zone->refs, NULL);
|
||||||
*zonep = zone;
|
*zonep = zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -746,14 +746,14 @@ dns_catz_zone_detach(dns_catz_zone_t **zonep) {
|
|||||||
dns_catz_zone_t *zone;
|
dns_catz_zone_t *zone;
|
||||||
isc_ht_iter_t *iter = NULL;
|
isc_ht_iter_t *iter = NULL;
|
||||||
isc_mem_t *mctx;
|
isc_mem_t *mctx;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
|
|
||||||
REQUIRE(zonep != NULL && *zonep != NULL);
|
REQUIRE(zonep != NULL && *zonep != NULL);
|
||||||
|
|
||||||
zone = *zonep;
|
zone = *zonep;
|
||||||
*zonep = NULL;
|
*zonep = NULL;
|
||||||
refs = isc_refcount_decrement(&zone->refs);
|
isc_refcount_decrement(&zone->refs, &refs);
|
||||||
if (refs == 1) {
|
if (refs == 0) {
|
||||||
if (zone->entries != NULL) {
|
if (zone->entries != NULL) {
|
||||||
result = isc_ht_iter_create(zone->entries, &iter);
|
result = isc_ht_iter_create(zone->entries, &iter);
|
||||||
INSIST(result == ISC_R_SUCCESS);
|
INSIST(result == ISC_R_SUCCESS);
|
||||||
@@ -802,7 +802,7 @@ dns_catz_catzs_detach(dns_catz_zones_t ** catzsp) {
|
|||||||
dns_catz_zones_t *catzs;
|
dns_catz_zones_t *catzs;
|
||||||
isc_ht_iter_t *iter = NULL;
|
isc_ht_iter_t *iter = NULL;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
dns_catz_zone_t *zone;
|
dns_catz_zone_t *zone;
|
||||||
|
|
||||||
|
|
||||||
@@ -811,9 +811,9 @@ dns_catz_catzs_detach(dns_catz_zones_t ** catzsp) {
|
|||||||
REQUIRE(catzs != NULL);
|
REQUIRE(catzs != NULL);
|
||||||
|
|
||||||
*catzsp = NULL;
|
*catzsp = NULL;
|
||||||
refs = isc_refcount_decrement(&catzs->refs);
|
isc_refcount_decrement(&catzs->refs, &refs);
|
||||||
|
|
||||||
if (refs == 1) {
|
if (refs == 0) {
|
||||||
DESTROYLOCK(&catzs->lock);
|
DESTROYLOCK(&catzs->lock);
|
||||||
if (catzs->zones != NULL) {
|
if (catzs->zones != NULL) {
|
||||||
result = isc_ht_iter_create(catzs->zones, &iter);
|
result = isc_ht_iter_create(catzs->zones, &iter);
|
||||||
|
|||||||
+1
-1
@@ -529,7 +529,7 @@ dns_dt_attach(dns_dtenv_t *source, dns_dtenv_t **destp) {
|
|||||||
REQUIRE(VALID_DTENV(source));
|
REQUIRE(VALID_DTENV(source));
|
||||||
REQUIRE(destp != NULL && *destp == NULL);
|
REQUIRE(destp != NULL && *destp == NULL);
|
||||||
|
|
||||||
isc_refcount_increment(&source->refcount);
|
isc_refcount_increment(&source->refcount, NULL);
|
||||||
*destp = source;
|
*destp = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-6
@@ -1163,7 +1163,7 @@ dst_key_attach(dst_key_t *source, dst_key_t **target) {
|
|||||||
REQUIRE(target != NULL && *target == NULL);
|
REQUIRE(target != NULL && *target == NULL);
|
||||||
REQUIRE(VALID_KEY(source));
|
REQUIRE(VALID_KEY(source));
|
||||||
|
|
||||||
isc_refcount_increment(&source->refs);
|
isc_refcount_increment(&source->refs, NULL);
|
||||||
*target = source;
|
*target = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1171,7 +1171,7 @@ void
|
|||||||
dst_key_free(dst_key_t **keyp) {
|
dst_key_free(dst_key_t **keyp) {
|
||||||
isc_mem_t *mctx;
|
isc_mem_t *mctx;
|
||||||
dst_key_t *key;
|
dst_key_t *key;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
|
|
||||||
REQUIRE(dst_initialized == ISC_TRUE);
|
REQUIRE(dst_initialized == ISC_TRUE);
|
||||||
REQUIRE(keyp != NULL && VALID_KEY(*keyp));
|
REQUIRE(keyp != NULL && VALID_KEY(*keyp));
|
||||||
@@ -1179,10 +1179,9 @@ dst_key_free(dst_key_t **keyp) {
|
|||||||
key = *keyp;
|
key = *keyp;
|
||||||
mctx = key->mctx;
|
mctx = key->mctx;
|
||||||
|
|
||||||
refs = isc_refcount_decrement(&key->refs);
|
isc_refcount_decrement(&key->refs, &refs);
|
||||||
if (refs > 1) {
|
if (refs != 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
isc_refcount_destroy(&key->refs);
|
isc_refcount_destroy(&key->refs);
|
||||||
if (key->keydata.generic != NULL) {
|
if (key->keydata.generic != NULL) {
|
||||||
@@ -1876,7 +1875,7 @@ static isc_result_t
|
|||||||
algorithm_status(unsigned int alg) {
|
algorithm_status(unsigned int alg) {
|
||||||
REQUIRE(dst_initialized == ISC_TRUE);
|
REQUIRE(dst_initialized == ISC_TRUE);
|
||||||
|
|
||||||
if (dst_algorithm_supported(alg)) {
|
if (dst_algorithm_supported(alg)) {
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
return (DST_R_UNSUPPORTEDALG);
|
return (DST_R_UNSUPPORTEDALG);
|
||||||
|
|||||||
+85
-11
@@ -38,6 +38,12 @@ ISC_LANG_BEGINDECLS
|
|||||||
#define DNS_RBTFIND_NOPREDECESSOR 0x04
|
#define DNS_RBTFIND_NOPREDECESSOR 0x04
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
#ifndef DNS_RBT_USEISCREFCOUNT
|
||||||
|
#ifdef ISC_REFCOUNT_HAVEATOMIC
|
||||||
|
#define DNS_RBT_USEISCREFCOUNT 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DNS_RBT_USEMAGIC 1
|
#define DNS_RBT_USEMAGIC 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -154,8 +160,13 @@ struct dns_rbtnode {
|
|||||||
unsigned int dirty:1;
|
unsigned int dirty:1;
|
||||||
unsigned int wild:1;
|
unsigned int wild:1;
|
||||||
unsigned int locknum:DNS_RBT_LOCKLENGTH;
|
unsigned int locknum:DNS_RBT_LOCKLENGTH;
|
||||||
|
#ifndef DNS_RBT_USEISCREFCOUNT
|
||||||
|
unsigned int references:DNS_RBT_REFLENGTH;
|
||||||
|
#endif
|
||||||
unsigned int :0; /* end of bitfields c/o node lock */
|
unsigned int :0; /* end of bitfields c/o node lock */
|
||||||
|
#ifdef DNS_RBT_USEISCREFCOUNT
|
||||||
isc_refcount_t references; /* note that this is not in the bitfield */
|
isc_refcount_t references; /* note that this is not in the bitfield */
|
||||||
|
#endif
|
||||||
/*@}*/
|
/*@}*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1044,18 +1055,81 @@ dns_rbtnodechain_nextflat(dns_rbtnodechain_t *chain, dns_name_t *name);
|
|||||||
* The following macros provide a common interface to these operations,
|
* The following macros provide a common interface to these operations,
|
||||||
* hiding the back-end. The usage is the same as that of isc_refcount_xxx().
|
* hiding the back-end. The usage is the same as that of isc_refcount_xxx().
|
||||||
*/
|
*/
|
||||||
#define dns_rbtnode_refinit(node, n) \
|
#ifdef DNS_RBT_USEISCREFCOUNT
|
||||||
isc_refcount_init(&(node)->references, (n))
|
#define dns_rbtnode_refinit(node, n) \
|
||||||
#define dns_rbtnode_refdestroy(node) \
|
do { \
|
||||||
isc_refcount_destroy(&(node)->references)
|
isc_refcount_init(&(node)->references, (n)); \
|
||||||
#define dns_rbtnode_refcurrent(node) \
|
} while (0)
|
||||||
|
#define dns_rbtnode_refdestroy(node) \
|
||||||
|
do { \
|
||||||
|
isc_refcount_destroy(&(node)->references); \
|
||||||
|
} while (0)
|
||||||
|
#define dns_rbtnode_refcurrent(node) \
|
||||||
isc_refcount_current(&(node)->references)
|
isc_refcount_current(&(node)->references)
|
||||||
#define dns_rbtnode_refincrement0(node) \
|
#define dns_rbtnode_refincrement0(node, refs) \
|
||||||
isc_refcount_increment0(&(node)->references)
|
do { \
|
||||||
#define dns_rbtnode_refincrement(node) \
|
isc_refcount_increment0(&(node)->references, (refs)); \
|
||||||
isc_refcount_increment(&(node)->references)
|
} while (0)
|
||||||
#define dns_rbtnode_refdecrement(node) \
|
#define dns_rbtnode_refincrement(node, refs) \
|
||||||
isc_refcount_decrement(&(node)->references)
|
do { \
|
||||||
|
isc_refcount_increment(&(node)->references, (refs)); \
|
||||||
|
} while (0)
|
||||||
|
#define dns_rbtnode_refdecrement(node, refs) \
|
||||||
|
do { \
|
||||||
|
isc_refcount_decrement(&(node)->references, (refs)); \
|
||||||
|
} while (0)
|
||||||
|
#else /* DNS_RBT_USEISCREFCOUNT */
|
||||||
|
#define dns_rbtnode_refinit(node, n) ((node)->references = (n))
|
||||||
|
#define dns_rbtnode_refdestroy(node) ISC_REQUIRE((node)->references == 0)
|
||||||
|
#define dns_rbtnode_refcurrent(node) ((node)->references)
|
||||||
|
|
||||||
|
#if (__STDC_VERSION__ + 0) >= 199901L || defined __GNUC__
|
||||||
|
static inline void
|
||||||
|
dns_rbtnode_refincrement0(dns_rbtnode_t *node, unsigned int *refs) {
|
||||||
|
node->references++;
|
||||||
|
if (refs != NULL)
|
||||||
|
*refs = node->references;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
dns_rbtnode_refincrement(dns_rbtnode_t *node, unsigned int *refs) {
|
||||||
|
ISC_REQUIRE(node->references > 0);
|
||||||
|
node->references++;
|
||||||
|
if (refs != NULL)
|
||||||
|
*refs = node->references;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
dns_rbtnode_refdecrement(dns_rbtnode_t *node, unsigned int *refs) {
|
||||||
|
ISC_REQUIRE(node->references > 0);
|
||||||
|
node->references--;
|
||||||
|
if (refs != NULL)
|
||||||
|
*refs = node->references;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define dns_rbtnode_refincrement0(node, refs) \
|
||||||
|
do { \
|
||||||
|
unsigned int *_tmp = (unsigned int *)(refs); \
|
||||||
|
(node)->references++; \
|
||||||
|
if ((_tmp) != NULL) \
|
||||||
|
(*_tmp) = (node)->references; \
|
||||||
|
} while (0)
|
||||||
|
#define dns_rbtnode_refincrement(node, refs) \
|
||||||
|
do { \
|
||||||
|
ISC_REQUIRE((node)->references > 0); \
|
||||||
|
(node)->references++; \
|
||||||
|
if ((refs) != NULL) \
|
||||||
|
(*refs) = (node)->references; \
|
||||||
|
} while (0)
|
||||||
|
#define dns_rbtnode_refdecrement(node, refs) \
|
||||||
|
do { \
|
||||||
|
ISC_REQUIRE((node)->references > 0); \
|
||||||
|
(node)->references--; \
|
||||||
|
if ((refs) != NULL) \
|
||||||
|
(*refs) = (node)->references; \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
#endif /* DNS_RBT_USEISCREFCOUNT */
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_rbtnode_nodename(dns_rbtnode_t *node, dns_name_t *name);
|
dns_rbtnode_nodename(dns_rbtnode_t *node, dns_name_t *name);
|
||||||
|
|||||||
+4
-5
@@ -140,19 +140,18 @@ dns_iptable_merge(dns_iptable_t *tab, dns_iptable_t *source, isc_boolean_t pos)
|
|||||||
void
|
void
|
||||||
dns_iptable_attach(dns_iptable_t *source, dns_iptable_t **target) {
|
dns_iptable_attach(dns_iptable_t *source, dns_iptable_t **target) {
|
||||||
REQUIRE(DNS_IPTABLE_VALID(source));
|
REQUIRE(DNS_IPTABLE_VALID(source));
|
||||||
isc_refcount_increment(&source->refcount);
|
isc_refcount_increment(&source->refcount, NULL);
|
||||||
*target = source;
|
*target = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_iptable_detach(dns_iptable_t **tabp) {
|
dns_iptable_detach(dns_iptable_t **tabp) {
|
||||||
dns_iptable_t *tab = *tabp;
|
dns_iptable_t *tab = *tabp;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
REQUIRE(DNS_IPTABLE_VALID(tab));
|
REQUIRE(DNS_IPTABLE_VALID(tab));
|
||||||
refs = isc_refcount_decrement(&tab->refcount);
|
isc_refcount_decrement(&tab->refcount, &refs);
|
||||||
if (refs == 1) {
|
if (refs == 0)
|
||||||
destroy_iptable(tab);
|
destroy_iptable(tab);
|
||||||
}
|
|
||||||
*tabp = NULL;
|
*tabp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-16
@@ -129,7 +129,7 @@ dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp) {
|
|||||||
REQUIRE(VALID_KEYTABLE(source));
|
REQUIRE(VALID_KEYTABLE(source));
|
||||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||||
|
|
||||||
isc_refcount_increment(&source->references);
|
isc_refcount_increment(&source->references, NULL);
|
||||||
|
|
||||||
*targetp = source;
|
*targetp = source;
|
||||||
}
|
}
|
||||||
@@ -137,7 +137,7 @@ dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp) {
|
|||||||
void
|
void
|
||||||
dns_keytable_detach(dns_keytable_t **keytablep) {
|
dns_keytable_detach(dns_keytable_t **keytablep) {
|
||||||
dns_keytable_t *keytable;
|
dns_keytable_t *keytable;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Detach *keytablep from its keytable.
|
* Detach *keytablep from its keytable.
|
||||||
@@ -148,8 +148,8 @@ dns_keytable_detach(dns_keytable_t **keytablep) {
|
|||||||
keytable = *keytablep;
|
keytable = *keytablep;
|
||||||
*keytablep = NULL;
|
*keytablep = NULL;
|
||||||
|
|
||||||
refs = isc_refcount_decrement(&keytable->references);
|
isc_refcount_decrement(&keytable->references, &refs);
|
||||||
if (refs == 1) {
|
if (refs == 0) {
|
||||||
INSIST(isc_refcount_current(&keytable->active_nodes) == 0);
|
INSIST(isc_refcount_current(&keytable->active_nodes) == 0);
|
||||||
isc_refcount_destroy(&keytable->active_nodes);
|
isc_refcount_destroy(&keytable->active_nodes);
|
||||||
isc_refcount_destroy(&keytable->references);
|
isc_refcount_destroy(&keytable->references);
|
||||||
@@ -422,7 +422,7 @@ dns_keytable_find(dns_keytable_t *keytable, const dns_name_t *keyname,
|
|||||||
DNS_RBTFIND_NOOPTIONS, NULL, NULL);
|
DNS_RBTFIND_NOOPTIONS, NULL, NULL);
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
if (node->data != NULL) {
|
if (node->data != NULL) {
|
||||||
isc_refcount_increment0(&keytable->active_nodes);
|
isc_refcount_increment0(&keytable->active_nodes, NULL);
|
||||||
dns_keynode_attach(node->data, keynodep);
|
dns_keynode_attach(node->data, keynodep);
|
||||||
} else
|
} else
|
||||||
result = ISC_R_NOTFOUND;
|
result = ISC_R_NOTFOUND;
|
||||||
@@ -450,7 +450,7 @@ dns_keytable_nextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
|
|||||||
return (ISC_R_NOTFOUND);
|
return (ISC_R_NOTFOUND);
|
||||||
|
|
||||||
dns_keynode_attach(keynode->next, nextnodep);
|
dns_keynode_attach(keynode->next, nextnodep);
|
||||||
isc_refcount_increment(&keytable->active_nodes);
|
isc_refcount_increment(&keytable->active_nodes, NULL);
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
@@ -498,7 +498,7 @@ dns_keytable_findkeynode(dns_keytable_t *keytable, const dns_name_t *name,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (knode != NULL) {
|
if (knode != NULL) {
|
||||||
isc_refcount_increment0(&keytable->active_nodes);
|
isc_refcount_increment0(&keytable->active_nodes, NULL);
|
||||||
dns_keynode_attach(knode, keynodep);
|
dns_keynode_attach(knode, keynodep);
|
||||||
} else
|
} else
|
||||||
result = DNS_R_PARTIALMATCH;
|
result = DNS_R_PARTIALMATCH;
|
||||||
@@ -536,7 +536,7 @@ dns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (knode != NULL) {
|
if (knode != NULL) {
|
||||||
isc_refcount_increment(&keytable->active_nodes);
|
isc_refcount_increment(&keytable->active_nodes, NULL);
|
||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
dns_keynode_attach(knode, nextnodep);
|
dns_keynode_attach(knode, nextnodep);
|
||||||
} else
|
} else
|
||||||
@@ -585,7 +585,7 @@ dns_keytable_attachkeynode(dns_keytable_t *keytable, dns_keynode_t *source,
|
|||||||
REQUIRE(VALID_KEYNODE(source));
|
REQUIRE(VALID_KEYNODE(source));
|
||||||
REQUIRE(target != NULL && *target == NULL);
|
REQUIRE(target != NULL && *target == NULL);
|
||||||
|
|
||||||
isc_refcount_increment(&keytable->active_nodes);
|
isc_refcount_increment(&keytable->active_nodes, NULL);
|
||||||
|
|
||||||
dns_keynode_attach(source, target);
|
dns_keynode_attach(source, target);
|
||||||
}
|
}
|
||||||
@@ -600,7 +600,7 @@ dns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep)
|
|||||||
REQUIRE(VALID_KEYTABLE(keytable));
|
REQUIRE(VALID_KEYTABLE(keytable));
|
||||||
REQUIRE(keynodep != NULL && VALID_KEYNODE(*keynodep));
|
REQUIRE(keynodep != NULL && VALID_KEYNODE(*keynodep));
|
||||||
|
|
||||||
isc_refcount_decrement(&keytable->active_nodes);
|
isc_refcount_decrement(&keytable->active_nodes, NULL);
|
||||||
dns_keynode_detach(keytable->mctx, keynodep);
|
dns_keynode_detach(keytable->mctx, keynodep);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -746,7 +746,7 @@ dns_keytable_forall(dns_keytable_t *keytable,
|
|||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
isc_refcount_increment0(&keytable->active_nodes);
|
isc_refcount_increment0(&keytable->active_nodes, NULL);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
dns_rbtnodechain_current(&chain, NULL, NULL, &node);
|
dns_rbtnodechain_current(&chain, NULL, NULL, &node);
|
||||||
if (node->data != NULL)
|
if (node->data != NULL)
|
||||||
@@ -758,7 +758,7 @@ dns_keytable_forall(dns_keytable_t *keytable,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isc_refcount_decrement(&keytable->active_nodes);
|
isc_refcount_decrement(&keytable->active_nodes, NULL);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
dns_rbtnodechain_invalidate(&chain);
|
dns_rbtnodechain_invalidate(&chain);
|
||||||
@@ -822,17 +822,17 @@ dns_keynode_create(isc_mem_t *mctx, dns_keynode_t **target) {
|
|||||||
void
|
void
|
||||||
dns_keynode_attach(dns_keynode_t *source, dns_keynode_t **target) {
|
dns_keynode_attach(dns_keynode_t *source, dns_keynode_t **target) {
|
||||||
REQUIRE(VALID_KEYNODE(source));
|
REQUIRE(VALID_KEYNODE(source));
|
||||||
isc_refcount_increment(&source->refcount);
|
isc_refcount_increment(&source->refcount, NULL);
|
||||||
*target = source;
|
*target = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_keynode_detach(isc_mem_t *mctx, dns_keynode_t **keynode) {
|
dns_keynode_detach(isc_mem_t *mctx, dns_keynode_t **keynode) {
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
dns_keynode_t *node = *keynode;
|
dns_keynode_t *node = *keynode;
|
||||||
REQUIRE(VALID_KEYNODE(node));
|
REQUIRE(VALID_KEYNODE(node));
|
||||||
refs = isc_refcount_decrement(&node->refcount);
|
isc_refcount_decrement(&node->refcount, &refs);
|
||||||
if (refs == 1) {
|
if (refs == 0) {
|
||||||
if (node->key != NULL)
|
if (node->key != NULL)
|
||||||
dst_key_free(&node->key);
|
dst_key_free(&node->key);
|
||||||
isc_refcount_destroy(&node->refcount);
|
isc_refcount_destroy(&node->refcount);
|
||||||
|
|||||||
+4
-4
@@ -58,19 +58,19 @@ struct dns_nta {
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
nta_ref(dns_nta_t *nta) {
|
nta_ref(dns_nta_t *nta) {
|
||||||
isc_refcount_increment(&nta->refcount);
|
isc_refcount_increment(&nta->refcount, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nta_detach(isc_mem_t *mctx, dns_nta_t **ntap) {
|
nta_detach(isc_mem_t *mctx, dns_nta_t **ntap) {
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
dns_nta_t *nta = *ntap;
|
dns_nta_t *nta = *ntap;
|
||||||
|
|
||||||
REQUIRE(VALID_NTA(nta));
|
REQUIRE(VALID_NTA(nta));
|
||||||
|
|
||||||
*ntap = NULL;
|
*ntap = NULL;
|
||||||
refs = isc_refcount_decrement(&nta->refcount);
|
isc_refcount_decrement(&nta->refcount, &refs);
|
||||||
if (refs == 1) {
|
if (refs == 0) {
|
||||||
nta->magic = 0;
|
nta->magic = 0;
|
||||||
if (nta->timer != NULL) {
|
if (nta->timer != NULL) {
|
||||||
(void) isc_timer_reset(nta->timer,
|
(void) isc_timer_reset(nta->timer,
|
||||||
|
|||||||
+4
-5
@@ -131,7 +131,7 @@ void
|
|||||||
dns_order_attach(dns_order_t *source, dns_order_t **target) {
|
dns_order_attach(dns_order_t *source, dns_order_t **target) {
|
||||||
REQUIRE(DNS_ORDER_VALID(source));
|
REQUIRE(DNS_ORDER_VALID(source));
|
||||||
REQUIRE(target != NULL && *target == NULL);
|
REQUIRE(target != NULL && *target == NULL);
|
||||||
isc_refcount_increment(&source->references);
|
isc_refcount_increment(&source->references, NULL);
|
||||||
*target = source;
|
*target = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,16 +139,15 @@ void
|
|||||||
dns_order_detach(dns_order_t **orderp) {
|
dns_order_detach(dns_order_t **orderp) {
|
||||||
dns_order_t *order;
|
dns_order_t *order;
|
||||||
dns_order_ent_t *ent;
|
dns_order_ent_t *ent;
|
||||||
int_fast32_t refs;
|
unsigned int references;
|
||||||
|
|
||||||
REQUIRE(orderp != NULL);
|
REQUIRE(orderp != NULL);
|
||||||
order = *orderp;
|
order = *orderp;
|
||||||
REQUIRE(DNS_ORDER_VALID(order));
|
REQUIRE(DNS_ORDER_VALID(order));
|
||||||
|
isc_refcount_decrement(&order->references, &references);
|
||||||
*orderp = NULL;
|
*orderp = NULL;
|
||||||
refs = isc_refcount_decrement(&order->references);
|
if (references != 0)
|
||||||
if (refs > 1) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
order->magic = 0;
|
order->magic = 0;
|
||||||
while ((ent = ISC_LIST_HEAD(order->ents)) != NULL) {
|
while ((ent = ISC_LIST_HEAD(order->ents)) != NULL) {
|
||||||
|
|||||||
+5
-5
@@ -231,20 +231,21 @@ dns_portlist_attach(dns_portlist_t *portlist, dns_portlist_t **portlistp) {
|
|||||||
REQUIRE(DNS_VALID_PORTLIST(portlist));
|
REQUIRE(DNS_VALID_PORTLIST(portlist));
|
||||||
REQUIRE(portlistp != NULL && *portlistp == NULL);
|
REQUIRE(portlistp != NULL && *portlistp == NULL);
|
||||||
|
|
||||||
isc_refcount_increment(&portlist->refcount);
|
isc_refcount_increment(&portlist->refcount, NULL);
|
||||||
*portlistp = portlist;
|
*portlistp = portlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_portlist_detach(dns_portlist_t **portlistp) {
|
dns_portlist_detach(dns_portlist_t **portlistp) {
|
||||||
dns_portlist_t *portlist;
|
dns_portlist_t *portlist;
|
||||||
int_fast32_t refs;
|
unsigned int count;
|
||||||
|
|
||||||
REQUIRE(portlistp != NULL);
|
REQUIRE(portlistp != NULL);
|
||||||
portlist = *portlistp;
|
portlist = *portlistp;
|
||||||
REQUIRE(DNS_VALID_PORTLIST(portlist));
|
REQUIRE(DNS_VALID_PORTLIST(portlist));
|
||||||
refs = isc_refcount_decrement(&portlist->refcount);
|
*portlistp = NULL;
|
||||||
if (refs == 1) {
|
isc_refcount_decrement(&portlist->refcount, &count);
|
||||||
|
if (count == 0) {
|
||||||
portlist->magic = 0;
|
portlist->magic = 0;
|
||||||
isc_refcount_destroy(&portlist->refcount);
|
isc_refcount_destroy(&portlist->refcount);
|
||||||
if (portlist->list != NULL)
|
if (portlist->list != NULL)
|
||||||
@@ -255,5 +256,4 @@ dns_portlist_detach(dns_portlist_t **portlistp) {
|
|||||||
isc_mem_putanddetach(&portlist->mctx, portlist,
|
isc_mem_putanddetach(&portlist->mctx, portlist,
|
||||||
sizeof(*portlist));
|
sizeof(*portlist));
|
||||||
}
|
}
|
||||||
*portlistp = NULL;
|
|
||||||
}
|
}
|
||||||
|
|||||||
+146
-73
@@ -135,6 +135,32 @@ typedef isc_uint32_t rbtdb_rdatatype_t;
|
|||||||
#define RBTDB_RDATATYPE_NCACHEANY \
|
#define RBTDB_RDATATYPE_NCACHEANY \
|
||||||
RBTDB_RDATATYPE_VALUE(0, dns_rdatatype_any)
|
RBTDB_RDATATYPE_VALUE(0, dns_rdatatype_any)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We use rwlock for DB lock only when ISC_RWLOCK_USEATOMIC is non 0.
|
||||||
|
* Using rwlock is effective with regard to lookup performance only when
|
||||||
|
* it is implemented in an efficient way.
|
||||||
|
* Otherwise, it is generally wise to stick to the simple locking since rwlock
|
||||||
|
* would require more memory or can even make lookups slower due to its own
|
||||||
|
* overhead (when it internally calls mutex locks).
|
||||||
|
*/
|
||||||
|
#ifdef ISC_RWLOCK_USEATOMIC
|
||||||
|
#define DNS_RBTDB_USERWLOCK 1
|
||||||
|
#else
|
||||||
|
#define DNS_RBTDB_USERWLOCK 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DNS_RBTDB_USERWLOCK
|
||||||
|
#define RBTDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
|
||||||
|
#define RBTDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
|
||||||
|
#define RBTDB_LOCK(l, t) RWLOCK((l), (t))
|
||||||
|
#define RBTDB_UNLOCK(l, t) RWUNLOCK((l), (t))
|
||||||
|
#else
|
||||||
|
#define RBTDB_INITLOCK(l) isc_mutex_init(l)
|
||||||
|
#define RBTDB_DESTROYLOCK(l) DESTROYLOCK(l)
|
||||||
|
#define RBTDB_LOCK(l, t) LOCK(l)
|
||||||
|
#define RBTDB_UNLOCK(l, t) UNLOCK(l)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since node locking is sensitive to both performance and memory footprint,
|
* Since node locking is sensitive to both performance and memory footprint,
|
||||||
* we need some trick here. If we have both high-performance rwlock and
|
* we need some trick here. If we have both high-performance rwlock and
|
||||||
@@ -154,6 +180,7 @@ typedef isc_uint32_t rbtdb_rdatatype_t;
|
|||||||
* Note that we cannot use NODE_LOCK()/NODE_UNLOCK() wherever the protected
|
* Note that we cannot use NODE_LOCK()/NODE_UNLOCK() wherever the protected
|
||||||
* section is also protected by NODE_STRONGLOCK().
|
* section is also protected by NODE_STRONGLOCK().
|
||||||
*/
|
*/
|
||||||
|
#if defined(ISC_RWLOCK_USEATOMIC) && defined(DNS_RBT_USEISCREFCOUNT)
|
||||||
typedef isc_rwlock_t nodelock_t;
|
typedef isc_rwlock_t nodelock_t;
|
||||||
|
|
||||||
#define NODE_INITLOCK(l) isc_rwlock_init((l), 0, 0)
|
#define NODE_INITLOCK(l) isc_rwlock_init((l), 0, 0)
|
||||||
@@ -167,6 +194,21 @@ typedef isc_rwlock_t nodelock_t;
|
|||||||
#define NODE_WEAKLOCK(l, t) NODE_LOCK(l, t)
|
#define NODE_WEAKLOCK(l, t) NODE_LOCK(l, t)
|
||||||
#define NODE_WEAKUNLOCK(l, t) NODE_UNLOCK(l, t)
|
#define NODE_WEAKUNLOCK(l, t) NODE_UNLOCK(l, t)
|
||||||
#define NODE_WEAKDOWNGRADE(l) isc_rwlock_downgrade(l)
|
#define NODE_WEAKDOWNGRADE(l) isc_rwlock_downgrade(l)
|
||||||
|
#else
|
||||||
|
typedef isc_mutex_t nodelock_t;
|
||||||
|
|
||||||
|
#define NODE_INITLOCK(l) isc_mutex_init(l)
|
||||||
|
#define NODE_DESTROYLOCK(l) DESTROYLOCK(l)
|
||||||
|
#define NODE_LOCK(l, t) LOCK(l)
|
||||||
|
#define NODE_UNLOCK(l, t) UNLOCK(l)
|
||||||
|
#define NODE_TRYUPGRADE(l) ISC_R_SUCCESS
|
||||||
|
|
||||||
|
#define NODE_STRONGLOCK(l) LOCK(l)
|
||||||
|
#define NODE_STRONGUNLOCK(l) UNLOCK(l)
|
||||||
|
#define NODE_WEAKLOCK(l, t) ((void)0)
|
||||||
|
#define NODE_WEAKUNLOCK(l, t) ((void)0)
|
||||||
|
#define NODE_WEAKDOWNGRADE(l) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* Whether to rate-limit updating the LRU to avoid possible thread contention.
|
* Whether to rate-limit updating the LRU to avoid possible thread contention.
|
||||||
@@ -425,7 +467,11 @@ struct dns_rbtdb {
|
|||||||
/* Unlocked. */
|
/* Unlocked. */
|
||||||
dns_db_t common;
|
dns_db_t common;
|
||||||
/* Locks the data in this struct */
|
/* Locks the data in this struct */
|
||||||
|
#if DNS_RBTDB_USERWLOCK
|
||||||
isc_rwlock_t lock;
|
isc_rwlock_t lock;
|
||||||
|
#else
|
||||||
|
isc_mutex_t lock;
|
||||||
|
#endif
|
||||||
/* Locks the tree structure (prevents nodes appearing/disappearing) */
|
/* Locks the tree structure (prevents nodes appearing/disappearing) */
|
||||||
isc_rwlock_t tree_lock;
|
isc_rwlock_t tree_lock;
|
||||||
/* Locks for individual tree nodes */
|
/* Locks for individual tree nodes */
|
||||||
@@ -769,7 +815,7 @@ attach(dns_db_t *source, dns_db_t **targetp) {
|
|||||||
|
|
||||||
REQUIRE(VALID_RBTDB(rbtdb));
|
REQUIRE(VALID_RBTDB(rbtdb));
|
||||||
|
|
||||||
isc_refcount_increment(&rbtdb->references);
|
isc_refcount_increment(&rbtdb->references, NULL);
|
||||||
|
|
||||||
*targetp = source;
|
*targetp = source;
|
||||||
}
|
}
|
||||||
@@ -968,10 +1014,14 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
|
|||||||
REQUIRE(rbtdb->future_version == NULL);
|
REQUIRE(rbtdb->future_version == NULL);
|
||||||
|
|
||||||
if (rbtdb->current_version != NULL) {
|
if (rbtdb->current_version != NULL) {
|
||||||
isc_refcount_decrement(&rbtdb->current_version->references);
|
unsigned int refs;
|
||||||
isc_refcount_destroy(&rbtdb->current_version->references); /* Ensures this was the last reference */
|
|
||||||
|
isc_refcount_decrement(&rbtdb->current_version->references,
|
||||||
|
&refs);
|
||||||
|
INSIST(refs == 0);
|
||||||
UNLINK(rbtdb->open_versions, rbtdb->current_version, link);
|
UNLINK(rbtdb->open_versions, rbtdb->current_version, link);
|
||||||
isc_rwlock_destroy(&rbtdb->current_version->glue_rwlock);
|
isc_rwlock_destroy(&rbtdb->current_version->glue_rwlock);
|
||||||
|
isc_refcount_destroy(&rbtdb->current_version->references);
|
||||||
isc_rwlock_destroy(&rbtdb->current_version->rwlock);
|
isc_rwlock_destroy(&rbtdb->current_version->rwlock);
|
||||||
isc_mem_put(rbtdb->common.mctx, rbtdb->current_version,
|
isc_mem_put(rbtdb->common.mctx, rbtdb->current_version,
|
||||||
sizeof(rbtdb_version_t));
|
sizeof(rbtdb_version_t));
|
||||||
@@ -1095,7 +1145,7 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
|
|||||||
if (rbtdb->task != NULL)
|
if (rbtdb->task != NULL)
|
||||||
isc_task_detach(&rbtdb->task);
|
isc_task_detach(&rbtdb->task);
|
||||||
|
|
||||||
isc_rwlock_destroy(&rbtdb->lock);
|
RBTDB_DESTROYLOCK(&rbtdb->lock);
|
||||||
rbtdb->common.magic = 0;
|
rbtdb->common.magic = 0;
|
||||||
rbtdb->common.impmagic = 0;
|
rbtdb->common.impmagic = 0;
|
||||||
isc_mem_detach(&rbtdb->hmctx);
|
isc_mem_detach(&rbtdb->hmctx);
|
||||||
@@ -1154,12 +1204,12 @@ maybe_free_rbtdb(dns_rbtdb_t *rbtdb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (inactive != 0) {
|
if (inactive != 0) {
|
||||||
RWLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
|
||||||
rbtdb->active -= inactive;
|
rbtdb->active -= inactive;
|
||||||
if (rbtdb->active == 0) {
|
if (rbtdb->active == 0) {
|
||||||
want_free = ISC_TRUE;
|
want_free = ISC_TRUE;
|
||||||
}
|
}
|
||||||
RWUNLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
||||||
if (want_free) {
|
if (want_free) {
|
||||||
char buf[DNS_NAME_FORMATSIZE];
|
char buf[DNS_NAME_FORMATSIZE];
|
||||||
if (dns_name_dynamic(&rbtdb->common.origin)) {
|
if (dns_name_dynamic(&rbtdb->common.origin)) {
|
||||||
@@ -1179,15 +1229,14 @@ maybe_free_rbtdb(dns_rbtdb_t *rbtdb) {
|
|||||||
static void
|
static void
|
||||||
detach(dns_db_t **dbp) {
|
detach(dns_db_t **dbp) {
|
||||||
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)(*dbp);
|
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)(*dbp);
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
|
|
||||||
REQUIRE(VALID_RBTDB(rbtdb));
|
REQUIRE(VALID_RBTDB(rbtdb));
|
||||||
|
|
||||||
refs = isc_refcount_decrement(&rbtdb->references);
|
isc_refcount_decrement(&rbtdb->references, &refs);
|
||||||
|
|
||||||
if (refs == 1) {
|
if (refs == 0)
|
||||||
maybe_free_rbtdb(rbtdb);
|
maybe_free_rbtdb(rbtdb);
|
||||||
}
|
|
||||||
|
|
||||||
*dbp = NULL;
|
*dbp = NULL;
|
||||||
}
|
}
|
||||||
@@ -1196,13 +1245,14 @@ static void
|
|||||||
currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
|
currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
|
||||||
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
|
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
|
||||||
rbtdb_version_t *version;
|
rbtdb_version_t *version;
|
||||||
|
unsigned int refs;
|
||||||
|
|
||||||
REQUIRE(VALID_RBTDB(rbtdb));
|
REQUIRE(VALID_RBTDB(rbtdb));
|
||||||
|
|
||||||
RWLOCK(&rbtdb->lock, isc_rwlocktype_read);
|
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
|
||||||
version = rbtdb->current_version;
|
version = rbtdb->current_version;
|
||||||
isc_refcount_increment(&version->references);
|
isc_refcount_increment(&version->references, &refs);
|
||||||
RWUNLOCK(&rbtdb->lock, isc_rwlocktype_read);
|
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
|
||||||
|
|
||||||
*versionp = (dns_dbversion_t *)version;
|
*versionp = (dns_dbversion_t *)version;
|
||||||
}
|
}
|
||||||
@@ -1265,7 +1315,7 @@ newversion(dns_db_t *db, dns_dbversion_t **versionp) {
|
|||||||
REQUIRE(versionp != NULL && *versionp == NULL);
|
REQUIRE(versionp != NULL && *versionp == NULL);
|
||||||
REQUIRE(rbtdb->future_version == NULL);
|
REQUIRE(rbtdb->future_version == NULL);
|
||||||
|
|
||||||
RWLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
|
||||||
RUNTIME_CHECK(rbtdb->next_serial != 0); /* XXX Error? */
|
RUNTIME_CHECK(rbtdb->next_serial != 0); /* XXX Error? */
|
||||||
version = allocate_version(rbtdb->common.mctx, rbtdb->next_serial, 1,
|
version = allocate_version(rbtdb->common.mctx, rbtdb->next_serial, 1,
|
||||||
ISC_TRUE);
|
ISC_TRUE);
|
||||||
@@ -1310,7 +1360,7 @@ newversion(dns_db_t *db, dns_dbversion_t **versionp) {
|
|||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
result = ISC_R_NOMEMORY;
|
result = ISC_R_NOMEMORY;
|
||||||
RWUNLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
||||||
|
|
||||||
if (version == NULL)
|
if (version == NULL)
|
||||||
return (result);
|
return (result);
|
||||||
@@ -1326,11 +1376,13 @@ attachversion(dns_db_t *db, dns_dbversion_t *source,
|
|||||||
{
|
{
|
||||||
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
|
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
|
||||||
rbtdb_version_t *rbtversion = source;
|
rbtdb_version_t *rbtversion = source;
|
||||||
|
unsigned int refs;
|
||||||
|
|
||||||
REQUIRE(VALID_RBTDB(rbtdb));
|
REQUIRE(VALID_RBTDB(rbtdb));
|
||||||
INSIST(rbtversion != NULL && rbtversion->rbtdb == rbtdb);
|
INSIST(rbtversion != NULL && rbtversion->rbtdb == rbtdb);
|
||||||
|
|
||||||
isc_refcount_increment(&rbtversion->references);
|
isc_refcount_increment(&rbtversion->references, &refs);
|
||||||
|
INSIST(refs > 1);
|
||||||
|
|
||||||
*targetp = rbtversion;
|
*targetp = rbtversion;
|
||||||
}
|
}
|
||||||
@@ -1340,6 +1392,7 @@ add_changed(dns_rbtdb_t *rbtdb, rbtdb_version_t *version,
|
|||||||
dns_rbtnode_t *node)
|
dns_rbtnode_t *node)
|
||||||
{
|
{
|
||||||
rbtdb_changed_t *changed;
|
rbtdb_changed_t *changed;
|
||||||
|
unsigned int refs;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Caller must be holding the node lock if its reference must be
|
* Caller must be holding the node lock if its reference must be
|
||||||
@@ -1348,19 +1401,20 @@ add_changed(dns_rbtdb_t *rbtdb, rbtdb_version_t *version,
|
|||||||
|
|
||||||
changed = isc_mem_get(rbtdb->common.mctx, sizeof(*changed));
|
changed = isc_mem_get(rbtdb->common.mctx, sizeof(*changed));
|
||||||
|
|
||||||
RWLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
|
||||||
|
|
||||||
REQUIRE(version->writer);
|
REQUIRE(version->writer);
|
||||||
|
|
||||||
if (changed != NULL) {
|
if (changed != NULL) {
|
||||||
(void)dns_rbtnode_refincrement(node);
|
dns_rbtnode_refincrement(node, &refs);
|
||||||
|
INSIST(refs != 0);
|
||||||
changed->node = node;
|
changed->node = node;
|
||||||
changed->dirty = ISC_FALSE;
|
changed->dirty = ISC_FALSE;
|
||||||
ISC_LIST_INITANDAPPEND(version->changed_list, changed, link);
|
ISC_LIST_INITANDAPPEND(version->changed_list, changed, link);
|
||||||
} else
|
} else
|
||||||
version->commit_ok = ISC_FALSE;
|
version->commit_ok = ISC_FALSE;
|
||||||
|
|
||||||
RWUNLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
||||||
|
|
||||||
return (changed);
|
return (changed);
|
||||||
}
|
}
|
||||||
@@ -1861,15 +1915,17 @@ check_ttl(dns_rbtnode_t *node, rbtdb_search_t *search,
|
|||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
new_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) {
|
new_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) {
|
||||||
int_fast32_t noderefs;
|
unsigned int lockrefs, noderefs;
|
||||||
isc_refcount_t *lockref;
|
isc_refcount_t *lockref;
|
||||||
|
|
||||||
INSIST(!ISC_LINK_LINKED(node, deadlink));
|
INSIST(!ISC_LINK_LINKED(node, deadlink));
|
||||||
noderefs = dns_rbtnode_refincrement0(node);
|
dns_rbtnode_refincrement0(node, &noderefs);
|
||||||
if (noderefs == 0) { /* this is the first reference to the node */
|
if (noderefs == 1) { /* this is the first reference to the node */
|
||||||
lockref = &rbtdb->node_locks[node->locknum].references;
|
lockref = &rbtdb->node_locks[node->locknum].references;
|
||||||
isc_refcount_increment0(lockref);
|
isc_refcount_increment0(lockref, &lockrefs);
|
||||||
|
INSIST(lockrefs != 0);
|
||||||
}
|
}
|
||||||
|
INSIST(noderefs != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
@@ -2001,7 +2057,7 @@ decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
|||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
isc_boolean_t write_locked;
|
isc_boolean_t write_locked;
|
||||||
rbtdb_nodelock_t *nodelock;
|
rbtdb_nodelock_t *nodelock;
|
||||||
int_fast32_t refs;
|
unsigned int refs, nrefs;
|
||||||
int bucket = node->locknum;
|
int bucket = node->locknum;
|
||||||
isc_boolean_t no_reference = ISC_TRUE;
|
isc_boolean_t no_reference = ISC_TRUE;
|
||||||
|
|
||||||
@@ -2013,12 +2069,13 @@ decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
|||||||
|
|
||||||
/* Handle easy and typical case first. */
|
/* Handle easy and typical case first. */
|
||||||
if (!node->dirty && KEEP_NODE(node, rbtdb)) {
|
if (!node->dirty && KEEP_NODE(node, rbtdb)) {
|
||||||
refs = dns_rbtnode_refdecrement(node);
|
dns_rbtnode_refdecrement(node, &nrefs);
|
||||||
if (refs == 1) {
|
INSIST((int)nrefs >= 0);
|
||||||
isc_refcount_decrement(&nodelock->references);
|
if (nrefs == 0) {
|
||||||
return ISC_TRUE;
|
isc_refcount_decrement(&nodelock->references, &refs);
|
||||||
|
INSIST((int)refs >= 0);
|
||||||
}
|
}
|
||||||
return ISC_FALSE;
|
return ((nrefs == 0) ? ISC_TRUE : ISC_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Upgrade the lock? */
|
/* Upgrade the lock? */
|
||||||
@@ -2027,12 +2084,12 @@ decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
|||||||
NODE_WEAKLOCK(&nodelock->lock, isc_rwlocktype_write);
|
NODE_WEAKLOCK(&nodelock->lock, isc_rwlocktype_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
refs = dns_rbtnode_refdecrement(node);
|
dns_rbtnode_refdecrement(node, &nrefs);
|
||||||
if (refs > 1) {
|
INSIST((int)nrefs >= 0);
|
||||||
|
if (nrefs > 0) {
|
||||||
/* Restore the lock? */
|
/* Restore the lock? */
|
||||||
if (nlock == isc_rwlocktype_read) {
|
if (nlock == isc_rwlocktype_read)
|
||||||
NODE_WEAKDOWNGRADE(&nodelock->lock);
|
NODE_WEAKDOWNGRADE(&nodelock->lock);
|
||||||
}
|
|
||||||
return (ISC_FALSE);
|
return (ISC_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2045,9 +2102,9 @@ decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
|||||||
* Caller doesn't know the least serial.
|
* Caller doesn't know the least serial.
|
||||||
* Get it.
|
* Get it.
|
||||||
*/
|
*/
|
||||||
RWLOCK(&rbtdb->lock, isc_rwlocktype_read);
|
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
|
||||||
least_serial = rbtdb->least_serial;
|
least_serial = rbtdb->least_serial;
|
||||||
RWUNLOCK(&rbtdb->lock,
|
RBTDB_UNLOCK(&rbtdb->lock,
|
||||||
isc_rwlocktype_read);
|
isc_rwlocktype_read);
|
||||||
}
|
}
|
||||||
clean_zone_node(rbtdb, node, least_serial);
|
clean_zone_node(rbtdb, node, least_serial);
|
||||||
@@ -2077,7 +2134,8 @@ decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
|||||||
} else
|
} else
|
||||||
write_locked = ISC_TRUE;
|
write_locked = ISC_TRUE;
|
||||||
|
|
||||||
isc_refcount_decrement(&nodelock->references);
|
isc_refcount_decrement(&nodelock->references, &refs);
|
||||||
|
INSIST((int)refs >= 0);
|
||||||
|
|
||||||
if (KEEP_NODE(node, rbtdb))
|
if (KEEP_NODE(node, rbtdb))
|
||||||
goto restore_locks;
|
goto restore_locks;
|
||||||
@@ -2432,7 +2490,7 @@ cleanup_dead_nodes_callback(isc_task_t *task, isc_event_t *event) {
|
|||||||
dns_rbtdb_t *rbtdb = event->ev_arg;
|
dns_rbtdb_t *rbtdb = event->ev_arg;
|
||||||
isc_boolean_t again = ISC_FALSE;
|
isc_boolean_t again = ISC_FALSE;
|
||||||
unsigned int locknum;
|
unsigned int locknum;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
|
|
||||||
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
|
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
|
||||||
for (locknum = 0; locknum < rbtdb->node_lock_count; locknum++) {
|
for (locknum = 0; locknum < rbtdb->node_lock_count; locknum++) {
|
||||||
@@ -2449,10 +2507,9 @@ cleanup_dead_nodes_callback(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_task_send(task, &event);
|
isc_task_send(task, &event);
|
||||||
else {
|
else {
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
refs = isc_refcount_decrement(&rbtdb->references);
|
isc_refcount_decrement(&rbtdb->references, &refs);
|
||||||
if (refs == 1) {
|
if (refs == 0)
|
||||||
maybe_free_rbtdb(rbtdb);
|
maybe_free_rbtdb(rbtdb);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2466,7 +2523,7 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
|
|||||||
rbtdb_changed_t *changed, *next_changed;
|
rbtdb_changed_t *changed, *next_changed;
|
||||||
rbtdb_serial_t serial, least_serial;
|
rbtdb_serial_t serial, least_serial;
|
||||||
dns_rbtnode_t *rbtnode;
|
dns_rbtnode_t *rbtnode;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
rdatasetheader_t *header;
|
rdatasetheader_t *header;
|
||||||
|
|
||||||
REQUIRE(VALID_RBTDB(rbtdb));
|
REQUIRE(VALID_RBTDB(rbtdb));
|
||||||
@@ -2477,12 +2534,12 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
|
|||||||
ISC_LIST_INIT(cleanup_list);
|
ISC_LIST_INIT(cleanup_list);
|
||||||
ISC_LIST_INIT(resigned_list);
|
ISC_LIST_INIT(resigned_list);
|
||||||
|
|
||||||
refs = isc_refcount_decrement(&version->references);
|
isc_refcount_decrement(&version->references, &refs);
|
||||||
if (refs > 1) { /* typical and easy case first */
|
if (refs > 0) { /* typical and easy case first */
|
||||||
if (commit) {
|
if (commit) {
|
||||||
RWLOCK(&rbtdb->lock, isc_rwlocktype_read);
|
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
|
||||||
INSIST(!version->writer);
|
INSIST(!version->writer);
|
||||||
RWUNLOCK(&rbtdb->lock, isc_rwlocktype_read);
|
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
|
||||||
}
|
}
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -2494,11 +2551,11 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
|
|||||||
if (version->writer && commit && !IS_CACHE(rbtdb))
|
if (version->writer && commit && !IS_CACHE(rbtdb))
|
||||||
iszonesecure(db, version, rbtdb->origin_node);
|
iszonesecure(db, version, rbtdb->origin_node);
|
||||||
|
|
||||||
RWLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
|
||||||
serial = version->serial;
|
serial = version->serial;
|
||||||
if (version->writer) {
|
if (version->writer) {
|
||||||
if (commit) {
|
if (commit) {
|
||||||
int_fast32_t cur_refs;
|
unsigned cur_ref;
|
||||||
rbtdb_version_t *cur_version;
|
rbtdb_version_t *cur_version;
|
||||||
|
|
||||||
INSIST(version->commit_ok);
|
INSIST(version->commit_ok);
|
||||||
@@ -2509,8 +2566,9 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
|
|||||||
* DB itself and unlink it from the open list.
|
* DB itself and unlink it from the open list.
|
||||||
*/
|
*/
|
||||||
cur_version = rbtdb->current_version;
|
cur_version = rbtdb->current_version;
|
||||||
cur_refs = isc_refcount_decrement(&cur_version->references);
|
isc_refcount_decrement(&cur_version->references,
|
||||||
if (cur_refs == 1) {
|
&cur_ref);
|
||||||
|
if (cur_ref == 0) {
|
||||||
if (cur_version->serial == rbtdb->least_serial)
|
if (cur_version->serial == rbtdb->least_serial)
|
||||||
INSIST(EMPTY(cur_version->changed_list));
|
INSIST(EMPTY(cur_version->changed_list));
|
||||||
UNLINK(rbtdb->open_versions,
|
UNLINK(rbtdb->open_versions,
|
||||||
@@ -2544,7 +2602,7 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
|
|||||||
* isn't being used by anyone, we can clean
|
* isn't being used by anyone, we can clean
|
||||||
* it up.
|
* it up.
|
||||||
*/
|
*/
|
||||||
if (cur_refs == 1) {
|
if (cur_ref == 0) {
|
||||||
cleanup_version = cur_version;
|
cleanup_version = cur_version;
|
||||||
APPENDLIST(version->changed_list,
|
APPENDLIST(version->changed_list,
|
||||||
cleanup_version->changed_list,
|
cleanup_version->changed_list,
|
||||||
@@ -2565,8 +2623,9 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
|
|||||||
* case where we need to increment the counter from
|
* case where we need to increment the counter from
|
||||||
* zero and need to use isc_refcount_increment0().
|
* zero and need to use isc_refcount_increment0().
|
||||||
*/
|
*/
|
||||||
cur_refs = isc_refcount_increment0(&version->references);
|
isc_refcount_increment0(&version->references,
|
||||||
INSIST(cur_refs == 0);
|
&cur_ref);
|
||||||
|
INSIST(cur_ref == 1);
|
||||||
PREPEND(rbtdb->open_versions,
|
PREPEND(rbtdb->open_versions,
|
||||||
rbtdb->current_version, link);
|
rbtdb->current_version, link);
|
||||||
resigned_list = version->resigned_list;
|
resigned_list = version->resigned_list;
|
||||||
@@ -2625,7 +2684,7 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
|
|||||||
UNLINK(rbtdb->open_versions, version, link);
|
UNLINK(rbtdb->open_versions, version, link);
|
||||||
}
|
}
|
||||||
least_serial = rbtdb->least_serial;
|
least_serial = rbtdb->least_serial;
|
||||||
RWUNLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
||||||
|
|
||||||
if (cleanup_version != NULL) {
|
if (cleanup_version != NULL) {
|
||||||
INSIST(EMPTY(cleanup_version->changed_list));
|
INSIST(EMPTY(cleanup_version->changed_list));
|
||||||
@@ -2718,7 +2777,7 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
|
|||||||
sizeof(*changed));
|
sizeof(*changed));
|
||||||
}
|
}
|
||||||
if (event != NULL) {
|
if (event != NULL) {
|
||||||
isc_refcount_increment(&rbtdb->references);
|
isc_refcount_increment(&rbtdb->references, NULL);
|
||||||
isc_task_send(rbtdb->task, &event);
|
isc_task_send(rbtdb->task, &event);
|
||||||
} else
|
} else
|
||||||
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
|
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
|
||||||
@@ -4420,6 +4479,11 @@ check_stale_header(dns_rbtnode_t *node, rdatasetheader_t *header,
|
|||||||
isc_rwlocktype_t *locktype, nodelock_t *lock,
|
isc_rwlocktype_t *locktype, nodelock_t *lock,
|
||||||
rbtdb_search_t *search, rdatasetheader_t **header_prev)
|
rbtdb_search_t *search, rdatasetheader_t **header_prev)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if !defined(ISC_RWLOCK_USEATOMIC) || !defined(DNS_RBT_USEISCREFCOUNT)
|
||||||
|
UNUSED(lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!ACTIVE(header, search->now)) {
|
if (!ACTIVE(header, search->now)) {
|
||||||
dns_ttl_t stale = header->rdh_ttl +
|
dns_ttl_t stale = header->rdh_ttl +
|
||||||
search->rbtdb->serve_stale_ttl;
|
search->rbtdb->serve_stale_ttl;
|
||||||
@@ -5267,12 +5331,14 @@ static void
|
|||||||
attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
|
attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
|
||||||
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
|
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
|
||||||
dns_rbtnode_t *node = (dns_rbtnode_t *)source;
|
dns_rbtnode_t *node = (dns_rbtnode_t *)source;
|
||||||
|
unsigned int refs;
|
||||||
|
|
||||||
REQUIRE(VALID_RBTDB(rbtdb));
|
REQUIRE(VALID_RBTDB(rbtdb));
|
||||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||||
|
|
||||||
NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock);
|
NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock);
|
||||||
dns_rbtnode_refincrement(node);
|
dns_rbtnode_refincrement(node, &refs);
|
||||||
|
INSIST(refs != 0);
|
||||||
NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock);
|
NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock);
|
||||||
|
|
||||||
*targetp = source;
|
*targetp = source;
|
||||||
@@ -5307,11 +5373,11 @@ detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
|
|||||||
*targetp = NULL;
|
*targetp = NULL;
|
||||||
|
|
||||||
if (inactive) {
|
if (inactive) {
|
||||||
RWLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
|
||||||
rbtdb->active--;
|
rbtdb->active--;
|
||||||
if (rbtdb->active == 0)
|
if (rbtdb->active == 0)
|
||||||
want_free = ISC_TRUE;
|
want_free = ISC_TRUE;
|
||||||
RWUNLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
||||||
if (want_free) {
|
if (want_free) {
|
||||||
char buf[DNS_NAME_FORMATSIZE];
|
char buf[DNS_NAME_FORMATSIZE];
|
||||||
if (dns_name_dynamic(&rbtdb->common.origin))
|
if (dns_name_dynamic(&rbtdb->common.origin))
|
||||||
@@ -5435,7 +5501,7 @@ printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) {
|
|||||||
NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
|
NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
|
||||||
isc_rwlocktype_read);
|
isc_rwlocktype_read);
|
||||||
|
|
||||||
fprintf(out, "node %p, %" PRIdFAST32 " references, locknum = %u\n",
|
fprintf(out, "node %p, %u references, locknum = %u\n",
|
||||||
rbtnode, dns_rbtnode_refcurrent(rbtnode),
|
rbtnode, dns_rbtnode_refcurrent(rbtnode),
|
||||||
rbtnode->locknum);
|
rbtnode->locknum);
|
||||||
if (rbtnode->data != NULL) {
|
if (rbtnode->data != NULL) {
|
||||||
@@ -5701,6 +5767,7 @@ allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
|||||||
dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
|
dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
|
||||||
rbtdb_version_t *rbtversion = version;
|
rbtdb_version_t *rbtversion = version;
|
||||||
rbtdb_rdatasetiter_t *iterator;
|
rbtdb_rdatasetiter_t *iterator;
|
||||||
|
unsigned int refs;
|
||||||
|
|
||||||
REQUIRE(VALID_RBTDB(rbtdb));
|
REQUIRE(VALID_RBTDB(rbtdb));
|
||||||
|
|
||||||
@@ -5716,7 +5783,9 @@ allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
|||||||
else {
|
else {
|
||||||
INSIST(rbtversion->rbtdb == rbtdb);
|
INSIST(rbtversion->rbtdb == rbtdb);
|
||||||
|
|
||||||
isc_refcount_increment(&rbtversion->references);
|
isc_refcount_increment(&rbtversion->references,
|
||||||
|
&refs);
|
||||||
|
INSIST(refs > 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (now == 0)
|
if (now == 0)
|
||||||
@@ -5733,7 +5802,8 @@ allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
|||||||
|
|
||||||
NODE_STRONGLOCK(&rbtdb->node_locks[rbtnode->locknum].lock);
|
NODE_STRONGLOCK(&rbtdb->node_locks[rbtnode->locknum].lock);
|
||||||
|
|
||||||
dns_rbtnode_refincrement(rbtnode);
|
dns_rbtnode_refincrement(rbtnode, &refs);
|
||||||
|
INSIST(refs != 0);
|
||||||
|
|
||||||
iterator->current = NULL;
|
iterator->current = NULL;
|
||||||
|
|
||||||
@@ -7378,13 +7448,13 @@ beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
|
|||||||
else
|
else
|
||||||
loadctx->now = 0;
|
loadctx->now = 0;
|
||||||
|
|
||||||
RWLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
|
||||||
|
|
||||||
REQUIRE((rbtdb->attributes & (RBTDB_ATTR_LOADED|RBTDB_ATTR_LOADING))
|
REQUIRE((rbtdb->attributes & (RBTDB_ATTR_LOADED|RBTDB_ATTR_LOADING))
|
||||||
== 0);
|
== 0);
|
||||||
rbtdb->attributes |= RBTDB_ATTR_LOADING;
|
rbtdb->attributes |= RBTDB_ATTR_LOADING;
|
||||||
|
|
||||||
RWUNLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
||||||
|
|
||||||
callbacks->add = loading_addrdataset;
|
callbacks->add = loading_addrdataset;
|
||||||
callbacks->add_private = loadctx;
|
callbacks->add_private = loadctx;
|
||||||
@@ -7405,7 +7475,7 @@ endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
|
|||||||
REQUIRE(loadctx != NULL);
|
REQUIRE(loadctx != NULL);
|
||||||
REQUIRE(loadctx->rbtdb == rbtdb);
|
REQUIRE(loadctx->rbtdb == rbtdb);
|
||||||
|
|
||||||
RWLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
|
||||||
|
|
||||||
REQUIRE((rbtdb->attributes & RBTDB_ATTR_LOADING) != 0);
|
REQUIRE((rbtdb->attributes & RBTDB_ATTR_LOADING) != 0);
|
||||||
REQUIRE((rbtdb->attributes & RBTDB_ATTR_LOADED) == 0);
|
REQUIRE((rbtdb->attributes & RBTDB_ATTR_LOADED) == 0);
|
||||||
@@ -7413,7 +7483,7 @@ endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
|
|||||||
rbtdb->attributes &= ~RBTDB_ATTR_LOADING;
|
rbtdb->attributes &= ~RBTDB_ATTR_LOADING;
|
||||||
rbtdb->attributes |= RBTDB_ATTR_LOADED;
|
rbtdb->attributes |= RBTDB_ATTR_LOADED;
|
||||||
|
|
||||||
RWUNLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there's a KEY rdataset at the zone origin containing a
|
* If there's a KEY rdataset at the zone origin containing a
|
||||||
@@ -7749,12 +7819,12 @@ settask(dns_db_t *db, isc_task_t *task) {
|
|||||||
|
|
||||||
REQUIRE(VALID_RBTDB(rbtdb));
|
REQUIRE(VALID_RBTDB(rbtdb));
|
||||||
|
|
||||||
RWLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
|
||||||
if (rbtdb->task != NULL)
|
if (rbtdb->task != NULL)
|
||||||
isc_task_detach(&rbtdb->task);
|
isc_task_detach(&rbtdb->task);
|
||||||
if (task != NULL)
|
if (task != NULL)
|
||||||
isc_task_attach(task, &rbtdb->task);
|
isc_task_attach(task, &rbtdb->task);
|
||||||
RWUNLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
static isc_boolean_t
|
static isc_boolean_t
|
||||||
@@ -8213,7 +8283,7 @@ dns_rbtdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
|
|||||||
|
|
||||||
ISC_LIST_INIT(rbtdb->common.update_listeners);
|
ISC_LIST_INIT(rbtdb->common.update_listeners);
|
||||||
|
|
||||||
result = isc_rwlock_init(&rbtdb->lock, 0, 0);
|
result = RBTDB_INITLOCK(&rbtdb->lock);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto cleanup_rbtdb;
|
goto cleanup_rbtdb;
|
||||||
|
|
||||||
@@ -8306,7 +8376,7 @@ dns_rbtdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
|
|||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
while (i-- > 0) {
|
while (i-- > 0) {
|
||||||
NODE_DESTROYLOCK(&rbtdb->node_locks[i].lock);
|
NODE_DESTROYLOCK(&rbtdb->node_locks[i].lock);
|
||||||
isc_refcount_decrement(&rbtdb->node_locks[i].references);
|
isc_refcount_decrement(&rbtdb->node_locks[i].references, NULL);
|
||||||
isc_refcount_destroy(&rbtdb->node_locks[i].references);
|
isc_refcount_destroy(&rbtdb->node_locks[i].references);
|
||||||
}
|
}
|
||||||
goto cleanup_deadnodes;
|
goto cleanup_deadnodes;
|
||||||
@@ -8440,7 +8510,7 @@ dns_rbtdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
|
|||||||
rbtdb->next_serial = 2;
|
rbtdb->next_serial = 2;
|
||||||
rbtdb->current_version = allocate_version(mctx, 1, 1, ISC_FALSE);
|
rbtdb->current_version = allocate_version(mctx, 1, 1, ISC_FALSE);
|
||||||
if (rbtdb->current_version == NULL) {
|
if (rbtdb->current_version == NULL) {
|
||||||
isc_refcount_decrement(&rbtdb->references);
|
isc_refcount_decrement(&rbtdb->references, NULL);
|
||||||
isc_refcount_destroy(&rbtdb->references);
|
isc_refcount_destroy(&rbtdb->references);
|
||||||
free_rbtdb(rbtdb, ISC_FALSE, NULL);
|
free_rbtdb(rbtdb, ISC_FALSE, NULL);
|
||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
@@ -8462,7 +8532,7 @@ dns_rbtdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
|
|||||||
isc_mem_put(mctx, rbtdb->current_version,
|
isc_mem_put(mctx, rbtdb->current_version,
|
||||||
sizeof(*rbtdb->current_version));
|
sizeof(*rbtdb->current_version));
|
||||||
rbtdb->current_version = NULL;
|
rbtdb->current_version = NULL;
|
||||||
isc_refcount_decrement(&rbtdb->references);
|
isc_refcount_decrement(&rbtdb->references, NULL);
|
||||||
isc_refcount_destroy(&rbtdb->references);
|
isc_refcount_destroy(&rbtdb->references);
|
||||||
free_rbtdb(rbtdb, ISC_FALSE, NULL);
|
free_rbtdb(rbtdb, ISC_FALSE, NULL);
|
||||||
return (result);
|
return (result);
|
||||||
@@ -8514,7 +8584,7 @@ dns_rbtdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
|
|||||||
isc_rwlock_destroy(&rbtdb->tree_lock);
|
isc_rwlock_destroy(&rbtdb->tree_lock);
|
||||||
|
|
||||||
cleanup_lock:
|
cleanup_lock:
|
||||||
isc_rwlock_destroy(&rbtdb->lock);
|
RBTDB_DESTROYLOCK(&rbtdb->lock);
|
||||||
|
|
||||||
cleanup_rbtdb:
|
cleanup_rbtdb:
|
||||||
isc_mem_put(mctx, rbtdb, sizeof(*rbtdb));
|
isc_mem_put(mctx, rbtdb, sizeof(*rbtdb));
|
||||||
@@ -9429,9 +9499,12 @@ dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
|
|||||||
* expirenode() currently always returns success.
|
* expirenode() currently always returns success.
|
||||||
*/
|
*/
|
||||||
if (expire_result == ISC_R_SUCCESS && node->down == NULL) {
|
if (expire_result == ISC_R_SUCCESS && node->down == NULL) {
|
||||||
|
unsigned int refs;
|
||||||
|
|
||||||
rbtdbiter->deletions[rbtdbiter->delcnt++] = node;
|
rbtdbiter->deletions[rbtdbiter->delcnt++] = node;
|
||||||
NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock);
|
NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock);
|
||||||
dns_rbtnode_refincrement(node);
|
dns_rbtnode_refincrement(node, &refs);
|
||||||
|
INSIST(refs != 0);
|
||||||
NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock);
|
NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-37
@@ -1479,7 +1479,7 @@ cleanup_task:
|
|||||||
dns_rbt_destroy(&zones->rbt);
|
dns_rbt_destroy(&zones->rbt);
|
||||||
|
|
||||||
cleanup_rbt:
|
cleanup_rbt:
|
||||||
isc_refcount_decrement(&zones->refs);
|
isc_refcount_decrement(&zones->refs, NULL);
|
||||||
isc_refcount_destroy(&zones->refs);
|
isc_refcount_destroy(&zones->refs);
|
||||||
|
|
||||||
cleanup_refcount:
|
cleanup_refcount:
|
||||||
@@ -1565,7 +1565,7 @@ cleanup_ht:
|
|||||||
isc_timer_detach(&zone->updatetimer);
|
isc_timer_detach(&zone->updatetimer);
|
||||||
|
|
||||||
cleanup_timer:
|
cleanup_timer:
|
||||||
isc_refcount_decrement(&zone->refs);
|
isc_refcount_decrement(&zone->refs, NULL);
|
||||||
isc_refcount_destroy(&zone->refs);
|
isc_refcount_destroy(&zone->refs);
|
||||||
|
|
||||||
cleanup_refcount:
|
cleanup_refcount:
|
||||||
@@ -2048,64 +2048,51 @@ cidr_free(dns_rpz_zones_t *rpzs) {
|
|||||||
static void
|
static void
|
||||||
rpz_detach(dns_rpz_zone_t **rpzp, dns_rpz_zones_t *rpzs) {
|
rpz_detach(dns_rpz_zone_t **rpzp, dns_rpz_zones_t *rpzs) {
|
||||||
dns_rpz_zone_t *rpz;
|
dns_rpz_zone_t *rpz;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
|
|
||||||
rpz = *rpzp;
|
rpz = *rpzp;
|
||||||
*rpzp = NULL;
|
*rpzp = NULL;
|
||||||
refs = isc_refcount_decrement(&rpz->refs);
|
isc_refcount_decrement(&rpz->refs, &refs);
|
||||||
if (refs > 1) {
|
if (refs != 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
isc_refcount_destroy(&rpz->refs);
|
isc_refcount_destroy(&rpz->refs);
|
||||||
|
|
||||||
if (dns_name_dynamic(&rpz->origin)) {
|
if (dns_name_dynamic(&rpz->origin))
|
||||||
dns_name_free(&rpz->origin, rpzs->mctx);
|
dns_name_free(&rpz->origin, rpzs->mctx);
|
||||||
}
|
if (dns_name_dynamic(&rpz->client_ip))
|
||||||
if (dns_name_dynamic(&rpz->client_ip)) {
|
|
||||||
dns_name_free(&rpz->client_ip, rpzs->mctx);
|
dns_name_free(&rpz->client_ip, rpzs->mctx);
|
||||||
}
|
if (dns_name_dynamic(&rpz->ip))
|
||||||
if (dns_name_dynamic(&rpz->ip)) {
|
|
||||||
dns_name_free(&rpz->ip, rpzs->mctx);
|
dns_name_free(&rpz->ip, rpzs->mctx);
|
||||||
}
|
if (dns_name_dynamic(&rpz->nsdname))
|
||||||
if (dns_name_dynamic(&rpz->nsdname)) {
|
|
||||||
dns_name_free(&rpz->nsdname, rpzs->mctx);
|
dns_name_free(&rpz->nsdname, rpzs->mctx);
|
||||||
}
|
if (dns_name_dynamic(&rpz->nsip))
|
||||||
if (dns_name_dynamic(&rpz->nsip)) {
|
|
||||||
dns_name_free(&rpz->nsip, rpzs->mctx);
|
dns_name_free(&rpz->nsip, rpzs->mctx);
|
||||||
}
|
if (dns_name_dynamic(&rpz->passthru))
|
||||||
if (dns_name_dynamic(&rpz->passthru)) {
|
|
||||||
dns_name_free(&rpz->passthru, rpzs->mctx);
|
dns_name_free(&rpz->passthru, rpzs->mctx);
|
||||||
}
|
if (dns_name_dynamic(&rpz->drop))
|
||||||
if (dns_name_dynamic(&rpz->drop)) {
|
|
||||||
dns_name_free(&rpz->drop, rpzs->mctx);
|
dns_name_free(&rpz->drop, rpzs->mctx);
|
||||||
}
|
if (dns_name_dynamic(&rpz->tcp_only))
|
||||||
if (dns_name_dynamic(&rpz->tcp_only)) {
|
|
||||||
dns_name_free(&rpz->tcp_only, rpzs->mctx);
|
dns_name_free(&rpz->tcp_only, rpzs->mctx);
|
||||||
}
|
if (dns_name_dynamic(&rpz->cname))
|
||||||
if (dns_name_dynamic(&rpz->cname)) {
|
|
||||||
dns_name_free(&rpz->cname, rpzs->mctx);
|
dns_name_free(&rpz->cname, rpzs->mctx);
|
||||||
}
|
if (rpz->db_registered)
|
||||||
if (rpz->db_registered) {
|
|
||||||
dns_db_updatenotify_unregister(rpz->db,
|
dns_db_updatenotify_unregister(rpz->db,
|
||||||
dns_rpz_dbupdate_callback, rpz);
|
dns_rpz_dbupdate_callback, rpz);
|
||||||
}
|
if (rpz->dbversion != NULL)
|
||||||
if (rpz->dbversion != NULL) {
|
|
||||||
dns_db_closeversion(rpz->db, &rpz->dbversion,
|
dns_db_closeversion(rpz->db, &rpz->dbversion,
|
||||||
ISC_FALSE);
|
ISC_FALSE);
|
||||||
}
|
if (rpz->db)
|
||||||
if (rpz->db) {
|
|
||||||
dns_db_detach(&rpz->db);
|
dns_db_detach(&rpz->db);
|
||||||
}
|
|
||||||
isc_ht_destroy(&rpz->nodes);
|
isc_ht_destroy(&rpz->nodes);
|
||||||
isc_timer_detach(&rpz->updatetimer);
|
isc_timer_detach(&rpz->updatetimer);
|
||||||
|
|
||||||
isc_mem_put(rpzs->mctx, rpz, sizeof(*rpz));
|
isc_mem_put(rpzs->mctx, rpz, sizeof(*rpz));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_rpz_attach_rpzs(dns_rpz_zones_t *rpzs, dns_rpz_zones_t **rpzsp) {
|
dns_rpz_attach_rpzs(dns_rpz_zones_t *rpzs, dns_rpz_zones_t **rpzsp) {
|
||||||
REQUIRE(rpzsp != NULL && *rpzsp == NULL);
|
REQUIRE(rpzsp != NULL && *rpzsp == NULL);
|
||||||
isc_refcount_increment(&rpzs->refs);
|
isc_refcount_increment(&rpzs->refs, NULL);
|
||||||
*rpzsp = rpzs;
|
*rpzsp = rpzs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2117,19 +2104,18 @@ dns_rpz_detach_rpzs(dns_rpz_zones_t **rpzsp) {
|
|||||||
dns_rpz_zones_t *rpzs;
|
dns_rpz_zones_t *rpzs;
|
||||||
dns_rpz_zone_t *rpz;
|
dns_rpz_zone_t *rpz;
|
||||||
dns_rpz_num_t rpz_num;
|
dns_rpz_num_t rpz_num;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
|
|
||||||
REQUIRE(rpzsp != NULL);
|
REQUIRE(rpzsp != NULL);
|
||||||
rpzs = *rpzsp;
|
rpzs = *rpzsp;
|
||||||
REQUIRE(rpzs != NULL);
|
REQUIRE(rpzs != NULL);
|
||||||
|
|
||||||
*rpzsp = NULL;
|
*rpzsp = NULL;
|
||||||
refs = isc_refcount_decrement(&rpzs->refs);
|
isc_refcount_decrement(&rpzs->refs, &refs);
|
||||||
|
if (refs != 0) {
|
||||||
if (refs > 1) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Forget the last of view's rpz machinery after the last reference.
|
* Forget the last of view's rpz machinery after the last reference.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+9
-12
@@ -375,9 +375,8 @@ dns_tsigkey_createfromkey(const dns_name_t *name, const dns_name_t *algorithm,
|
|||||||
|
|
||||||
cleanup_refs:
|
cleanup_refs:
|
||||||
tkey->magic = 0;
|
tkey->magic = 0;
|
||||||
while (refs-- > 0) {
|
while (refs-- > 0)
|
||||||
isc_refcount_decrement(&tkey->refs);
|
isc_refcount_decrement(&tkey->refs, NULL);
|
||||||
}
|
|
||||||
isc_refcount_destroy(&tkey->refs);
|
isc_refcount_destroy(&tkey->refs);
|
||||||
cleanup_creator:
|
cleanup_creator:
|
||||||
if (tkey->key != NULL)
|
if (tkey->key != NULL)
|
||||||
@@ -713,7 +712,7 @@ dns_tsigkey_attach(dns_tsigkey_t *source, dns_tsigkey_t **targetp) {
|
|||||||
REQUIRE(VALID_TSIG_KEY(source));
|
REQUIRE(VALID_TSIG_KEY(source));
|
||||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||||
|
|
||||||
isc_refcount_increment(&source->refs);
|
isc_refcount_increment(&source->refs, NULL);
|
||||||
*targetp = source;
|
*targetp = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -742,17 +741,16 @@ tsigkey_free(dns_tsigkey_t *key) {
|
|||||||
void
|
void
|
||||||
dns_tsigkey_detach(dns_tsigkey_t **keyp) {
|
dns_tsigkey_detach(dns_tsigkey_t **keyp) {
|
||||||
dns_tsigkey_t *key;
|
dns_tsigkey_t *key;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
|
|
||||||
REQUIRE(keyp != NULL);
|
REQUIRE(keyp != NULL);
|
||||||
REQUIRE(VALID_TSIG_KEY(*keyp));
|
REQUIRE(VALID_TSIG_KEY(*keyp));
|
||||||
|
|
||||||
key = *keyp;
|
key = *keyp;
|
||||||
refs = isc_refcount_decrement(&key->refs);
|
isc_refcount_decrement(&key->refs, &refs);
|
||||||
|
|
||||||
if (refs == 1) {
|
if (refs == 0)
|
||||||
tsigkey_free(key);
|
tsigkey_free(key);
|
||||||
}
|
|
||||||
|
|
||||||
*keyp = NULL;
|
*keyp = NULL;
|
||||||
}
|
}
|
||||||
@@ -1792,7 +1790,7 @@ dns_tsigkey_find(dns_tsigkey_t **tsigkey, const dns_name_t *name,
|
|||||||
return (ISC_R_NOTFOUND);
|
return (ISC_R_NOTFOUND);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
isc_refcount_increment(&key->refs);
|
isc_refcount_increment(&key->refs, NULL);
|
||||||
RWUNLOCK(&ring->lock, isc_rwlocktype_read);
|
RWUNLOCK(&ring->lock, isc_rwlocktype_read);
|
||||||
adjust_lru(key);
|
adjust_lru(key);
|
||||||
*tsigkey = key;
|
*tsigkey = key;
|
||||||
@@ -1861,9 +1859,8 @@ dns_tsigkeyring_add(dns_tsig_keyring_t *ring, const dns_name_t *name,
|
|||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
|
||||||
result = keyring_add(ring, name, tkey);
|
result = keyring_add(ring, name, tkey);
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS)
|
||||||
isc_refcount_increment(&tkey->refs);
|
isc_refcount_increment(&tkey->refs, NULL);
|
||||||
}
|
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -567,7 +567,7 @@ dns_view_attach(dns_view_t *source, dns_view_t **targetp) {
|
|||||||
REQUIRE(DNS_VIEW_VALID(source));
|
REQUIRE(DNS_VIEW_VALID(source));
|
||||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||||
|
|
||||||
isc_refcount_increment(&source->references);
|
isc_refcount_increment(&source->references, NULL);
|
||||||
|
|
||||||
*targetp = source;
|
*targetp = source;
|
||||||
}
|
}
|
||||||
@@ -575,7 +575,7 @@ dns_view_attach(dns_view_t *source, dns_view_t **targetp) {
|
|||||||
static void
|
static void
|
||||||
view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
|
view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
|
||||||
dns_view_t *view;
|
dns_view_t *view;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
isc_boolean_t done = ISC_FALSE;
|
isc_boolean_t done = ISC_FALSE;
|
||||||
|
|
||||||
REQUIRE(viewp != NULL);
|
REQUIRE(viewp != NULL);
|
||||||
@@ -584,8 +584,8 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
|
|||||||
|
|
||||||
if (flush)
|
if (flush)
|
||||||
view->flush = ISC_TRUE;
|
view->flush = ISC_TRUE;
|
||||||
refs = isc_refcount_decrement(&view->references);
|
isc_refcount_decrement(&view->references, &refs);
|
||||||
if (refs == 1) {
|
if (refs == 0) {
|
||||||
dns_zone_t *mkzone = NULL, *rdzone = NULL;
|
dns_zone_t *mkzone = NULL, *rdzone = NULL;
|
||||||
|
|
||||||
LOCK(&view->lock);
|
LOCK(&view->lock);
|
||||||
|
|||||||
+101
-85
@@ -174,6 +174,18 @@ typedef struct dns_include dns_include_t;
|
|||||||
do { result = isc_mutex_trylock(&(z)->lock); } while (0)
|
do { result = isc_mutex_trylock(&(z)->lock); } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ISC_RWLOCK_USEATOMIC
|
||||||
|
#define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
|
||||||
|
#define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
|
||||||
|
#define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
|
||||||
|
#define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
|
||||||
|
#else
|
||||||
|
#define ZONEDB_INITLOCK(l) isc_mutex_init(l)
|
||||||
|
#define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
|
||||||
|
#define ZONEDB_LOCK(l, t) LOCK(l)
|
||||||
|
#define ZONEDB_UNLOCK(l, t) UNLOCK(l)
|
||||||
|
#endif
|
||||||
|
|
||||||
struct dns_zone {
|
struct dns_zone {
|
||||||
/* Unlocked */
|
/* Unlocked */
|
||||||
unsigned int magic;
|
unsigned int magic;
|
||||||
@@ -184,7 +196,11 @@ struct dns_zone {
|
|||||||
isc_mem_t *mctx;
|
isc_mem_t *mctx;
|
||||||
isc_refcount_t erefs;
|
isc_refcount_t erefs;
|
||||||
|
|
||||||
|
#ifdef ISC_RWLOCK_USEATOMIC
|
||||||
isc_rwlock_t dblock;
|
isc_rwlock_t dblock;
|
||||||
|
#else
|
||||||
|
isc_mutex_t dblock;
|
||||||
|
#endif
|
||||||
dns_db_t *db; /* Locked by dblock */
|
dns_db_t *db; /* Locked by dblock */
|
||||||
|
|
||||||
/* Locked */
|
/* Locked */
|
||||||
@@ -886,7 +902,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
|
|||||||
goto free_zone;
|
goto free_zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = isc_rwlock_init(&zone->dblock, 0, 0);
|
result = ZONEDB_INITLOCK(&zone->dblock);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto free_mutex;
|
goto free_mutex;
|
||||||
}
|
}
|
||||||
@@ -1068,11 +1084,11 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
|
|||||||
isc_stats_detach(&zone->gluecachestats);
|
isc_stats_detach(&zone->gluecachestats);
|
||||||
|
|
||||||
free_erefs:
|
free_erefs:
|
||||||
isc_refcount_decrement(&zone->erefs);
|
isc_refcount_decrement(&zone->erefs, NULL);
|
||||||
isc_refcount_destroy(&zone->erefs);
|
isc_refcount_destroy(&zone->erefs);
|
||||||
|
|
||||||
free_dblock:
|
free_dblock:
|
||||||
isc_rwlock_destroy(&zone->dblock);
|
ZONEDB_DESTROYLOCK(&zone->dblock);
|
||||||
|
|
||||||
free_mutex:
|
free_mutex:
|
||||||
DESTROYLOCK(&zone->lock);
|
DESTROYLOCK(&zone->lock);
|
||||||
@@ -1233,7 +1249,7 @@ zone_free(dns_zone_t *zone) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* last stuff */
|
/* last stuff */
|
||||||
isc_rwlock_destroy(&zone->dblock);
|
ZONEDB_DESTROYLOCK(&zone->dblock);
|
||||||
DESTROYLOCK(&zone->lock);
|
DESTROYLOCK(&zone->lock);
|
||||||
isc_refcount_destroy(&zone->erefs);
|
isc_refcount_destroy(&zone->erefs);
|
||||||
zone->magic = 0;
|
zone->magic = 0;
|
||||||
@@ -1325,7 +1341,7 @@ dns_zone_getserial(dns_zone_t *zone, isc_uint32_t *serialp) {
|
|||||||
REQUIRE(serialp != NULL);
|
REQUIRE(serialp != NULL);
|
||||||
|
|
||||||
LOCK_ZONE(zone);
|
LOCK_ZONE(zone);
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL) {
|
if (zone->db != NULL) {
|
||||||
result = zone_get_from_db(zone, zone->db, NULL, &soacount,
|
result = zone_get_from_db(zone, zone->db, NULL, &soacount,
|
||||||
serialp, NULL, NULL, NULL, NULL,
|
serialp, NULL, NULL, NULL, NULL,
|
||||||
@@ -1334,7 +1350,7 @@ dns_zone_getserial(dns_zone_t *zone, isc_uint32_t *serialp) {
|
|||||||
result = ISC_R_FAILURE;
|
result = ISC_R_FAILURE;
|
||||||
} else
|
} else
|
||||||
result = DNS_R_NOTLOADED;
|
result = DNS_R_NOTLOADED;
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
UNLOCK_ZONE(zone);
|
UNLOCK_ZONE(zone);
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
@@ -1989,7 +2005,7 @@ zone_load(dns_zone_t *zone, unsigned int flags, isc_boolean_t locked) {
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_write);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
|
||||||
/* ask SDLZ driver if the zone is supported */
|
/* ask SDLZ driver if the zone is supported */
|
||||||
findzone = dlzdb->implementation->methods->findzone;
|
findzone = dlzdb->implementation->methods->findzone;
|
||||||
result = (*findzone)(dlzdb->implementation->driverarg,
|
result = (*findzone)(dlzdb->implementation->driverarg,
|
||||||
@@ -2003,7 +2019,7 @@ zone_load(dns_zone_t *zone, unsigned int flags, isc_boolean_t locked) {
|
|||||||
dns_db_detach(&db);
|
dns_db_detach(&db);
|
||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
}
|
}
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_write);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
|
||||||
|
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
if (dlzdb->configure_callback == NULL)
|
if (dlzdb->configure_callback == NULL)
|
||||||
@@ -2364,7 +2380,7 @@ zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
|
|||||||
|
|
||||||
LOCK_ZONE(zone);
|
LOCK_ZONE(zone);
|
||||||
INSIST(zone != zone->raw);
|
INSIST(zone != zone->raw);
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL) {
|
if (zone->db != NULL) {
|
||||||
const dns_master_style_t *output_style;
|
const dns_master_style_t *output_style;
|
||||||
|
|
||||||
@@ -2386,7 +2402,7 @@ zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
|
|||||||
dns_db_closeversion(zone->db, &version, ISC_FALSE);
|
dns_db_closeversion(zone->db, &version, ISC_FALSE);
|
||||||
} else
|
} else
|
||||||
result = ISC_R_CANCELED;
|
result = ISC_R_CANCELED;
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
UNLOCK_ZONE(zone);
|
UNLOCK_ZONE(zone);
|
||||||
if (result != DNS_R_CONTINUE)
|
if (result != DNS_R_CONTINUE)
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -3191,10 +3207,10 @@ resume_signingwithkey(dns_zone_t *zone) {
|
|||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
dns_db_t *db = NULL;
|
dns_db_t *db = NULL;
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL)
|
if (zone->db != NULL)
|
||||||
dns_db_attach(zone->db, &db);
|
dns_db_attach(zone->db, &db);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (db == NULL)
|
if (db == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@@ -3264,10 +3280,10 @@ zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
|
|||||||
char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
|
char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
|
||||||
dns_db_t *db = NULL;
|
dns_db_t *db = NULL;
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL)
|
if (zone->db != NULL)
|
||||||
dns_db_attach(zone->db, &db);
|
dns_db_attach(zone->db, &db);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
|
|
||||||
if (db == NULL) {
|
if (db == NULL) {
|
||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
@@ -3443,10 +3459,10 @@ resume_addnsec3chain(dns_zone_t *zone) {
|
|||||||
if (zone->privatetype == 0)
|
if (zone->privatetype == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL)
|
if (zone->db != NULL)
|
||||||
dns_db_attach(zone->db, &db);
|
dns_db_attach(zone->db, &db);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (db == NULL)
|
if (db == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@@ -3542,10 +3558,10 @@ set_resigntime(dns_zone_t *zone) {
|
|||||||
dns_rdataset_init(&rdataset);
|
dns_rdataset_init(&rdataset);
|
||||||
dns_fixedname_init(&fixed);
|
dns_fixedname_init(&fixed);
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL)
|
if (zone->db != NULL)
|
||||||
dns_db_attach(zone->db, &db);
|
dns_db_attach(zone->db, &db);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (db == NULL) {
|
if (db == NULL) {
|
||||||
isc_time_settoepoch(&zone->resigntime);
|
isc_time_settoepoch(&zone->resigntime);
|
||||||
return;
|
return;
|
||||||
@@ -4719,15 +4735,15 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
|||||||
DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
|
DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
|
||||||
zone->refreshkeytime = now;
|
zone->refreshkeytime = now;
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_write);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
|
||||||
if (zone->db != NULL) {
|
if (zone->db != NULL) {
|
||||||
result = zone_replacedb(zone, db, ISC_FALSE);
|
result = zone_replacedb(zone, db, ISC_FALSE);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_write);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else {
|
} else {
|
||||||
zone_attachdb(zone, db);
|
zone_attachdb(zone, db);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_write);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
|
||||||
DNS_ZONE_SETFLAG(zone,
|
DNS_ZONE_SETFLAG(zone,
|
||||||
DNS_ZONEFLG_LOADED|
|
DNS_ZONEFLG_LOADED|
|
||||||
DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
|
DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
|
||||||
@@ -5178,7 +5194,7 @@ void
|
|||||||
dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
|
dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
|
||||||
REQUIRE(DNS_ZONE_VALID(source));
|
REQUIRE(DNS_ZONE_VALID(source));
|
||||||
REQUIRE(target != NULL && *target == NULL);
|
REQUIRE(target != NULL && *target == NULL);
|
||||||
isc_refcount_increment(&source->erefs);
|
isc_refcount_increment(&source->erefs, NULL);
|
||||||
*target = source;
|
*target = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5187,16 +5203,16 @@ dns_zone_detach(dns_zone_t **zonep) {
|
|||||||
dns_zone_t *zone;
|
dns_zone_t *zone;
|
||||||
dns_zone_t *raw = NULL;
|
dns_zone_t *raw = NULL;
|
||||||
dns_zone_t *secure = NULL;
|
dns_zone_t *secure = NULL;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
isc_boolean_t free_now = ISC_FALSE;
|
isc_boolean_t free_now = ISC_FALSE;
|
||||||
|
|
||||||
REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
|
REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
|
||||||
|
|
||||||
zone = *zonep;
|
zone = *zonep;
|
||||||
|
|
||||||
refs = isc_refcount_decrement(&zone->erefs);
|
isc_refcount_decrement(&zone->erefs, &refs);
|
||||||
|
|
||||||
if (refs == 1) {
|
if (refs == 0) {
|
||||||
LOCK_ZONE(zone);
|
LOCK_ZONE(zone);
|
||||||
INSIST(zone != zone->raw);
|
INSIST(zone != zone->raw);
|
||||||
/*
|
/*
|
||||||
@@ -5903,12 +5919,12 @@ dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
|
|||||||
|
|
||||||
REQUIRE(DNS_ZONE_VALID(zone));
|
REQUIRE(DNS_ZONE_VALID(zone));
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db == NULL)
|
if (zone->db == NULL)
|
||||||
result = DNS_R_NOTLOADED;
|
result = DNS_R_NOTLOADED;
|
||||||
else
|
else
|
||||||
dns_db_attach(zone->db, dpb);
|
dns_db_attach(zone->db, dpb);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
@@ -5918,10 +5934,10 @@ dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
|
|||||||
REQUIRE(DNS_ZONE_VALID(zone));
|
REQUIRE(DNS_ZONE_VALID(zone));
|
||||||
REQUIRE(zone->type == dns_zone_staticstub);
|
REQUIRE(zone->type == dns_zone_staticstub);
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_write);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
|
||||||
REQUIRE(zone->db == NULL);
|
REQUIRE(zone->db == NULL);
|
||||||
dns_db_attach(db, &zone->db);
|
dns_db_attach(db, &zone->db);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_write);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6417,9 +6433,9 @@ zone_resigninc(dns_zone_t *zone) {
|
|||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
dns_db_attach(zone->db, &db);
|
dns_db_attach(zone->db, &db);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
|
|
||||||
result = dns_db_newversion(db, &version);
|
result = dns_db_newversion(db, &version);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
@@ -7421,7 +7437,7 @@ zone_nsec3chain(dns_zone_t *zone) {
|
|||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
/*
|
/*
|
||||||
* This function is called when zone timer fires, after the latter gets
|
* This function is called when zone timer fires, after the latter gets
|
||||||
* set by zone_addnsec3chain(). If the action triggering the call to
|
* set by zone_addnsec3chain(). If the action triggering the call to
|
||||||
@@ -7434,7 +7450,7 @@ zone_nsec3chain(dns_zone_t *zone) {
|
|||||||
if (zone->db != NULL) {
|
if (zone->db != NULL) {
|
||||||
dns_db_attach(zone->db, &db);
|
dns_db_attach(zone->db, &db);
|
||||||
}
|
}
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (db == NULL) {
|
if (db == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -7511,12 +7527,12 @@ zone_nsec3chain(dns_zone_t *zone) {
|
|||||||
LOCK_ZONE(zone);
|
LOCK_ZONE(zone);
|
||||||
nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
|
nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (nsec3chain->done || nsec3chain->db != zone->db) {
|
if (nsec3chain->done || nsec3chain->db != zone->db) {
|
||||||
ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
|
ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
|
||||||
ISC_LIST_APPEND(cleanup, nsec3chain, link);
|
ISC_LIST_APPEND(cleanup, nsec3chain, link);
|
||||||
}
|
}
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
UNLOCK_ZONE(zone);
|
UNLOCK_ZONE(zone);
|
||||||
if (ISC_LIST_TAIL(cleanup) == nsec3chain)
|
if (ISC_LIST_TAIL(cleanup) == nsec3chain)
|
||||||
goto next_addchain;
|
goto next_addchain;
|
||||||
@@ -8312,10 +8328,10 @@ zone_sign(dns_zone_t *zone) {
|
|||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL)
|
if (zone->db != NULL)
|
||||||
dns_db_attach(zone->db, &db);
|
dns_db_attach(zone->db, &db);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (db == NULL) {
|
if (db == NULL) {
|
||||||
result = ISC_R_FAILURE;
|
result = ISC_R_FAILURE;
|
||||||
goto failure;
|
goto failure;
|
||||||
@@ -8374,7 +8390,7 @@ zone_sign(dns_zone_t *zone) {
|
|||||||
while (signing != NULL && nodes-- > 0 && signatures > 0) {
|
while (signing != NULL && nodes-- > 0 && signatures > 0) {
|
||||||
nextsigning = ISC_LIST_NEXT(signing, link);
|
nextsigning = ISC_LIST_NEXT(signing, link);
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (signing->done || signing->db != zone->db) {
|
if (signing->done || signing->db != zone->db) {
|
||||||
/*
|
/*
|
||||||
* The zone has been reloaded. We will have
|
* The zone has been reloaded. We will have
|
||||||
@@ -8383,10 +8399,10 @@ zone_sign(dns_zone_t *zone) {
|
|||||||
*/
|
*/
|
||||||
ISC_LIST_UNLINK(zone->signing, signing, link);
|
ISC_LIST_UNLINK(zone->signing, signing, link);
|
||||||
ISC_LIST_APPEND(cleanup, signing, link);
|
ISC_LIST_APPEND(cleanup, signing, link);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
goto next_signing;
|
goto next_signing;
|
||||||
}
|
}
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
|
|
||||||
if (signing->db != db)
|
if (signing->db != db)
|
||||||
goto next_signing;
|
goto next_signing;
|
||||||
@@ -9656,9 +9672,9 @@ zone_refreshkeys(dns_zone_t *zone) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
dns_db_attach(zone->db, &db);
|
dns_db_attach(zone->db, &db);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
|
|
||||||
dns_diff_init(zone->mctx, &diff);
|
dns_diff_init(zone->mctx, &diff);
|
||||||
|
|
||||||
@@ -10023,7 +10039,7 @@ dns_zone_markdirty(dns_zone_t *zone) {
|
|||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL) {
|
if (zone->db != NULL) {
|
||||||
result = zone_get_from_db(zone, zone->db, NULL,
|
result = zone_get_from_db(zone, zone->db, NULL,
|
||||||
&soacount, &serial,
|
&soacount, &serial,
|
||||||
@@ -10031,7 +10047,7 @@ dns_zone_markdirty(dns_zone_t *zone) {
|
|||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
} else
|
} else
|
||||||
result = DNS_R_NOTLOADED;
|
result = DNS_R_NOTLOADED;
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (result == ISC_R_SUCCESS && soacount > 0U)
|
if (result == ISC_R_SUCCESS && soacount > 0U)
|
||||||
zone_send_secureserial(zone, serial);
|
zone_send_secureserial(zone, serial);
|
||||||
}
|
}
|
||||||
@@ -10300,7 +10316,7 @@ dump_done(void *arg, isc_result_t result) {
|
|||||||
isc_uint32_t sserial;
|
isc_uint32_t sserial;
|
||||||
isc_result_t mresult;
|
isc_result_t mresult;
|
||||||
|
|
||||||
RWLOCK(&secure->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&secure->dblock, isc_rwlocktype_read);
|
||||||
if (secure->db != NULL) {
|
if (secure->db != NULL) {
|
||||||
mresult = dns_db_getsoaserial(zone->secure->db,
|
mresult = dns_db_getsoaserial(zone->secure->db,
|
||||||
NULL, &sserial);
|
NULL, &sserial);
|
||||||
@@ -10308,7 +10324,7 @@ dump_done(void *arg, isc_result_t result) {
|
|||||||
isc_serial_lt(sserial, serial))
|
isc_serial_lt(sserial, serial))
|
||||||
serial = sserial;
|
serial = sserial;
|
||||||
}
|
}
|
||||||
RWUNLOCK(&secure->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&secure->dblock, isc_rwlocktype_read);
|
||||||
}
|
}
|
||||||
if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
|
if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
|
||||||
dns_db_t *zdb = NULL;
|
dns_db_t *zdb = NULL;
|
||||||
@@ -10372,10 +10388,10 @@ zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
|
|||||||
ENTER;
|
ENTER;
|
||||||
|
|
||||||
redo:
|
redo:
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL)
|
if (zone->db != NULL)
|
||||||
dns_db_attach(zone->db, &db);
|
dns_db_attach(zone->db, &db);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
LOCK_ZONE(zone);
|
LOCK_ZONE(zone);
|
||||||
if (zone->masterfile != NULL) {
|
if (zone->masterfile != NULL) {
|
||||||
masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
|
masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
|
||||||
@@ -10465,10 +10481,10 @@ dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
|
|||||||
|
|
||||||
REQUIRE(DNS_ZONE_VALID(zone));
|
REQUIRE(DNS_ZONE_VALID(zone));
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL)
|
if (zone->db != NULL)
|
||||||
dns_db_attach(zone->db, &db);
|
dns_db_attach(zone->db, &db);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (db == NULL)
|
if (db == NULL)
|
||||||
return (DNS_R_NOTLOADED);
|
return (DNS_R_NOTLOADED);
|
||||||
|
|
||||||
@@ -10560,9 +10576,9 @@ zone_unload(dns_zone_t *zone) {
|
|||||||
if (zone->dctx != NULL)
|
if (zone->dctx != NULL)
|
||||||
dns_dumpctx_cancel(zone->dctx);
|
dns_dumpctx_cancel(zone->dctx);
|
||||||
}
|
}
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_write);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
|
||||||
zone_detachdb(zone);
|
zone_detachdb(zone);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_write);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
|
||||||
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
|
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
|
||||||
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
|
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
|
||||||
}
|
}
|
||||||
@@ -11114,10 +11130,10 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
|
|||||||
/*
|
/*
|
||||||
* Get SOA RRset.
|
* Get SOA RRset.
|
||||||
*/
|
*/
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL)
|
if (zone->db != NULL)
|
||||||
dns_db_attach(zone->db, &zonedb);
|
dns_db_attach(zone->db, &zonedb);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zonedb == NULL)
|
if (zonedb == NULL)
|
||||||
return;
|
return;
|
||||||
dns_db_currentversion(zonedb, &version);
|
dns_db_currentversion(zonedb, &version);
|
||||||
@@ -11517,7 +11533,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) {
|
|||||||
* Tidy up.
|
* Tidy up.
|
||||||
*/
|
*/
|
||||||
dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
|
dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_write);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
|
||||||
if (zone->db == NULL)
|
if (zone->db == NULL)
|
||||||
zone_attachdb(zone, stub->db);
|
zone_attachdb(zone, stub->db);
|
||||||
result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
|
result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
|
||||||
@@ -11530,7 +11546,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) {
|
|||||||
DNS_MAX_EXPIRE);
|
DNS_MAX_EXPIRE);
|
||||||
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
|
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
|
||||||
}
|
}
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_write);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
|
||||||
dns_db_detach(&stub->db);
|
dns_db_detach(&stub->db);
|
||||||
|
|
||||||
dns_message_destroy(&msg);
|
dns_message_destroy(&msg);
|
||||||
@@ -12464,12 +12480,12 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
|
|||||||
* new one and attach it to the zone once we have the NS
|
* new one and attach it to the zone once we have the NS
|
||||||
* RRset and glue.
|
* RRset and glue.
|
||||||
*/
|
*/
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL) {
|
if (zone->db != NULL) {
|
||||||
dns_db_attach(zone->db, &stub->db);
|
dns_db_attach(zone->db, &stub->db);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
} else {
|
} else {
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
|
|
||||||
INSIST(zone->db_argc >= 1);
|
INSIST(zone->db_argc >= 1);
|
||||||
result = dns_db_create(zone->mctx, zone->db_argv[0],
|
result = dns_db_create(zone->mctx, zone->db_argv[0],
|
||||||
@@ -13004,10 +13020,10 @@ notify_createmessage(dns_zone_t *zone, unsigned int flags,
|
|||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto soa_cleanup;
|
goto soa_cleanup;
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
|
INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
|
||||||
dns_db_attach(zone->db, &zonedb);
|
dns_db_attach(zone->db, &zonedb);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
|
|
||||||
dns_name_init(tempname, NULL);
|
dns_name_init(tempname, NULL);
|
||||||
dns_name_clone(&zone->origin, tempname);
|
dns_name_clone(&zone->origin, tempname);
|
||||||
@@ -13803,10 +13819,10 @@ dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
|
|||||||
if (zone->task != NULL)
|
if (zone->task != NULL)
|
||||||
isc_task_detach(&zone->task);
|
isc_task_detach(&zone->task);
|
||||||
isc_task_attach(task, &zone->task);
|
isc_task_attach(task, &zone->task);
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL)
|
if (zone->db != NULL)
|
||||||
dns_db_settask(zone->db, zone->task);
|
dns_db_settask(zone->db, zone->task);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
UNLOCK_ZONE(zone);
|
UNLOCK_ZONE(zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14138,12 +14154,12 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
|
|||||||
* zone->db may be NULL, if the load from disk failed.
|
* zone->db may be NULL, if the load from disk failed.
|
||||||
*/
|
*/
|
||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL)
|
if (zone->db != NULL)
|
||||||
dns_db_attach(zone->db, &zone->rss_db);
|
dns_db_attach(zone->db, &zone->rss_db);
|
||||||
else
|
else
|
||||||
result = ISC_R_FAILURE;
|
result = ISC_R_FAILURE;
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
|
|
||||||
if (result == ISC_R_SUCCESS && zone->raw != NULL)
|
if (result == ISC_R_SUCCESS && zone->raw != NULL)
|
||||||
dns_zone_attach(zone->raw, &zone->rss_raw);
|
dns_zone_attach(zone->raw, &zone->rss_raw);
|
||||||
@@ -14643,7 +14659,7 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TIME_NOW(&loadtime);
|
TIME_NOW(&loadtime);
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL) {
|
if (zone->db != NULL) {
|
||||||
result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
|
result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
|
||||||
if (result == ISC_R_SUCCESS)
|
if (result == ISC_R_SUCCESS)
|
||||||
@@ -14655,11 +14671,11 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
|
|||||||
*/
|
*/
|
||||||
result = save_nsec3param(zone, &nsec3list);
|
result = save_nsec3param(zone, &nsec3list);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
|
|
||||||
result = dns_db_create(zone->mctx, zone->db_argv[0],
|
result = dns_db_create(zone->mctx, zone->db_argv[0],
|
||||||
&zone->origin, dns_dbtype_zone, zone->rdclass,
|
&zone->origin, dns_dbtype_zone, zone->rdclass,
|
||||||
@@ -14821,9 +14837,9 @@ dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
|
|||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_write);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
|
||||||
result = zone_replacedb(zone, db, dump);
|
result = zone_replacedb(zone, db, dump);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_write);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
|
||||||
if (secure != NULL)
|
if (secure != NULL)
|
||||||
UNLOCK_ZONE(secure);
|
UNLOCK_ZONE(secure);
|
||||||
UNLOCK_ZONE(zone);
|
UNLOCK_ZONE(zone);
|
||||||
@@ -15065,9 +15081,9 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
|
|||||||
/*
|
/*
|
||||||
* Has the zone expired underneath us?
|
* Has the zone expired underneath us?
|
||||||
*/
|
*/
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db == NULL) {
|
if (zone->db == NULL) {
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
goto same_master;
|
goto same_master;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15081,7 +15097,7 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
|
|||||||
result = zone_get_from_db(zone, zone->db, &nscount,
|
result = zone_get_from_db(zone, zone->db, &nscount,
|
||||||
&soacount, &serial, &refresh,
|
&soacount, &serial, &refresh,
|
||||||
&retry, &expire, &minimum, NULL);
|
&retry, &expire, &minimum, NULL);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
if (soacount != 1)
|
if (soacount != 1)
|
||||||
dns_zone_log(zone, ISC_LOG_ERROR,
|
dns_zone_log(zone, ISC_LOG_ERROR,
|
||||||
@@ -15496,9 +15512,9 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) {
|
|||||||
/*
|
/*
|
||||||
* Decide whether we should request IXFR or AXFR.
|
* Decide whether we should request IXFR or AXFR.
|
||||||
*/
|
*/
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
loaded = ISC_TF(zone->db != NULL);
|
loaded = ISC_TF(zone->db != NULL);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
|
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
dns_zone_log(zone, ISC_LOG_DEBUG(1),
|
dns_zone_log(zone, ISC_LOG_DEBUG(1),
|
||||||
@@ -17318,10 +17334,10 @@ zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
|
|||||||
|
|
||||||
TIME_NOW(&now);
|
TIME_NOW(&now);
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL)
|
if (zone->db != NULL)
|
||||||
dns_db_attach(zone->db, &db);
|
dns_db_attach(zone->db, &db);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
|
|
||||||
if (db == NULL) {
|
if (db == NULL) {
|
||||||
result = ISC_R_NOTFOUND;
|
result = ISC_R_NOTFOUND;
|
||||||
@@ -18461,7 +18477,7 @@ dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
|
|||||||
|
|
||||||
|
|
||||||
/* dns_zone_attach(raw, &zone->raw); */
|
/* dns_zone_attach(raw, &zone->raw); */
|
||||||
isc_refcount_increment(&raw->erefs);
|
isc_refcount_increment(&raw->erefs, NULL);
|
||||||
zone->raw = raw;
|
zone->raw = raw;
|
||||||
|
|
||||||
/* dns_zone_iattach(zone, &raw->secure); */
|
/* dns_zone_iattach(zone, &raw->secure); */
|
||||||
@@ -18527,10 +18543,10 @@ keydone(isc_task_t *task, isc_event_t *event) {
|
|||||||
dns_rdataset_init(&rdataset);
|
dns_rdataset_init(&rdataset);
|
||||||
dns_diff_init(zone->mctx, &diff);
|
dns_diff_init(zone->mctx, &diff);
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL)
|
if (zone->db != NULL)
|
||||||
dns_db_attach(zone->db, &db);
|
dns_db_attach(zone->db, &db);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (db == NULL)
|
if (db == NULL)
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
@@ -18732,17 +18748,17 @@ setnsec3param(isc_task_t *task, isc_event_t *event) {
|
|||||||
dns_rdataset_init(&nrdataset);
|
dns_rdataset_init(&nrdataset);
|
||||||
dns_diff_init(zone->mctx, &diff);
|
dns_diff_init(zone->mctx, &diff);
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL)
|
if (zone->db != NULL)
|
||||||
dns_db_attach(zone->db, &db);
|
dns_db_attach(zone->db, &db);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (db == NULL)
|
if (db == NULL)
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
dns_db_currentversion(db, &oldver);
|
dns_db_currentversion(db, &oldver);
|
||||||
result = dns_db_newversion(db, &newver);
|
result = dns_db_newversion(db, &newver);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
dns_zone_log(zone, ISC_LOG_ERROR,
|
dns_zone_log(zone, ISC_LOG_ERROR,
|
||||||
"setnsec3param:dns_db_newversion -> %s",
|
"setnsec3param:dns_db_newversion -> %s",
|
||||||
dns_result_totext(result));
|
dns_result_totext(result));
|
||||||
@@ -19085,10 +19101,10 @@ setserial(isc_task_t *task, isc_event_t *event) {
|
|||||||
|
|
||||||
dns_diff_init(zone->mctx, &diff);
|
dns_diff_init(zone->mctx, &diff);
|
||||||
|
|
||||||
RWLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (zone->db != NULL)
|
if (zone->db != NULL)
|
||||||
dns_db_attach(zone->db, &db);
|
dns_db_attach(zone->db, &db);
|
||||||
RWUNLOCK(&zone->dblock, isc_rwlocktype_read);
|
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||||
if (db == NULL)
|
if (db == NULL)
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -21,6 +21,7 @@ PROVIDER = @PKCS11_PROVIDER@
|
|||||||
|
|
||||||
CINCLUDES = -I${srcdir}/unix/include \
|
CINCLUDES = -I${srcdir}/unix/include \
|
||||||
-I${srcdir}/@ISC_THREAD_DIR@/include \
|
-I${srcdir}/@ISC_THREAD_DIR@/include \
|
||||||
|
-I${srcdir}/@ISC_ARCH_DIR@/include \
|
||||||
-I./include \
|
-I./include \
|
||||||
-I${srcdir}/include ${DNS_INCLUDES} @ISC_OPENSSL_INC@
|
-I${srcdir}/include ${DNS_INCLUDES} @ISC_OPENSSL_INC@
|
||||||
CDEFINES = -DPK11_LIB_LOCATION=\"${PROVIDER}\"
|
CDEFINES = -DPK11_LIB_LOCATION=\"${PROVIDER}\"
|
||||||
@@ -57,7 +58,7 @@ OBJS = @ISC_EXTRA_OBJS@ @ISC_PK11_O@ @ISC_PK11_RESULT_O@ \
|
|||||||
md5.@O@ mem.@O@ mutexblock.@O@ \
|
md5.@O@ mem.@O@ mutexblock.@O@ \
|
||||||
netaddr.@O@ netscope.@O@ pool.@O@ \
|
netaddr.@O@ netscope.@O@ pool.@O@ \
|
||||||
parseint.@O@ portset.@O@ quota.@O@ radix.@O@ random.@O@ \
|
parseint.@O@ portset.@O@ quota.@O@ radix.@O@ random.@O@ \
|
||||||
ratelimiter.@O@ region.@O@ regex.@O@ result.@O@ \
|
ratelimiter.@O@ refcount.@O@ region.@O@ regex.@O@ result.@O@ \
|
||||||
rwlock.@O@ \
|
rwlock.@O@ \
|
||||||
safe.@O@ serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ \
|
safe.@O@ serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ \
|
||||||
string.@O@ strtoul.@O@ symtab.@O@ task.@O@ taskpool.@O@ \
|
string.@O@ strtoul.@O@ symtab.@O@ task.@O@ taskpool.@O@ \
|
||||||
@@ -75,18 +76,18 @@ SRCS = @ISC_EXTRA_SRCS@ @ISC_PK11_C@ @ISC_PK11_RESULT_C@ \
|
|||||||
md5.c mem.c mutexblock.c \
|
md5.c mem.c mutexblock.c \
|
||||||
netaddr.c netscope.c pool.c \
|
netaddr.c netscope.c pool.c \
|
||||||
parseint.c portset.c quota.c radix.c random.c \
|
parseint.c portset.c quota.c radix.c random.c \
|
||||||
ratelimiter.c region.c regex.c result.c rwlock.c \
|
ratelimiter.c refcount.c region.c regex.c result.c rwlock.c \
|
||||||
safe.c serial.c sha1.c sha2.c sockaddr.c stats.c string.c \
|
safe.c serial.c sha1.c sha2.c sockaddr.c stats.c string.c \
|
||||||
strtoul.c symtab.c task.c taskpool.c timer.c \
|
strtoul.c symtab.c task.c taskpool.c timer.c \
|
||||||
tm.c version.c
|
tm.c version.c
|
||||||
|
|
||||||
LIBS = @ISC_OPENSSL_LIBS@ @ISC_ATOMIC_LIBS@ @LIBS@
|
LIBS = @ISC_OPENSSL_LIBS@ @LIBS@
|
||||||
|
|
||||||
# Note: the order of SUBDIRS is important.
|
# Note: the order of SUBDIRS is important.
|
||||||
# Attempt to disable parallel processing.
|
# Attempt to disable parallel processing.
|
||||||
.NOTPARALLEL:
|
.NOTPARALLEL:
|
||||||
.NO_PARALLEL:
|
.NO_PARALLEL:
|
||||||
SUBDIRS = include unix nls @ISC_THREAD_DIR@
|
SUBDIRS = include unix nls @ISC_THREAD_DIR@ @ISC_ARCH_DIR@
|
||||||
TARGETS = timestamp
|
TARGETS = timestamp
|
||||||
TESTDIRS = @UNITTESTS@
|
TESTDIRS = @UNITTESTS@
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SUBDIRS = include
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SUBDIRS = isc
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
VERSION=@BIND9_VERSION@
|
||||||
|
|
||||||
|
HEADERS = atomic.h
|
||||||
|
|
||||||
|
SUBDIRS =
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
|
|
||||||
|
installdirs:
|
||||||
|
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc
|
||||||
|
|
||||||
|
install:: installdirs
|
||||||
|
for i in ${HEADERS}; do \
|
||||||
|
${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall::
|
||||||
|
for i in ${HEADERS}; do \
|
||||||
|
rm -f ${DESTDIR}${includedir}/isc/$$i ; \
|
||||||
|
done
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* See the COPYRIGHT file distributed with this work for additional
|
||||||
|
* information regarding copyright ownership.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This code was written based on FreeBSD's kernel source whose copyright
|
||||||
|
* follows:
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1998 Doug Rabson
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* $FreeBSD: src/sys/alpha/include/atomic.h,v 1.18.6.1 2004/09/13 21:52:04 wilko Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ISC_ATOMIC_H
|
||||||
|
#define ISC_ATOMIC_H 1
|
||||||
|
|
||||||
|
#include <isc/platform.h>
|
||||||
|
#include <isc/types.h>
|
||||||
|
|
||||||
|
#ifdef ISC_PLATFORM_USEOSFASM
|
||||||
|
#include <c_asm.h>
|
||||||
|
|
||||||
|
#pragma intrinsic(asm)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine atomically increments the value stored in 'p' by 'val', and
|
||||||
|
* returns the previous value. Memory access ordering around this function
|
||||||
|
* can be critical, so we add explicit memory block instructions at the
|
||||||
|
* beginning and the end of it (same for other functions).
|
||||||
|
*/
|
||||||
|
static inline isc_int32_t
|
||||||
|
isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
return (asm("mb;"
|
||||||
|
"1:"
|
||||||
|
"ldl_l %t0, 0(%a0);" /* load old value */
|
||||||
|
"mov %t0, %v0;" /* copy the old value */
|
||||||
|
"addl %t0, %a1, %t0;" /* calculate new value */
|
||||||
|
"stl_c %t0, 0(%a0);" /* attempt to store */
|
||||||
|
"beq %t0, 1b;" /* spin if failed */
|
||||||
|
"mb;",
|
||||||
|
p, val));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine atomically stores the value 'val' in 'p'.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
(void)asm("mb;"
|
||||||
|
"1:"
|
||||||
|
"ldl_l %t0, 0(%a0);" /* load old value */
|
||||||
|
"mov %a1, %t0;" /* value to store */
|
||||||
|
"stl_c %t0, 0(%a0);" /* attempt to store */
|
||||||
|
"beq %t0, 1b;" /* spin if failed */
|
||||||
|
"mb;",
|
||||||
|
p, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine atomically replaces the value in 'p' with 'val', if the
|
||||||
|
* original value is equal to 'cmpval'. The original value is returned in any
|
||||||
|
* case.
|
||||||
|
*/
|
||||||
|
static inline isc_int32_t
|
||||||
|
isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
|
||||||
|
|
||||||
|
return(asm("mb;"
|
||||||
|
"1:"
|
||||||
|
"ldl_l %t0, 0(%a0);" /* load old value */
|
||||||
|
"mov %t0, %v0;" /* copy the old value */
|
||||||
|
"cmpeq %t0, %a1, %t0;" /* compare */
|
||||||
|
"beq %t0, 2f;" /* exit if not equal */
|
||||||
|
"mov %a2, %t0;" /* value to store */
|
||||||
|
"stl_c %t0, 0(%a0);" /* attempt to store */
|
||||||
|
"beq %t0, 1b;" /* if it failed, spin */
|
||||||
|
"2:"
|
||||||
|
"mb;",
|
||||||
|
p, cmpval, val));
|
||||||
|
}
|
||||||
|
#elif defined (ISC_PLATFORM_USEGCCASM)
|
||||||
|
static inline isc_int32_t
|
||||||
|
isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
isc_int32_t temp, prev;
|
||||||
|
|
||||||
|
__asm__ volatile(
|
||||||
|
"mb;"
|
||||||
|
"1:"
|
||||||
|
"ldl_l %0, %1;" /* load old value */
|
||||||
|
"mov %0, %2;" /* copy the old value */
|
||||||
|
"addl %0, %3, %0;" /* calculate new value */
|
||||||
|
"stl_c %0, %1;" /* attempt to store */
|
||||||
|
"beq %0, 1b;" /* spin if failed */
|
||||||
|
"mb;"
|
||||||
|
: "=&r"(temp), "+m"(*p), "=&r"(prev)
|
||||||
|
: "r"(val)
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
return (prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
isc_int32_t temp;
|
||||||
|
|
||||||
|
__asm__ volatile(
|
||||||
|
"mb;"
|
||||||
|
"1:"
|
||||||
|
"ldl_l %0, %1;" /* load old value */
|
||||||
|
"mov %2, %0;" /* value to store */
|
||||||
|
"stl_c %0, %1;" /* attempt to store */
|
||||||
|
"beq %0, 1b;" /* if it failed, spin */
|
||||||
|
"mb;"
|
||||||
|
: "=&r"(temp), "+m"(*p)
|
||||||
|
: "r"(val)
|
||||||
|
: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline isc_int32_t
|
||||||
|
isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
|
||||||
|
isc_int32_t temp, prev;
|
||||||
|
|
||||||
|
__asm__ volatile(
|
||||||
|
"mb;"
|
||||||
|
"1:"
|
||||||
|
"ldl_l %0, %1;" /* load old value */
|
||||||
|
"mov %0, %2;" /* copy the old value */
|
||||||
|
"cmpeq %0, %3, %0;" /* compare */
|
||||||
|
"beq %0, 2f;" /* exit if not equal */
|
||||||
|
"mov %4, %0;" /* value to store */
|
||||||
|
"stl_c %0, %1;" /* attempt to store */
|
||||||
|
"beq %0, 1b;" /* if it failed, spin */
|
||||||
|
"2:"
|
||||||
|
"mb;"
|
||||||
|
: "=&r"(temp), "+m"(*p), "=&r"(prev)
|
||||||
|
: "r"(cmpval), "r"(val)
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
return (prev);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
#error "unsupported compiler. disable atomic ops by --disable-atomic"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ISC_ATOMIC_H */
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SUBDIRS = include
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SUBDIRS = isc
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
VERSION=@BIND9_VERSION@
|
||||||
|
|
||||||
|
HEADERS = atomic.h
|
||||||
|
|
||||||
|
SUBDIRS =
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
|
|
||||||
|
installdirs:
|
||||||
|
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc
|
||||||
|
|
||||||
|
install:: installdirs
|
||||||
|
for i in ${HEADERS}; do \
|
||||||
|
${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall::
|
||||||
|
for i in ${HEADERS}; do \
|
||||||
|
rm -f ${DESTDIR}${includedir}/isc/$$i ; \
|
||||||
|
done
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* See the COPYRIGHT file distributed with this work for additional
|
||||||
|
* information regarding copyright ownership.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ISC_ATOMIC_H
|
||||||
|
#define ISC_ATOMIC_H 1
|
||||||
|
|
||||||
|
#include <isc/platform.h>
|
||||||
|
#include <isc/types.h>
|
||||||
|
|
||||||
|
#ifdef ISC_PLATFORM_USEGCCASM
|
||||||
|
/*
|
||||||
|
* This routine atomically increments the value stored in 'p' by 'val', and
|
||||||
|
* returns the previous value.
|
||||||
|
*
|
||||||
|
* Open issue: can 'fetchadd' make the code faster for some particular values
|
||||||
|
* (e.g., 1 and -1)?
|
||||||
|
*/
|
||||||
|
static inline isc_int32_t
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__attribute__ ((unused))
|
||||||
|
#endif
|
||||||
|
isc_atomic_xadd(isc_int32_t *p, isc_int32_t val)
|
||||||
|
{
|
||||||
|
isc_int32_t prev, swapped;
|
||||||
|
|
||||||
|
for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) {
|
||||||
|
swapped = prev + val;
|
||||||
|
__asm__ volatile(
|
||||||
|
"mov ar.ccv=%2;;"
|
||||||
|
"cmpxchg4.acq %0=%4,%3,ar.ccv"
|
||||||
|
: "=r" (swapped), "=m" (*p)
|
||||||
|
: "r" (prev), "r" (swapped), "m" (*p)
|
||||||
|
: "memory");
|
||||||
|
if (swapped == prev)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine atomically stores the value 'val' in 'p'.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__attribute__ ((unused))
|
||||||
|
#endif
|
||||||
|
isc_atomic_store(isc_int32_t *p, isc_int32_t val)
|
||||||
|
{
|
||||||
|
__asm__ volatile(
|
||||||
|
"st4.rel %0=%1"
|
||||||
|
: "=m" (*p)
|
||||||
|
: "r" (val)
|
||||||
|
: "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine atomically replaces the value in 'p' with 'val', if the
|
||||||
|
* original value is equal to 'cmpval'. The original value is returned in any
|
||||||
|
* case.
|
||||||
|
*/
|
||||||
|
static inline isc_int32_t
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__attribute__ ((unused))
|
||||||
|
#endif
|
||||||
|
isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val)
|
||||||
|
{
|
||||||
|
isc_int32_t ret;
|
||||||
|
|
||||||
|
__asm__ volatile(
|
||||||
|
"mov ar.ccv=%2;;"
|
||||||
|
"cmpxchg4.acq %0=%4,%3,ar.ccv"
|
||||||
|
: "=r" (ret), "=m" (*p)
|
||||||
|
: "r" (cmpval), "r" (val), "m" (*p)
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
#else /* !ISC_PLATFORM_USEGCCASM */
|
||||||
|
|
||||||
|
#error "unsupported compiler. disable atomic ops by --disable-atomic"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif /* ISC_ATOMIC_H */
|
||||||
@@ -271,6 +271,57 @@
|
|||||||
*/
|
*/
|
||||||
@ISC_PLATFORM_HAVESYSUNH@
|
@ISC_PLATFORM_HAVESYSUNH@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the "xadd" operation is available on this architecture,
|
||||||
|
* ISC_PLATFORM_HAVEXADD will be defined.
|
||||||
|
*/
|
||||||
|
@ISC_PLATFORM_HAVEXADD@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the "xaddq" operation (64bit xadd) is available on this architecture,
|
||||||
|
* ISC_PLATFORM_HAVEXADDQ will be defined.
|
||||||
|
*/
|
||||||
|
@ISC_PLATFORM_HAVEXADDQ@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the 32-bit "atomic swap" operation is available on this
|
||||||
|
* architecture, ISC_PLATFORM_HAVEATOMICSTORE" will be defined.
|
||||||
|
*/
|
||||||
|
@ISC_PLATFORM_HAVEATOMICSTORE@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the 64-bit "atomic swap" operation is available on this
|
||||||
|
* architecture, ISC_PLATFORM_HAVEATOMICSTORE" will be defined.
|
||||||
|
*/
|
||||||
|
@ISC_PLATFORM_HAVEATOMICSTOREQ@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the "compare-and-exchange" operation is available on this architecture,
|
||||||
|
* ISC_PLATFORM_HAVECMPXCHG will be defined.
|
||||||
|
*/
|
||||||
|
@ISC_PLATFORM_HAVECMPXCHG@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If <stdatomic.h> is available on this architecture,
|
||||||
|
* ISC_PLATFORM_HAVESTDATOMIC will be defined.
|
||||||
|
*/
|
||||||
|
@ISC_PLATFORM_HAVESTDATOMIC@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define if gcc ASM extension is available
|
||||||
|
*/
|
||||||
|
@ISC_PLATFORM_USEGCCASM@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define if Tru64 style ASM syntax must be used.
|
||||||
|
*/
|
||||||
|
@ISC_PLATFORM_USEOSFASM@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define if the standard __asm function must be used.
|
||||||
|
*/
|
||||||
|
@ISC_PLATFORM_USESTDASM@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define with the busy wait nop asm or function call.
|
* Define with the busy wait nop asm or function call.
|
||||||
*/
|
*/
|
||||||
@@ -301,6 +352,12 @@
|
|||||||
*** Windows dll support.
|
*** Windows dll support.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define if MacOS style of PPC assembly must be used.
|
||||||
|
* e.g. "r6", not "6", for register six.
|
||||||
|
*/
|
||||||
|
@ISC_PLATFORM_USEMACASM@
|
||||||
|
|
||||||
#ifndef ISC_PLATFORM_USEDECLSPEC
|
#ifndef ISC_PLATFORM_USEDECLSPEC
|
||||||
#define LIBISC_EXTERNAL_DATA
|
#define LIBISC_EXTERNAL_DATA
|
||||||
#define LIBDNS_EXTERNAL_DATA
|
#define LIBDNS_EXTERNAL_DATA
|
||||||
|
|||||||
+178
-54
@@ -14,15 +14,15 @@
|
|||||||
#define ISC_REFCOUNT_H 1
|
#define ISC_REFCOUNT_H 1
|
||||||
|
|
||||||
#include <isc/assertions.h>
|
#include <isc/assertions.h>
|
||||||
|
#include <isc/atomic.h>
|
||||||
#include <isc/error.h>
|
#include <isc/error.h>
|
||||||
#include <isc/lang.h>
|
#include <isc/lang.h>
|
||||||
#include <isc/mutex.h>
|
#include <isc/mutex.h>
|
||||||
#include <isc/platform.h>
|
#include <isc/platform.h>
|
||||||
#include <isc/types.h>
|
#include <isc/types.h>
|
||||||
|
|
||||||
#ifdef ISC_PLATFORM_USETHREADS
|
#if defined(ISC_PLATFORM_HAVESTDATOMIC)
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
#include <stdint.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*! \file isc/refcount.h
|
/*! \file isc/refcount.h
|
||||||
@@ -93,82 +93,206 @@ ISC_LANG_BEGINDECLS
|
|||||||
* Sample implementations
|
* Sample implementations
|
||||||
*/
|
*/
|
||||||
#ifdef ISC_PLATFORM_USETHREADS
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
#if (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_INT_LOCK_FREE)) || defined(ISC_PLATFORM_HAVEXADD)
|
||||||
|
#define ISC_REFCOUNT_HAVEATOMIC 1
|
||||||
|
#if (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_INT_LOCK_FREE))
|
||||||
|
#define ISC_REFCOUNT_HAVESTDATOMIC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef atomic_int_fast32_t isc_refcount_t;
|
typedef struct isc_refcount {
|
||||||
|
#if defined(ISC_REFCOUNT_HAVESTDATOMIC)
|
||||||
|
atomic_int_fast32_t refs;
|
||||||
|
#else
|
||||||
|
isc_int32_t refs;
|
||||||
|
#endif
|
||||||
|
} isc_refcount_t;
|
||||||
|
|
||||||
static inline
|
#if defined(ISC_REFCOUNT_HAVESTDATOMIC)
|
||||||
isc_result_t
|
|
||||||
isc_refcount_init(isc_refcount_t *ref, int_fast32_t n) {
|
|
||||||
atomic_store_explicit(ref, n, memory_order_release);
|
|
||||||
return (ISC_R_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define isc_refcount_current(ref) \
|
#define isc_refcount_current(rp) \
|
||||||
atomic_load_explicit(ref, memory_order_acquire)
|
((unsigned int)(atomic_load_explicit(&(rp)->refs, \
|
||||||
|
memory_order_relaxed)))
|
||||||
|
#define isc_refcount_destroy(rp) ISC_REQUIRE(isc_refcount_current(rp) == 0)
|
||||||
|
|
||||||
static inline
|
#define isc_refcount_increment0(rp, tp) \
|
||||||
void
|
do { \
|
||||||
isc_refcount_destroy(isc_refcount_t *ref) {
|
unsigned int *_tmp = (unsigned int *)(tp); \
|
||||||
int_fast32_t cur = isc_refcount_current(ref);
|
isc_int32_t prev; \
|
||||||
ISC_REQUIRE(cur == 0);
|
prev = atomic_fetch_add_explicit \
|
||||||
}
|
(&(rp)->refs, 1, memory_order_relaxed); \
|
||||||
|
if (_tmp != NULL) \
|
||||||
|
*_tmp = prev + 1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define isc_refcount_increment0(ref) \
|
#define isc_refcount_increment(rp, tp) \
|
||||||
atomic_fetch_add_explicit(ref, 1, memory_order_relaxed)
|
do { \
|
||||||
|
unsigned int *_tmp = (unsigned int *)(tp); \
|
||||||
|
isc_int32_t prev; \
|
||||||
|
prev = atomic_fetch_add_explicit \
|
||||||
|
(&(rp)->refs, 1, memory_order_relaxed); \
|
||||||
|
ISC_REQUIRE(prev > 0); \
|
||||||
|
if (_tmp != NULL) \
|
||||||
|
*_tmp = prev + 1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
static inline int_fast32_t isc_refcount_increment(isc_refcount_t *ref) {
|
#define isc_refcount_decrement(rp, tp) \
|
||||||
int_fast32_t prev = atomic_fetch_add_explicit(ref, 1,
|
do { \
|
||||||
memory_order_relaxed);
|
unsigned int *_tmp = (unsigned int *)(tp); \
|
||||||
ISC_REQUIRE(prev > 0);
|
isc_int32_t prev; \
|
||||||
return (prev);
|
prev = atomic_fetch_sub_explicit \
|
||||||
}
|
(&(rp)->refs, 1, memory_order_relaxed); \
|
||||||
|
ISC_REQUIRE(prev > 0); \
|
||||||
|
if (_tmp != NULL) \
|
||||||
|
*_tmp = prev - 1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
static inline int_fast32_t isc_refcount_decrement(isc_refcount_t *ref) {
|
#else /* ISC_REFCOUNT_HAVESTDATOMIC */
|
||||||
int_fast32_t prev = atomic_fetch_sub_explicit(ref, 1,
|
|
||||||
memory_order_release);
|
|
||||||
ISC_REQUIRE(prev > 0);
|
|
||||||
return (prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#define isc_refcount_current(rp) \
|
||||||
|
((unsigned int)(isc_atomic_xadd(&(rp)->refs, 0)))
|
||||||
|
#define isc_refcount_destroy(rp) ISC_REQUIRE(isc_refcount_current(rp) == 0)
|
||||||
|
|
||||||
|
#define isc_refcount_increment0(rp, tp) \
|
||||||
|
do { \
|
||||||
|
unsigned int *_tmp = (unsigned int *)(tp); \
|
||||||
|
isc_int32_t prev; \
|
||||||
|
prev = isc_atomic_xadd(&(rp)->refs, 1); \
|
||||||
|
if (_tmp != NULL) \
|
||||||
|
*_tmp = prev + 1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define isc_refcount_increment(rp, tp) \
|
||||||
|
do { \
|
||||||
|
unsigned int *_tmp = (unsigned int *)(tp); \
|
||||||
|
isc_int32_t prev; \
|
||||||
|
prev = isc_atomic_xadd(&(rp)->refs, 1); \
|
||||||
|
ISC_REQUIRE(prev > 0); \
|
||||||
|
if (_tmp != NULL) \
|
||||||
|
*_tmp = prev + 1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define isc_refcount_decrement(rp, tp) \
|
||||||
|
do { \
|
||||||
|
unsigned int *_tmp = (unsigned int *)(tp); \
|
||||||
|
isc_int32_t prev; \
|
||||||
|
prev = isc_atomic_xadd(&(rp)->refs, -1); \
|
||||||
|
ISC_REQUIRE(prev > 0); \
|
||||||
|
if (_tmp != NULL) \
|
||||||
|
*_tmp = prev - 1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#endif /* ISC_REFCOUNT_HAVESTDATOMIC */
|
||||||
|
|
||||||
|
#else /* ISC_PLATFORM_HAVEXADD */
|
||||||
|
|
||||||
|
typedef struct isc_refcount {
|
||||||
|
int refs;
|
||||||
|
isc_mutex_t lock;
|
||||||
|
} isc_refcount_t;
|
||||||
|
|
||||||
|
/*% Destroys a reference counter. */
|
||||||
|
#define isc_refcount_destroy(rp) \
|
||||||
|
do { \
|
||||||
|
isc_result_t _result; \
|
||||||
|
ISC_REQUIRE((rp)->refs == 0); \
|
||||||
|
_result = isc_mutex_destroy(&(rp)->lock); \
|
||||||
|
ISC_ERROR_RUNTIMECHECK(_result == ISC_R_SUCCESS); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Increments the reference count, returning the new value in
|
||||||
|
* 'tp' if it's not NULL.
|
||||||
|
*/
|
||||||
|
#define isc_refcount_increment0(rp, tp) \
|
||||||
|
do { \
|
||||||
|
isc_result_t _result; \
|
||||||
|
unsigned int *_tmp = (unsigned int *)(tp); \
|
||||||
|
_result = isc_mutex_lock(&(rp)->lock); \
|
||||||
|
ISC_ERROR_RUNTIMECHECK(_result == ISC_R_SUCCESS); \
|
||||||
|
++((rp)->refs); \
|
||||||
|
if (_tmp != NULL) \
|
||||||
|
*_tmp = ((rp)->refs); \
|
||||||
|
_result = isc_mutex_unlock(&(rp)->lock); \
|
||||||
|
ISC_ERROR_RUNTIMECHECK(_result == ISC_R_SUCCESS); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define isc_refcount_increment(rp, tp) \
|
||||||
|
do { \
|
||||||
|
isc_result_t _result; \
|
||||||
|
unsigned int *_tmp = (unsigned int *)(tp); \
|
||||||
|
_result = isc_mutex_lock(&(rp)->lock); \
|
||||||
|
ISC_ERROR_RUNTIMECHECK(_result == ISC_R_SUCCESS); \
|
||||||
|
ISC_REQUIRE((rp)->refs > 0); \
|
||||||
|
++((rp)->refs); \
|
||||||
|
if (_tmp != NULL) \
|
||||||
|
*_tmp = ((rp)->refs); \
|
||||||
|
_result = isc_mutex_unlock(&(rp)->lock); \
|
||||||
|
ISC_ERROR_RUNTIMECHECK(_result == ISC_R_SUCCESS); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Decrements the reference count, returning the new value in 'tp'
|
||||||
|
* if it's not NULL.
|
||||||
|
*/
|
||||||
|
#define isc_refcount_decrement(rp, tp) \
|
||||||
|
do { \
|
||||||
|
isc_result_t _result; \
|
||||||
|
unsigned int *_tmp = (unsigned int *)(tp); \
|
||||||
|
_result = isc_mutex_lock(&(rp)->lock); \
|
||||||
|
ISC_ERROR_RUNTIMECHECK(_result == ISC_R_SUCCESS); \
|
||||||
|
ISC_REQUIRE((rp)->refs > 0); \
|
||||||
|
--((rp)->refs); \
|
||||||
|
if (_tmp != NULL) \
|
||||||
|
*_tmp = ((rp)->refs); \
|
||||||
|
_result = isc_mutex_unlock(&(rp)->lock); \
|
||||||
|
ISC_ERROR_RUNTIMECHECK(_result == ISC_R_SUCCESS); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#endif /* (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_INT_LOCK_FREE)) || defined(ISC_PLATFORM_HAVEXADD) */
|
||||||
#else /* ISC_PLATFORM_USETHREADS */
|
#else /* ISC_PLATFORM_USETHREADS */
|
||||||
|
|
||||||
|
typedef struct isc_refcount {
|
||||||
|
int refs;
|
||||||
|
} isc_refcount_t;
|
||||||
|
|
||||||
typedef isc_int32_t isc_refcount_t
|
#define isc_refcount_destroy(rp) ISC_REQUIRE((rp)->refs == 0)
|
||||||
|
#define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
|
||||||
|
|
||||||
static inline
|
#define isc_refcount_increment0(rp, tp) \
|
||||||
isc_result_t
|
|
||||||
isc_refcount_init(isc_refcount_t *ref, isc_refcount_t n) {
|
|
||||||
ISC_REQUIRE(ref);
|
|
||||||
*ref = n;
|
|
||||||
return (ISC_R_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define isc_refcount_destroy(ref) ISC_REQUIRE(ref == 0)
|
|
||||||
#define isc_refcount_current(ref) ((unsigned int)(ref)
|
|
||||||
|
|
||||||
#define isc_refcount_increment0(ref) \
|
|
||||||
do { \
|
do { \
|
||||||
++ref; \
|
unsigned int *_tmp = (unsigned int *)(tp); \
|
||||||
|
int _n = ++(rp)->refs; \
|
||||||
|
if (_tmp != NULL) \
|
||||||
|
*_tmp = _n; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define isc_refcount_increment(ref) \
|
#define isc_refcount_increment(rp, tp) \
|
||||||
do { \
|
|
||||||
ISC_REQUIRE(ref > 0); \
|
|
||||||
++ref; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define isc_refcount_decrement(ref, tp) \
|
|
||||||
do { \
|
do { \
|
||||||
unsigned int *_tmp = (unsigned int *)(tp); \
|
unsigned int *_tmp = (unsigned int *)(tp); \
|
||||||
int _n; \
|
int _n; \
|
||||||
ISC_REQUIRE((ref) > 0); \
|
ISC_REQUIRE((rp)->refs > 0); \
|
||||||
_n = --ref; \
|
_n = ++(rp)->refs; \
|
||||||
|
if (_tmp != NULL) \
|
||||||
|
*_tmp = _n; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define isc_refcount_decrement(rp, tp) \
|
||||||
|
do { \
|
||||||
|
unsigned int *_tmp = (unsigned int *)(tp); \
|
||||||
|
int _n; \
|
||||||
|
ISC_REQUIRE((rp)->refs > 0); \
|
||||||
|
_n = --(rp)->refs; \
|
||||||
if (_tmp != NULL) \
|
if (_tmp != NULL) \
|
||||||
*_tmp = _n; \
|
*_tmp = _n; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#endif /* ISC_PLATFORM_USETHREADS */
|
#endif /* ISC_PLATFORM_USETHREADS */
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_refcount_init(isc_refcount_t *ref, unsigned int n);
|
||||||
|
|
||||||
ISC_LANG_ENDDECLS
|
ISC_LANG_ENDDECLS
|
||||||
|
|
||||||
#endif /* ISC_REFCOUNT_H */
|
#endif /* ISC_REFCOUNT_H */
|
||||||
|
|||||||
@@ -15,14 +15,13 @@
|
|||||||
|
|
||||||
/*! \file isc/rwlock.h */
|
/*! \file isc/rwlock.h */
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <isc/condition.h>
|
#include <isc/condition.h>
|
||||||
#include <isc/lang.h>
|
#include <isc/lang.h>
|
||||||
#include <isc/platform.h>
|
#include <isc/platform.h>
|
||||||
#include <isc/types.h>
|
#include <isc/types.h>
|
||||||
|
|
||||||
#ifdef ISC_PLATFORM_USETHREADS
|
#if defined(ISC_PLATFORM_HAVESTDATOMIC)
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -35,6 +34,12 @@ typedef enum {
|
|||||||
} isc_rwlocktype_t;
|
} isc_rwlocktype_t;
|
||||||
|
|
||||||
#ifdef ISC_PLATFORM_USETHREADS
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
#if (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_INT_LOCK_FREE)) || (defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG))
|
||||||
|
#define ISC_RWLOCK_USEATOMIC 1
|
||||||
|
#if (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_INT_LOCK_FREE))
|
||||||
|
#define ISC_RWLOCK_USESTDATOMIC 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
struct isc_rwlock {
|
struct isc_rwlock {
|
||||||
/* Unlocked. */
|
/* Unlocked. */
|
||||||
@@ -42,6 +47,7 @@ struct isc_rwlock {
|
|||||||
isc_mutex_t lock;
|
isc_mutex_t lock;
|
||||||
isc_int32_t spins;
|
isc_int32_t spins;
|
||||||
|
|
||||||
|
#if defined(ISC_RWLOCK_USEATOMIC)
|
||||||
/*
|
/*
|
||||||
* When some atomic instructions with hardware assistance are
|
* When some atomic instructions with hardware assistance are
|
||||||
* available, rwlock will use those so that concurrent readers do not
|
* available, rwlock will use those so that concurrent readers do not
|
||||||
@@ -56,9 +62,15 @@ struct isc_rwlock {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Read or modified atomically. */
|
/* Read or modified atomically. */
|
||||||
|
#if defined(ISC_RWLOCK_USESTDATOMIC)
|
||||||
atomic_int_fast32_t write_requests;
|
atomic_int_fast32_t write_requests;
|
||||||
atomic_int_fast32_t write_completions;
|
atomic_int_fast32_t write_completions;
|
||||||
atomic_int_fast32_t cnt_and_flag;
|
atomic_int_fast32_t cnt_and_flag;
|
||||||
|
#else
|
||||||
|
isc_int32_t write_requests;
|
||||||
|
isc_int32_t write_completions;
|
||||||
|
isc_int32_t cnt_and_flag;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Locked by lock. */
|
/* Locked by lock. */
|
||||||
isc_condition_t readable;
|
isc_condition_t readable;
|
||||||
@@ -70,6 +82,30 @@ struct isc_rwlock {
|
|||||||
|
|
||||||
/* Unlocked. */
|
/* Unlocked. */
|
||||||
unsigned int write_quota;
|
unsigned int write_quota;
|
||||||
|
|
||||||
|
#else /* ISC_RWLOCK_USEATOMIC */
|
||||||
|
|
||||||
|
/*%< Locked by lock. */
|
||||||
|
isc_condition_t readable;
|
||||||
|
isc_condition_t writeable;
|
||||||
|
isc_rwlocktype_t type;
|
||||||
|
|
||||||
|
/*% The number of threads that have the lock. */
|
||||||
|
unsigned int active;
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* The number of lock grants made since the lock was last switched
|
||||||
|
* from reading to writing or vice versa; used in determining
|
||||||
|
* when the quota is reached and it is time to switch.
|
||||||
|
*/
|
||||||
|
unsigned int granted;
|
||||||
|
|
||||||
|
unsigned int readers_waiting;
|
||||||
|
unsigned int writers_waiting;
|
||||||
|
unsigned int read_quota;
|
||||||
|
unsigned int write_quota;
|
||||||
|
isc_rwlocktype_t original;
|
||||||
|
#endif /* ISC_RWLOCK_USEATOMIC */
|
||||||
};
|
};
|
||||||
#else /* ISC_PLATFORM_USETHREADS */
|
#else /* ISC_PLATFORM_USETHREADS */
|
||||||
struct isc_rwlock {
|
struct isc_rwlock {
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SUBDIRS = include
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SUBDIRS = isc
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
VERSION=@BIND9_VERSION@
|
||||||
|
|
||||||
|
HEADERS = atomic.h
|
||||||
|
|
||||||
|
SUBDIRS =
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
|
|
||||||
|
installdirs:
|
||||||
|
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc
|
||||||
|
|
||||||
|
install:: installdirs
|
||||||
|
for i in ${HEADERS}; do \
|
||||||
|
${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall::
|
||||||
|
for i in ${HEADERS}; do \
|
||||||
|
rm -f ${DESTDIR}${includedir}/isc/$$i ; \
|
||||||
|
done
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* See the COPYRIGHT file distributed with this work for additional
|
||||||
|
* information regarding copyright ownership.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ISC_ATOMIC_H
|
||||||
|
#define ISC_ATOMIC_H 1
|
||||||
|
|
||||||
|
#include <isc/platform.h>
|
||||||
|
#include <isc/types.h>
|
||||||
|
|
||||||
|
#ifdef ISC_PLATFORM_USEGCCASM
|
||||||
|
/*
|
||||||
|
* This routine atomically increments the value stored in 'p' by 'val', and
|
||||||
|
* returns the previous value.
|
||||||
|
*/
|
||||||
|
static inline isc_int32_t
|
||||||
|
isc_atomic_xadd(isc_int32_t *p, int val) {
|
||||||
|
isc_int32_t orig;
|
||||||
|
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
" .set push \n"
|
||||||
|
" .set mips2 \n"
|
||||||
|
" .set noreorder \n"
|
||||||
|
" .set noat \n"
|
||||||
|
"1: ll $1, %1 \n"
|
||||||
|
" addu %0, $1, %2 \n"
|
||||||
|
" sc %0, %1 \n"
|
||||||
|
" beqz %0, 1b \n"
|
||||||
|
" move %0, $1 \n"
|
||||||
|
" .set pop \n"
|
||||||
|
: "=&r" (orig), "+R" (*p)
|
||||||
|
: "r" (val)
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
return (orig);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine atomically stores the value 'val' in 'p'.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
*p = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine atomically replaces the value in 'p' with 'val', if the
|
||||||
|
* original value is equal to 'cmpval'. The original value is returned in any
|
||||||
|
* case.
|
||||||
|
*/
|
||||||
|
static inline isc_int32_t
|
||||||
|
isc_atomic_cmpxchg(isc_int32_t *p, int cmpval, int val) {
|
||||||
|
isc_int32_t orig;
|
||||||
|
isc_int32_t tmp;
|
||||||
|
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
" .set push \n"
|
||||||
|
" .set mips2 \n"
|
||||||
|
" .set noreorder \n"
|
||||||
|
" .set noat \n"
|
||||||
|
"1: ll $1, %1 \n"
|
||||||
|
" bne $1, %3, 2f \n"
|
||||||
|
" move %2, %4 \n"
|
||||||
|
" sc %2, %1 \n"
|
||||||
|
" beqz %2, 1b \n"
|
||||||
|
"2: move %0, $1 \n"
|
||||||
|
" .set pop \n"
|
||||||
|
: "=&r"(orig), "+R" (*p), "=r" (tmp)
|
||||||
|
: "r"(cmpval), "r"(val)
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
return (orig);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* !ISC_PLATFORM_USEGCCASM */
|
||||||
|
|
||||||
|
#error "unsupported compiler. disable atomic ops by --disable-atomic"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif /* ISC_ATOMIC_H */
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SUBDIRS = include
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SUBDIRS = isc
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
VERSION=@BIND9_VERSION@
|
||||||
|
|
||||||
|
HEADERS = atomic.h
|
||||||
|
|
||||||
|
SUBDIRS =
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
|
|
||||||
|
installdirs:
|
||||||
|
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc
|
||||||
|
|
||||||
|
install:: installdirs
|
||||||
|
for i in ${HEADERS}; do \
|
||||||
|
${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall::
|
||||||
|
for i in ${HEADERS}; do \
|
||||||
|
rm -f ${DESTDIR}${includedir}/isc/$$i ; \
|
||||||
|
done
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* See the COPYRIGHT file distributed with this work for additional
|
||||||
|
* information regarding copyright ownership.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ISC_ATOMIC_H
|
||||||
|
#define ISC_ATOMIC_H 1
|
||||||
|
|
||||||
|
/* This file is inherently empty. */
|
||||||
|
|
||||||
|
#endif /* ISC_ATOMIC_H */
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SUBDIRS = include
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SUBDIRS = isc
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
VERSION=@BIND9_VERSION@
|
||||||
|
|
||||||
|
HEADERS = atomic.h
|
||||||
|
|
||||||
|
SUBDIRS =
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
|
|
||||||
|
installdirs:
|
||||||
|
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc
|
||||||
|
|
||||||
|
install:: installdirs
|
||||||
|
for i in ${HEADERS}; do \
|
||||||
|
${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall::
|
||||||
|
for i in ${HEADERS}; do \
|
||||||
|
rm -f ${DESTDIR}${includedir}/isc/$$i ; \
|
||||||
|
done
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* See the COPYRIGHT file distributed with this work for additional
|
||||||
|
* information regarding copyright ownership.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ISC_ATOMIC_H
|
||||||
|
#define ISC_ATOMIC_H 1
|
||||||
|
|
||||||
|
#include <isc/platform.h>
|
||||||
|
#include <isc/types.h>
|
||||||
|
|
||||||
|
/*!\file
|
||||||
|
* static inline isc_int32_t
|
||||||
|
* isc_atomic_xadd(isc_int32_t *p, isc_int32_t val);
|
||||||
|
*
|
||||||
|
* This routine atomically increments the value stored in 'p' by 'val', and
|
||||||
|
* returns the previous value.
|
||||||
|
*
|
||||||
|
* static inline void
|
||||||
|
* isc_atomic_store(void *p, isc_int32_t val);
|
||||||
|
*
|
||||||
|
* This routine atomically stores the value 'val' in 'p'.
|
||||||
|
*
|
||||||
|
* static inline isc_int32_t
|
||||||
|
* isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val);
|
||||||
|
*
|
||||||
|
* This routine atomically replaces the value in 'p' with 'val', if the
|
||||||
|
* original value is equal to 'cmpval'. The original value is returned in any
|
||||||
|
* case.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(_AIX)
|
||||||
|
|
||||||
|
#include <sys/atomic_op.h>
|
||||||
|
|
||||||
|
#define isc_atomic_store(p, v) _clear_lock(p, v)
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
static inline isc_int32_t
|
||||||
|
#else
|
||||||
|
static isc_int32_t
|
||||||
|
#endif
|
||||||
|
isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
asm("ics");
|
||||||
|
#else
|
||||||
|
__isync();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = fetch_and_add((atomic_p)p, (int)val);
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
asm("ics");
|
||||||
|
#else
|
||||||
|
__isync();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
static inline int
|
||||||
|
#else
|
||||||
|
static int
|
||||||
|
#endif
|
||||||
|
isc_atomic_cmpxchg(atomic_p p, int old, int replacement) {
|
||||||
|
int orig = old;
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
asm("ics");
|
||||||
|
#else
|
||||||
|
__isync();
|
||||||
|
#endif
|
||||||
|
if (compare_and_swap(p, &orig, replacement))
|
||||||
|
orig = old;
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
asm("ics");
|
||||||
|
#else
|
||||||
|
__isync();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (orig);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(ISC_PLATFORM_USEGCCASM) || defined(ISC_PLATFORM_USEMACASM)
|
||||||
|
static inline isc_int32_t
|
||||||
|
isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
isc_int32_t orig;
|
||||||
|
|
||||||
|
__asm__ volatile (
|
||||||
|
#ifdef ISC_PLATFORM_USEMACASM
|
||||||
|
"1:"
|
||||||
|
"lwarx r6, 0, %1\n"
|
||||||
|
"mr %0, r6\n"
|
||||||
|
"add r6, r6, %2\n"
|
||||||
|
"stwcx. r6, 0, %1\n"
|
||||||
|
"bne- 1b\n"
|
||||||
|
"sync"
|
||||||
|
#else
|
||||||
|
"1:"
|
||||||
|
"lwarx 6, 0, %1\n"
|
||||||
|
"mr %0, 6\n"
|
||||||
|
"add 6, 6, %2\n"
|
||||||
|
"stwcx. 6, 0, %1\n"
|
||||||
|
"bne- 1b\n"
|
||||||
|
"sync"
|
||||||
|
#endif
|
||||||
|
: "=&r"(orig)
|
||||||
|
: "r"(p), "r"(val)
|
||||||
|
: "r6", "memory"
|
||||||
|
);
|
||||||
|
|
||||||
|
return (orig);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
isc_atomic_store(void *p, isc_int32_t val) {
|
||||||
|
__asm__ volatile (
|
||||||
|
#ifdef ISC_PLATFORM_USEMACASM
|
||||||
|
"1:"
|
||||||
|
"lwarx r6, 0, %0\n"
|
||||||
|
"lwz r6, %1\n"
|
||||||
|
"stwcx. r6, 0, %0\n"
|
||||||
|
"bne- 1b\n"
|
||||||
|
"sync"
|
||||||
|
#else
|
||||||
|
"1:"
|
||||||
|
"lwarx 6, 0, %0\n"
|
||||||
|
"lwz 6, %1\n"
|
||||||
|
"stwcx. 6, 0, %0\n"
|
||||||
|
"bne- 1b\n"
|
||||||
|
"sync"
|
||||||
|
#endif
|
||||||
|
:
|
||||||
|
: "r"(p), "m"(val)
|
||||||
|
: "r6", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline isc_int32_t
|
||||||
|
isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
|
||||||
|
isc_int32_t orig;
|
||||||
|
|
||||||
|
__asm__ volatile (
|
||||||
|
#ifdef ISC_PLATFORM_USEMACASM
|
||||||
|
"1:"
|
||||||
|
"lwarx r6, 0, %1\n"
|
||||||
|
"mr %0,r6\n"
|
||||||
|
"cmpw r6, %2\n"
|
||||||
|
"bne 2f\n"
|
||||||
|
"mr r6, %3\n"
|
||||||
|
"stwcx. r6, 0, %1\n"
|
||||||
|
"bne- 1b\n"
|
||||||
|
"2:\n"
|
||||||
|
"sync"
|
||||||
|
#else
|
||||||
|
"1:"
|
||||||
|
"lwarx 6, 0, %1\n"
|
||||||
|
"mr %0,6\n"
|
||||||
|
"cmpw 6, %2\n"
|
||||||
|
"bne 2f\n"
|
||||||
|
"mr 6, %3\n"
|
||||||
|
"stwcx. 6, 0, %1\n"
|
||||||
|
"bne- 1b\n"
|
||||||
|
"2:\n"
|
||||||
|
"sync"
|
||||||
|
#endif
|
||||||
|
: "=&r" (orig)
|
||||||
|
: "r"(p), "r"(cmpval), "r"(val)
|
||||||
|
: "r6", "memory"
|
||||||
|
);
|
||||||
|
|
||||||
|
return (orig);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#error "unsupported compiler. disable atomic ops by --disable-atomic"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif /* ISC_ATOMIC_H */
|
||||||
+4
-4
@@ -76,14 +76,14 @@ _new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family, void *dest,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
_deref_prefix(isc_prefix_t *prefix) {
|
_deref_prefix(isc_prefix_t *prefix) {
|
||||||
int_fast32_t refs;
|
int refs;
|
||||||
|
|
||||||
if (prefix == NULL)
|
if (prefix == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
refs = isc_refcount_decrement(&prefix->refcount);
|
isc_refcount_decrement(&prefix->refcount, &refs);
|
||||||
|
|
||||||
if (refs == 1) {
|
if (refs <= 0) {
|
||||||
isc_refcount_destroy(&prefix->refcount);
|
isc_refcount_destroy(&prefix->refcount);
|
||||||
isc_mem_putanddetach(&prefix->mctx, prefix,
|
isc_mem_putanddetach(&prefix->mctx, prefix,
|
||||||
sizeof(isc_prefix_t));
|
sizeof(isc_prefix_t));
|
||||||
@@ -110,7 +110,7 @@ _ref_prefix(isc_mem_t *mctx, isc_prefix_t **target, isc_prefix_t *prefix) {
|
|||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_refcount_increment(&prefix->refcount);
|
isc_refcount_increment(&prefix->refcount, NULL);
|
||||||
|
|
||||||
*target = prefix;
|
*target = prefix;
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
|||||||
+6
-1
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -96,6 +97,7 @@ getrandom_buf(void *buf, size_t buflen) {
|
|||||||
while (left > 0) {
|
while (left > 0) {
|
||||||
ret = getrandom(p, left, 0);
|
ret = getrandom(p, left, 0);
|
||||||
if (ret == -1 && errno == EINTR) {
|
if (ret == -1 && errno == EINTR) {
|
||||||
|
fprintf(stderr, "getrandom_buf: getrandom() call interrupted.\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,6 +107,9 @@ getrandom_buf(void *buf, size_t buflen) {
|
|||||||
left -= ret;
|
left -= ret;
|
||||||
p += ret;
|
p += ret;
|
||||||
}
|
}
|
||||||
|
if (left > 0) {
|
||||||
|
fprintf(stderr, "getrandom_buf: getrandom() returned less then requested bytes (%zd < %zu).\n", ret, left+ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
@@ -175,7 +180,7 @@ isc_random_buf(void *buf, size_t buflen) {
|
|||||||
}
|
}
|
||||||
# elif HAVE_PKCS11
|
# elif HAVE_PKCS11
|
||||||
RUNTIME_CHECK(pk11_rand_bytes(buf, buflen) == ISC_R_SUCCESS);
|
RUNTIME_CHECK(pk11_rand_bytes(buf, buflen) == ISC_R_SUCCESS);
|
||||||
# endif /* if defined(HAVE_ARC4RANDOM_BUF) */
|
# endif /* if defined(HAVE_ARC4RANDOM_BUF) */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* See the COPYRIGHT file distributed with this work for additional
|
||||||
|
* information regarding copyright ownership.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <isc/mutex.h>
|
||||||
|
#include <isc/refcount.h>
|
||||||
|
#include <isc/result.h>
|
||||||
|
#include <isc/util.h>
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_refcount_init(isc_refcount_t *ref, unsigned int n) {
|
||||||
|
REQUIRE(ref != NULL);
|
||||||
|
|
||||||
|
ref->refs = n;
|
||||||
|
#if defined(ISC_PLATFORM_USETHREADS) && !defined(ISC_REFCOUNT_HAVEATOMIC)
|
||||||
|
return (isc_mutex_init(&ref->lock));
|
||||||
|
#else
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <isc/atomic.h>
|
||||||
#include <isc/magic.h>
|
#include <isc/magic.h>
|
||||||
#include <isc/msgs.h>
|
#include <isc/msgs.h>
|
||||||
#include <isc/platform.h>
|
#include <isc/platform.h>
|
||||||
@@ -40,8 +41,10 @@
|
|||||||
#define RWLOCK_MAX_ADAPTIVE_COUNT 100
|
#define RWLOCK_MAX_ADAPTIVE_COUNT 100
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(ISC_RWLOCK_USEATOMIC)
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
|
isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ISC_RWLOCK_TRACE
|
#ifdef ISC_RWLOCK_TRACE
|
||||||
#include <stdio.h> /* Required for fprintf/stderr. */
|
#include <stdio.h> /* Required for fprintf/stderr. */
|
||||||
@@ -49,6 +52,7 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
print_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
print_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||||
|
#if defined(ISC_RWLOCK_USEATOMIC)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
|
isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
|
||||||
ISC_MSG_PRINTLOCK2,
|
ISC_MSG_PRINTLOCK2,
|
||||||
@@ -65,6 +69,26 @@ print_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
rwl->write_requests, rwl->write_completions,
|
rwl->write_requests, rwl->write_completions,
|
||||||
rwl->cnt_and_flag, rwl->readers_waiting,
|
rwl->cnt_and_flag, rwl->readers_waiting,
|
||||||
rwl->write_granted, rwl->write_quota);
|
rwl->write_granted, rwl->write_quota);
|
||||||
|
#else
|
||||||
|
fprintf(stderr,
|
||||||
|
isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
|
||||||
|
ISC_MSG_PRINTLOCK,
|
||||||
|
"rwlock %p thread %lu %s(%s): %s, %u active, "
|
||||||
|
"%u granted, %u rwaiting, %u wwaiting\n"),
|
||||||
|
rwl, isc_thread_self(), operation,
|
||||||
|
(type == isc_rwlocktype_read ?
|
||||||
|
isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
|
||||||
|
ISC_MSG_READ, "read") :
|
||||||
|
isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
|
||||||
|
ISC_MSG_WRITE, "write")),
|
||||||
|
(rwl->type == isc_rwlocktype_read ?
|
||||||
|
isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
|
||||||
|
ISC_MSG_READING, "reading") :
|
||||||
|
isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
|
||||||
|
ISC_MSG_WRITING, "writing")),
|
||||||
|
rwl->active, rwl->granted,
|
||||||
|
rwl->readers_waiting, rwl->writers_waiting);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* ISC_RWLOCK_TRACE */
|
#endif /* ISC_RWLOCK_TRACE */
|
||||||
|
|
||||||
@@ -83,6 +107,7 @@ isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
|||||||
rwl->magic = 0;
|
rwl->magic = 0;
|
||||||
|
|
||||||
rwl->spins = 0;
|
rwl->spins = 0;
|
||||||
|
#if defined(ISC_RWLOCK_USEATOMIC)
|
||||||
rwl->write_requests = 0;
|
rwl->write_requests = 0;
|
||||||
rwl->write_completions = 0;
|
rwl->write_completions = 0;
|
||||||
rwl->cnt_and_flag = 0;
|
rwl->cnt_and_flag = 0;
|
||||||
@@ -95,6 +120,20 @@ isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
|||||||
if (write_quota == 0)
|
if (write_quota == 0)
|
||||||
write_quota = RWLOCK_DEFAULT_WRITE_QUOTA;
|
write_quota = RWLOCK_DEFAULT_WRITE_QUOTA;
|
||||||
rwl->write_quota = write_quota;
|
rwl->write_quota = write_quota;
|
||||||
|
#else
|
||||||
|
rwl->type = isc_rwlocktype_read;
|
||||||
|
rwl->original = isc_rwlocktype_none;
|
||||||
|
rwl->active = 0;
|
||||||
|
rwl->granted = 0;
|
||||||
|
rwl->readers_waiting = 0;
|
||||||
|
rwl->writers_waiting = 0;
|
||||||
|
if (read_quota == 0)
|
||||||
|
read_quota = RWLOCK_DEFAULT_READ_QUOTA;
|
||||||
|
rwl->read_quota = read_quota;
|
||||||
|
if (write_quota == 0)
|
||||||
|
write_quota = RWLOCK_DEFAULT_WRITE_QUOTA;
|
||||||
|
rwl->write_quota = write_quota;
|
||||||
|
#endif
|
||||||
|
|
||||||
result = isc_mutex_init(&rwl->lock);
|
result = isc_mutex_init(&rwl->lock);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
@@ -137,8 +176,16 @@ void
|
|||||||
isc_rwlock_destroy(isc_rwlock_t *rwl) {
|
isc_rwlock_destroy(isc_rwlock_t *rwl) {
|
||||||
REQUIRE(VALID_RWLOCK(rwl));
|
REQUIRE(VALID_RWLOCK(rwl));
|
||||||
|
|
||||||
|
#if defined(ISC_RWLOCK_USEATOMIC)
|
||||||
REQUIRE(rwl->write_requests == rwl->write_completions &&
|
REQUIRE(rwl->write_requests == rwl->write_completions &&
|
||||||
rwl->cnt_and_flag == 0 && rwl->readers_waiting == 0);
|
rwl->cnt_and_flag == 0 && rwl->readers_waiting == 0);
|
||||||
|
#else
|
||||||
|
LOCK(&rwl->lock);
|
||||||
|
REQUIRE(rwl->active == 0 &&
|
||||||
|
rwl->readers_waiting == 0 &&
|
||||||
|
rwl->writers_waiting == 0);
|
||||||
|
UNLOCK(&rwl->lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
rwl->magic = 0;
|
rwl->magic = 0;
|
||||||
(void)isc_condition_destroy(&rwl->readable);
|
(void)isc_condition_destroy(&rwl->readable);
|
||||||
@@ -146,6 +193,8 @@ isc_rwlock_destroy(isc_rwlock_t *rwl) {
|
|||||||
DESTROYLOCK(&rwl->lock);
|
DESTROYLOCK(&rwl->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(ISC_RWLOCK_USEATOMIC)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When some architecture-dependent atomic operations are available,
|
* When some architecture-dependent atomic operations are available,
|
||||||
* rwlock can be more efficient than the generic algorithm defined below.
|
* rwlock can be more efficient than the generic algorithm defined below.
|
||||||
@@ -234,9 +283,13 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
UNLOCK(&rwl->lock);
|
UNLOCK(&rwl->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(ISC_RWLOCK_USESTDATOMIC)
|
||||||
cntflag = atomic_fetch_add_explicit(&rwl->cnt_and_flag,
|
cntflag = atomic_fetch_add_explicit(&rwl->cnt_and_flag,
|
||||||
READER_INCR,
|
READER_INCR,
|
||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
cntflag = isc_atomic_xadd(&rwl->cnt_and_flag, READER_INCR);
|
||||||
|
#endif
|
||||||
POST(cntflag);
|
POST(cntflag);
|
||||||
while (1) {
|
while (1) {
|
||||||
if ((rwl->cnt_and_flag & WRITER_ACTIVE) == 0)
|
if ((rwl->cnt_and_flag & WRITER_ACTIVE) == 0)
|
||||||
@@ -286,8 +339,12 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
isc_int32_t prev_writer;
|
isc_int32_t prev_writer;
|
||||||
|
|
||||||
/* enter the waiting queue, and wait for our turn */
|
/* enter the waiting queue, and wait for our turn */
|
||||||
|
#if defined(ISC_RWLOCK_USESTDATOMIC)
|
||||||
prev_writer = atomic_fetch_add_explicit(&rwl->write_requests, 1,
|
prev_writer = atomic_fetch_add_explicit(&rwl->write_requests, 1,
|
||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
prev_writer = isc_atomic_xadd(&rwl->write_requests, 1);
|
||||||
|
#endif
|
||||||
while (rwl->write_completions != prev_writer) {
|
while (rwl->write_completions != prev_writer) {
|
||||||
LOCK(&rwl->lock);
|
LOCK(&rwl->lock);
|
||||||
if (rwl->write_completions != prev_writer) {
|
if (rwl->write_completions != prev_writer) {
|
||||||
@@ -300,10 +357,16 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
#if defined(ISC_RWLOCK_USESTDATOMIC)
|
||||||
int_fast32_t cntflag2 = 0;
|
int_fast32_t cntflag2 = 0;
|
||||||
atomic_compare_exchange_strong_explicit
|
atomic_compare_exchange_strong_explicit
|
||||||
(&rwl->cnt_and_flag, &cntflag2, WRITER_ACTIVE,
|
(&rwl->cnt_and_flag, &cntflag2, WRITER_ACTIVE,
|
||||||
memory_order_relaxed, memory_order_relaxed);
|
memory_order_relaxed, memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
isc_int32_t cntflag2;
|
||||||
|
cntflag2 = isc_atomic_cmpxchg(&rwl->cnt_and_flag, 0,
|
||||||
|
WRITER_ACTIVE);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (cntflag2 == 0)
|
if (cntflag2 == 0)
|
||||||
break;
|
break;
|
||||||
@@ -368,17 +431,26 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
return (ISC_R_LOCKBUSY);
|
return (ISC_R_LOCKBUSY);
|
||||||
|
|
||||||
/* Otherwise, be ready for reading. */
|
/* Otherwise, be ready for reading. */
|
||||||
|
#if defined(ISC_RWLOCK_USESTDATOMIC)
|
||||||
cntflag = atomic_fetch_add_explicit(&rwl->cnt_and_flag,
|
cntflag = atomic_fetch_add_explicit(&rwl->cnt_and_flag,
|
||||||
READER_INCR,
|
READER_INCR,
|
||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
cntflag = isc_atomic_xadd(&rwl->cnt_and_flag, READER_INCR);
|
||||||
|
#endif
|
||||||
if ((cntflag & WRITER_ACTIVE) != 0) {
|
if ((cntflag & WRITER_ACTIVE) != 0) {
|
||||||
/*
|
/*
|
||||||
* A writer is working. We lose, and cancel the read
|
* A writer is working. We lose, and cancel the read
|
||||||
* request.
|
* request.
|
||||||
*/
|
*/
|
||||||
|
#if defined(ISC_RWLOCK_USESTDATOMIC)
|
||||||
cntflag = atomic_fetch_sub_explicit
|
cntflag = atomic_fetch_sub_explicit
|
||||||
(&rwl->cnt_and_flag, READER_INCR,
|
(&rwl->cnt_and_flag, READER_INCR,
|
||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
cntflag = isc_atomic_xadd(&rwl->cnt_and_flag,
|
||||||
|
-READER_INCR);
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* If no other readers are waiting and we've suspended
|
* If no other readers are waiting and we've suspended
|
||||||
* new writers in this short period, wake them up.
|
* new writers in this short period, wake them up.
|
||||||
@@ -394,18 +466,29 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Try locking without entering the waiting queue. */
|
/* Try locking without entering the waiting queue. */
|
||||||
|
#if defined(ISC_RWLOCK_USESTDATOMIC)
|
||||||
int_fast32_t zero = 0;
|
int_fast32_t zero = 0;
|
||||||
if (!atomic_compare_exchange_strong_explicit
|
if (!atomic_compare_exchange_strong_explicit
|
||||||
(&rwl->cnt_and_flag, &zero, WRITER_ACTIVE,
|
(&rwl->cnt_and_flag, &zero, WRITER_ACTIVE,
|
||||||
memory_order_relaxed, memory_order_relaxed))
|
memory_order_relaxed, memory_order_relaxed))
|
||||||
return (ISC_R_LOCKBUSY);
|
return (ISC_R_LOCKBUSY);
|
||||||
|
#else
|
||||||
|
cntflag = isc_atomic_cmpxchg(&rwl->cnt_and_flag, 0,
|
||||||
|
WRITER_ACTIVE);
|
||||||
|
if (cntflag != 0)
|
||||||
|
return (ISC_R_LOCKBUSY);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXXJT: jump into the queue, possibly breaking the writer
|
* XXXJT: jump into the queue, possibly breaking the writer
|
||||||
* order.
|
* order.
|
||||||
*/
|
*/
|
||||||
|
#if defined(ISC_RWLOCK_USESTDATOMIC)
|
||||||
atomic_fetch_sub_explicit(&rwl->write_completions, 1,
|
atomic_fetch_sub_explicit(&rwl->write_completions, 1,
|
||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
(void)isc_atomic_xadd(&rwl->write_completions, -1);
|
||||||
|
#endif
|
||||||
|
|
||||||
rwl->write_granted++;
|
rwl->write_granted++;
|
||||||
}
|
}
|
||||||
@@ -422,6 +505,7 @@ isc_result_t
|
|||||||
isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
|
isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
|
||||||
REQUIRE(VALID_RWLOCK(rwl));
|
REQUIRE(VALID_RWLOCK(rwl));
|
||||||
|
|
||||||
|
#if defined(ISC_RWLOCK_USESTDATOMIC)
|
||||||
{
|
{
|
||||||
int_fast32_t reader_incr = READER_INCR;
|
int_fast32_t reader_incr = READER_INCR;
|
||||||
|
|
||||||
@@ -447,6 +531,30 @@ isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
|
|||||||
return (ISC_R_LOCKBUSY);
|
return (ISC_R_LOCKBUSY);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
isc_int32_t prevcnt;
|
||||||
|
|
||||||
|
/* Try to acquire write access. */
|
||||||
|
prevcnt = isc_atomic_cmpxchg(&rwl->cnt_and_flag,
|
||||||
|
READER_INCR, WRITER_ACTIVE);
|
||||||
|
/*
|
||||||
|
* There must have been no writer, and there must have
|
||||||
|
* been at least one reader.
|
||||||
|
*/
|
||||||
|
INSIST((prevcnt & WRITER_ACTIVE) == 0 &&
|
||||||
|
(prevcnt & ~WRITER_ACTIVE) != 0);
|
||||||
|
|
||||||
|
if (prevcnt == READER_INCR) {
|
||||||
|
/*
|
||||||
|
* We are the only reader and have been upgraded.
|
||||||
|
* Now jump into the head of the writer waiting queue.
|
||||||
|
*/
|
||||||
|
(void)isc_atomic_xadd(&rwl->write_completions, -1);
|
||||||
|
} else
|
||||||
|
return (ISC_R_LOCKBUSY);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
@@ -457,6 +565,7 @@ isc_rwlock_downgrade(isc_rwlock_t *rwl) {
|
|||||||
|
|
||||||
REQUIRE(VALID_RWLOCK(rwl));
|
REQUIRE(VALID_RWLOCK(rwl));
|
||||||
|
|
||||||
|
#if defined(ISC_RWLOCK_USESTDATOMIC)
|
||||||
{
|
{
|
||||||
/* Become an active reader. */
|
/* Become an active reader. */
|
||||||
prev_readers = atomic_fetch_add_explicit(&rwl->cnt_and_flag,
|
prev_readers = atomic_fetch_add_explicit(&rwl->cnt_and_flag,
|
||||||
@@ -471,6 +580,18 @@ isc_rwlock_downgrade(isc_rwlock_t *rwl) {
|
|||||||
atomic_fetch_add_explicit(&rwl->write_completions, 1,
|
atomic_fetch_add_explicit(&rwl->write_completions, 1,
|
||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
/* Become an active reader. */
|
||||||
|
prev_readers = isc_atomic_xadd(&rwl->cnt_and_flag, READER_INCR);
|
||||||
|
/* We must have been a writer. */
|
||||||
|
INSIST((prev_readers & WRITER_ACTIVE) != 0);
|
||||||
|
|
||||||
|
/* Complete write */
|
||||||
|
(void)isc_atomic_xadd(&rwl->cnt_and_flag, -WRITER_ACTIVE);
|
||||||
|
(void)isc_atomic_xadd(&rwl->write_completions, 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Resume other readers */
|
/* Resume other readers */
|
||||||
LOCK(&rwl->lock);
|
LOCK(&rwl->lock);
|
||||||
@@ -491,9 +612,13 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (type == isc_rwlocktype_read) {
|
if (type == isc_rwlocktype_read) {
|
||||||
|
#if defined(ISC_RWLOCK_USESTDATOMIC)
|
||||||
prev_cnt = atomic_fetch_sub_explicit(&rwl->cnt_and_flag,
|
prev_cnt = atomic_fetch_sub_explicit(&rwl->cnt_and_flag,
|
||||||
READER_INCR,
|
READER_INCR,
|
||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
prev_cnt = isc_atomic_xadd(&rwl->cnt_and_flag, -READER_INCR);
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* If we're the last reader and any writers are waiting, wake
|
* If we're the last reader and any writers are waiting, wake
|
||||||
* them up. We need to wake up all of them to ensure the
|
* them up. We need to wake up all of them to ensure the
|
||||||
@@ -512,10 +637,15 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
* Reset the flag, and (implicitly) tell other writers
|
* Reset the flag, and (implicitly) tell other writers
|
||||||
* we are done.
|
* we are done.
|
||||||
*/
|
*/
|
||||||
|
#if defined(ISC_RWLOCK_USESTDATOMIC)
|
||||||
atomic_fetch_sub_explicit(&rwl->cnt_and_flag, WRITER_ACTIVE,
|
atomic_fetch_sub_explicit(&rwl->cnt_and_flag, WRITER_ACTIVE,
|
||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
atomic_fetch_add_explicit(&rwl->write_completions, 1,
|
atomic_fetch_add_explicit(&rwl->write_completions, 1,
|
||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
(void)isc_atomic_xadd(&rwl->cnt_and_flag, -WRITER_ACTIVE);
|
||||||
|
(void)isc_atomic_xadd(&rwl->write_completions, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (rwl->write_granted >= rwl->write_quota ||
|
if (rwl->write_granted >= rwl->write_quota ||
|
||||||
rwl->write_requests == rwl->write_completions ||
|
rwl->write_requests == rwl->write_completions ||
|
||||||
@@ -553,6 +683,213 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else /* ISC_RWLOCK_USEATOMIC */
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
doit(isc_rwlock_t *rwl, isc_rwlocktype_t type, isc_boolean_t nonblock) {
|
||||||
|
isc_boolean_t skip = ISC_FALSE;
|
||||||
|
isc_boolean_t done = ISC_FALSE;
|
||||||
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
|
REQUIRE(VALID_RWLOCK(rwl));
|
||||||
|
|
||||||
|
LOCK(&rwl->lock);
|
||||||
|
|
||||||
|
#ifdef ISC_RWLOCK_TRACE
|
||||||
|
print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
|
||||||
|
ISC_MSG_PRELOCK, "prelock"), rwl, type);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (type == isc_rwlocktype_read) {
|
||||||
|
if (rwl->readers_waiting != 0)
|
||||||
|
skip = ISC_TRUE;
|
||||||
|
while (!done) {
|
||||||
|
if (!skip &&
|
||||||
|
((rwl->active == 0 ||
|
||||||
|
(rwl->type == isc_rwlocktype_read &&
|
||||||
|
(rwl->writers_waiting == 0 ||
|
||||||
|
rwl->granted < rwl->read_quota)))))
|
||||||
|
{
|
||||||
|
rwl->type = isc_rwlocktype_read;
|
||||||
|
rwl->active++;
|
||||||
|
rwl->granted++;
|
||||||
|
done = ISC_TRUE;
|
||||||
|
} else if (nonblock) {
|
||||||
|
result = ISC_R_LOCKBUSY;
|
||||||
|
done = ISC_TRUE;
|
||||||
|
} else {
|
||||||
|
skip = ISC_FALSE;
|
||||||
|
rwl->readers_waiting++;
|
||||||
|
WAIT(&rwl->readable, &rwl->lock);
|
||||||
|
rwl->readers_waiting--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (rwl->writers_waiting != 0)
|
||||||
|
skip = ISC_TRUE;
|
||||||
|
while (!done) {
|
||||||
|
if (!skip && rwl->active == 0) {
|
||||||
|
rwl->type = isc_rwlocktype_write;
|
||||||
|
rwl->active = 1;
|
||||||
|
rwl->granted++;
|
||||||
|
done = ISC_TRUE;
|
||||||
|
} else if (nonblock) {
|
||||||
|
result = ISC_R_LOCKBUSY;
|
||||||
|
done = ISC_TRUE;
|
||||||
|
} else {
|
||||||
|
skip = ISC_FALSE;
|
||||||
|
rwl->writers_waiting++;
|
||||||
|
WAIT(&rwl->writeable, &rwl->lock);
|
||||||
|
rwl->writers_waiting--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ISC_RWLOCK_TRACE
|
||||||
|
print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
|
||||||
|
ISC_MSG_POSTLOCK, "postlock"), rwl, type);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UNLOCK(&rwl->lock);
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||||
|
isc_int32_t cnt = 0;
|
||||||
|
isc_int32_t max_cnt = rwl->spins * 2 + 10;
|
||||||
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
|
if (max_cnt > RWLOCK_MAX_ADAPTIVE_COUNT)
|
||||||
|
max_cnt = RWLOCK_MAX_ADAPTIVE_COUNT;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (cnt++ >= max_cnt) {
|
||||||
|
result = doit(rwl, type, ISC_FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef ISC_PLATFORM_BUSYWAITNOP
|
||||||
|
ISC_PLATFORM_BUSYWAITNOP;
|
||||||
|
#endif
|
||||||
|
} while (doit(rwl, type, ISC_TRUE) != ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
rwl->spins += (cnt - rwl->spins) / 8;
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||||
|
return (doit(rwl, type, ISC_TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
|
||||||
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
|
REQUIRE(VALID_RWLOCK(rwl));
|
||||||
|
LOCK(&rwl->lock);
|
||||||
|
REQUIRE(rwl->type == isc_rwlocktype_read);
|
||||||
|
REQUIRE(rwl->active != 0);
|
||||||
|
|
||||||
|
/* If we are the only reader then succeed. */
|
||||||
|
if (rwl->active == 1) {
|
||||||
|
rwl->original = (rwl->original == isc_rwlocktype_none) ?
|
||||||
|
isc_rwlocktype_read : isc_rwlocktype_none;
|
||||||
|
rwl->type = isc_rwlocktype_write;
|
||||||
|
} else
|
||||||
|
result = ISC_R_LOCKBUSY;
|
||||||
|
|
||||||
|
UNLOCK(&rwl->lock);
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
isc_rwlock_downgrade(isc_rwlock_t *rwl) {
|
||||||
|
|
||||||
|
REQUIRE(VALID_RWLOCK(rwl));
|
||||||
|
LOCK(&rwl->lock);
|
||||||
|
REQUIRE(rwl->type == isc_rwlocktype_write);
|
||||||
|
REQUIRE(rwl->active == 1);
|
||||||
|
|
||||||
|
rwl->type = isc_rwlocktype_read;
|
||||||
|
rwl->original = (rwl->original == isc_rwlocktype_none) ?
|
||||||
|
isc_rwlocktype_write : isc_rwlocktype_none;
|
||||||
|
/*
|
||||||
|
* Resume processing any read request that were blocked when
|
||||||
|
* we upgraded.
|
||||||
|
*/
|
||||||
|
if (rwl->original == isc_rwlocktype_none &&
|
||||||
|
(rwl->writers_waiting == 0 || rwl->granted < rwl->read_quota) &&
|
||||||
|
rwl->readers_waiting > 0)
|
||||||
|
BROADCAST(&rwl->readable);
|
||||||
|
|
||||||
|
UNLOCK(&rwl->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||||
|
|
||||||
|
REQUIRE(VALID_RWLOCK(rwl));
|
||||||
|
LOCK(&rwl->lock);
|
||||||
|
REQUIRE(rwl->type == type);
|
||||||
|
|
||||||
|
UNUSED(type);
|
||||||
|
|
||||||
|
#ifdef ISC_RWLOCK_TRACE
|
||||||
|
print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
|
||||||
|
ISC_MSG_PREUNLOCK, "preunlock"), rwl, type);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
INSIST(rwl->active > 0);
|
||||||
|
rwl->active--;
|
||||||
|
if (rwl->active == 0) {
|
||||||
|
if (rwl->original != isc_rwlocktype_none) {
|
||||||
|
rwl->type = rwl->original;
|
||||||
|
rwl->original = isc_rwlocktype_none;
|
||||||
|
}
|
||||||
|
if (rwl->type == isc_rwlocktype_read) {
|
||||||
|
rwl->granted = 0;
|
||||||
|
if (rwl->writers_waiting > 0) {
|
||||||
|
rwl->type = isc_rwlocktype_write;
|
||||||
|
SIGNAL(&rwl->writeable);
|
||||||
|
} else if (rwl->readers_waiting > 0) {
|
||||||
|
/* Does this case ever happen? */
|
||||||
|
BROADCAST(&rwl->readable);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (rwl->readers_waiting > 0) {
|
||||||
|
if (rwl->writers_waiting > 0 &&
|
||||||
|
rwl->granted < rwl->write_quota) {
|
||||||
|
SIGNAL(&rwl->writeable);
|
||||||
|
} else {
|
||||||
|
rwl->granted = 0;
|
||||||
|
rwl->type = isc_rwlocktype_read;
|
||||||
|
BROADCAST(&rwl->readable);
|
||||||
|
}
|
||||||
|
} else if (rwl->writers_waiting > 0) {
|
||||||
|
rwl->granted = 0;
|
||||||
|
SIGNAL(&rwl->writeable);
|
||||||
|
} else {
|
||||||
|
rwl->granted = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
INSIST(rwl->original == isc_rwlocktype_none);
|
||||||
|
|
||||||
|
#ifdef ISC_RWLOCK_TRACE
|
||||||
|
print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
|
||||||
|
ISC_MSG_POSTUNLOCK, "postunlock"),
|
||||||
|
rwl, type);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UNLOCK(&rwl->lock);
|
||||||
|
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ISC_RWLOCK_USEATOMIC */
|
||||||
#else /* ISC_PLATFORM_USETHREADS */
|
#else /* ISC_PLATFORM_USETHREADS */
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SUBDIRS = include
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SUBDIRS = isc
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
VERSION=@BIND9_VERSION@
|
||||||
|
|
||||||
|
HEADERS = atomic.h
|
||||||
|
|
||||||
|
SUBDIRS =
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
|
|
||||||
|
installdirs:
|
||||||
|
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc
|
||||||
|
|
||||||
|
install:: installdirs
|
||||||
|
for i in ${HEADERS}; do \
|
||||||
|
${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \
|
||||||
|
done
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* See the COPYRIGHT file distributed with this work for additional
|
||||||
|
* information regarding copyright ownership.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This code was written based on FreeBSD's kernel source whose copyright
|
||||||
|
* follows:
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1998 Doug Rabson.
|
||||||
|
* Copyright (c) 2001 Jake Burkholder.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* from: FreeBSD: src/sys/i386/include/atomic.h,v 1.20 2001/02/11
|
||||||
|
* $FreeBSD: src/sys/sparc64/include/atomic.h,v 1.8 2004/05/22 00:52:16 marius Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ISC_ATOMIC_H
|
||||||
|
#define ISC_ATOMIC_H 1
|
||||||
|
|
||||||
|
#include <isc/platform.h>
|
||||||
|
#include <isc/types.h>
|
||||||
|
|
||||||
|
#define ASI_P 0x80 /* Primary Address Space Identifier */
|
||||||
|
|
||||||
|
#ifdef ISC_PLATFORM_USEGCCASM
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine atomically increments the value stored in 'p' by 'val', and
|
||||||
|
* returns the previous value.
|
||||||
|
*/
|
||||||
|
static inline isc_int32_t
|
||||||
|
isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
isc_int32_t prev, swapped;
|
||||||
|
|
||||||
|
for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) {
|
||||||
|
swapped = prev + val;
|
||||||
|
__asm__ volatile(
|
||||||
|
"casa [%2] %3, %4, %0"
|
||||||
|
: "+r"(swapped), "=m"(*p)
|
||||||
|
: "r"(p), "n"(ASI_P), "r"(prev), "m"(*p));
|
||||||
|
if (swapped == prev)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine atomically stores the value 'val' in 'p'.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
isc_int32_t prev, swapped;
|
||||||
|
|
||||||
|
for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) {
|
||||||
|
swapped = val;
|
||||||
|
__asm__ volatile(
|
||||||
|
"casa [%2] %3, %4, %0"
|
||||||
|
: "+r"(swapped), "=m"(*p)
|
||||||
|
: "r"(p), "n"(ASI_P), "r"(prev), "m"(*p));
|
||||||
|
if (swapped == prev)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine atomically replaces the value in 'p' with 'val', if the
|
||||||
|
* original value is equal to 'cmpval'. The original value is returned in any
|
||||||
|
* case.
|
||||||
|
*/
|
||||||
|
static inline isc_int32_t
|
||||||
|
isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
|
||||||
|
isc_int32_t temp = val;
|
||||||
|
|
||||||
|
__asm__ volatile(
|
||||||
|
"casa [%2] %3, %4, %0"
|
||||||
|
: "+r"(temp), "=m"(*p)
|
||||||
|
: "r"(p), "n"(ASI_P), "r"(cmpval), "m"(*p));
|
||||||
|
|
||||||
|
return (temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ISC_PLATFORM_USEGCCASM */
|
||||||
|
|
||||||
|
#error "unsupported compiler. disable atomic ops by --disable-atomic"
|
||||||
|
|
||||||
|
#endif /* ISC_PLATFORM_USEGCCASM */
|
||||||
|
|
||||||
|
#endif /* ISC_ATOMIC_H */
|
||||||
+307
-83
@@ -16,17 +16,17 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <isc/atomic.h>
|
||||||
#include <isc/buffer.h>
|
#include <isc/buffer.h>
|
||||||
#include <isc/magic.h>
|
#include <isc/magic.h>
|
||||||
#include <isc/mem.h>
|
#include <isc/mem.h>
|
||||||
#include <isc/platform.h>
|
#include <isc/platform.h>
|
||||||
#include <isc/print.h>
|
#include <isc/print.h>
|
||||||
#include <isc/refcount.h>
|
|
||||||
#include <isc/rwlock.h>
|
#include <isc/rwlock.h>
|
||||||
#include <isc/stats.h>
|
#include <isc/stats.h>
|
||||||
#include <isc/util.h>
|
#include <isc/util.h>
|
||||||
|
|
||||||
#ifdef ISC_PLATFORM_USETHREADS
|
#if defined(ISC_PLATFORM_HAVESTDATOMIC)
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -34,16 +34,68 @@
|
|||||||
#define ISC_STATS_VALID(x) ISC_MAGIC_VALID(x, ISC_STATS_MAGIC)
|
#define ISC_STATS_VALID(x) ISC_MAGIC_VALID(x, ISC_STATS_MAGIC)
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* `ISC_STATS_LOCKCOUNTERS` indicates if the complete set of statistics
|
* Local macro confirming prescence of 64-bit
|
||||||
* counters have to be locked before update, so that an instantaneous
|
* increment and store operations, just to make
|
||||||
* snapshot of them can be dumped.
|
* the later macros simpler
|
||||||
*/
|
*/
|
||||||
#define ISC_STATS_LOCKCOUNTERS 0
|
#if (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_LONG_LOCK_FREE)) || \
|
||||||
|
(defined(ISC_PLATFORM_HAVEXADDQ) && defined(ISC_PLATFORM_HAVEATOMICSTOREQ))
|
||||||
|
#define ISC_STATS_HAVEATOMICQ 1
|
||||||
|
#if (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_LONG_LOCK_FREE))
|
||||||
|
#define ISC_STATS_HAVESTDATOMICQ 1
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define ISC_STATS_HAVEATOMICQ 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ISC_PLATFORM_USETHREADS
|
/*%
|
||||||
|
* Only lock the counters if 64-bit atomic operations are
|
||||||
|
* not available but cheap atomic lock operations are.
|
||||||
|
* On a modern 64-bit system this should never be the case.
|
||||||
|
*
|
||||||
|
* Normal locks are too expensive to be used whenever a counter
|
||||||
|
* is updated.
|
||||||
|
*/
|
||||||
|
#if !ISC_STATS_HAVEATOMICQ && defined(ISC_RWLOCK_HAVEATOMIC)
|
||||||
|
#define ISC_STATS_LOCKCOUNTERS 1
|
||||||
|
#else
|
||||||
|
#define ISC_STATS_LOCKCOUNTERS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* If 64-bit atomic operations are not available but
|
||||||
|
* 32-bit operations are then split the counter into two,
|
||||||
|
* using the atomic operations to try to ensure that any carry
|
||||||
|
* from the low word is correctly carried into the high word.
|
||||||
|
*
|
||||||
|
* Otherwise, just rely on standard 64-bit data types
|
||||||
|
* and operations
|
||||||
|
*/
|
||||||
|
#if !ISC_STATS_HAVEATOMICQ && ((defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_INT_LOCK_FREE)) || defined(ISC_PLATFORM_HAVEXADD))
|
||||||
|
#define ISC_STATS_USEMULTIFIELDS 1
|
||||||
|
#if (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_INT_LOCK_FREE))
|
||||||
|
#define ISC_STATS_HAVESTDATOMIC 1
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define ISC_STATS_USEMULTIFIELDS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ISC_STATS_USEMULTIFIELDS
|
||||||
|
typedef struct {
|
||||||
|
#if defined(ISC_STATS_HAVESTDATOMIC)
|
||||||
|
atomic_int_fast32_t hi;
|
||||||
|
atomic_int_fast32_t lo;
|
||||||
|
#else
|
||||||
|
isc_uint32_t hi;
|
||||||
|
isc_uint32_t lo;
|
||||||
|
#endif
|
||||||
|
} isc_stat_t;
|
||||||
|
#else
|
||||||
|
#if defined(ISC_STATS_HAVESTDATOMICQ)
|
||||||
typedef atomic_int_fast64_t isc_stat_t;
|
typedef atomic_int_fast64_t isc_stat_t;
|
||||||
#else
|
#else
|
||||||
typedef isc_int64_t isc_stat_t;
|
typedef isc_uint64_t isc_stat_t;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct isc_stats {
|
struct isc_stats {
|
||||||
@@ -52,8 +104,16 @@ struct isc_stats {
|
|||||||
isc_mem_t *mctx;
|
isc_mem_t *mctx;
|
||||||
int ncounters;
|
int ncounters;
|
||||||
|
|
||||||
isc_refcount_t references;
|
isc_mutex_t lock;
|
||||||
|
unsigned int references; /* locked by lock */
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Locked by counterlock or unlocked if efficient rwlock is not
|
||||||
|
* available.
|
||||||
|
*/
|
||||||
|
#if ISC_STATS_LOCKCOUNTERS
|
||||||
|
isc_rwlock_t counterlock;
|
||||||
|
#endif
|
||||||
isc_stat_t *counters;
|
isc_stat_t *counters;
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
@@ -70,47 +130,8 @@ struct isc_stats {
|
|||||||
isc_uint64_t *copiedcounters;
|
isc_uint64_t *copiedcounters;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
static isc_result_t
|
||||||
isc_stats_attach(isc_stats_t *stats, isc_stats_t **statsp) {
|
create_stats(isc_mem_t *mctx, int ncounters, isc_stats_t **statsp) {
|
||||||
REQUIRE(ISC_STATS_VALID(stats));
|
|
||||||
REQUIRE(statsp != NULL && *statsp == NULL);
|
|
||||||
|
|
||||||
isc_refcount_increment(&stats->references);
|
|
||||||
|
|
||||||
*statsp = stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
isc_stats_detach(isc_stats_t **statsp) {
|
|
||||||
isc_stats_t *stats;
|
|
||||||
int_fast32_t refcount;
|
|
||||||
|
|
||||||
REQUIRE(statsp != NULL && ISC_STATS_VALID(*statsp));
|
|
||||||
|
|
||||||
stats = *statsp;
|
|
||||||
*statsp = NULL;
|
|
||||||
|
|
||||||
refcount = isc_refcount_decrement(&stats->references);
|
|
||||||
|
|
||||||
if (refcount == 1) {
|
|
||||||
isc_mem_put(stats->mctx, stats->copiedcounters,
|
|
||||||
sizeof(isc_stat_t) * stats->ncounters);
|
|
||||||
isc_mem_put(stats->mctx, stats->counters,
|
|
||||||
sizeof(isc_stat_t) * stats->ncounters);
|
|
||||||
isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
isc_stats_ncounters(isc_stats_t *stats) {
|
|
||||||
REQUIRE(ISC_STATS_VALID(stats));
|
|
||||||
|
|
||||||
return (stats->ncounters);
|
|
||||||
}
|
|
||||||
|
|
||||||
isc_result_t
|
|
||||||
isc_stats_create(isc_mem_t *mctx, isc_stats_t **statsp, int ncounters) {
|
|
||||||
isc_stats_t *stats;
|
isc_stats_t *stats;
|
||||||
isc_result_t result = ISC_R_SUCCESS;
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
@@ -120,12 +141,15 @@ isc_stats_create(isc_mem_t *mctx, isc_stats_t **statsp, int ncounters) {
|
|||||||
if (stats == NULL)
|
if (stats == NULL)
|
||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
|
|
||||||
|
result = isc_mutex_init(&stats->lock);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto clean_stats;
|
||||||
|
|
||||||
stats->counters = isc_mem_get(mctx, sizeof(isc_stat_t) * ncounters);
|
stats->counters = isc_mem_get(mctx, sizeof(isc_stat_t) * ncounters);
|
||||||
if (stats->counters == NULL) {
|
if (stats->counters == NULL) {
|
||||||
result = ISC_R_NOMEMORY;
|
result = ISC_R_NOMEMORY;
|
||||||
goto clean_stats;
|
goto clean_mutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
stats->copiedcounters = isc_mem_get(mctx,
|
stats->copiedcounters = isc_mem_get(mctx,
|
||||||
sizeof(isc_uint64_t) * ncounters);
|
sizeof(isc_uint64_t) * ncounters);
|
||||||
if (stats->copiedcounters == NULL) {
|
if (stats->copiedcounters == NULL) {
|
||||||
@@ -133,7 +157,13 @@ isc_stats_create(isc_mem_t *mctx, isc_stats_t **statsp, int ncounters) {
|
|||||||
goto clean_counters;
|
goto clean_counters;
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_refcount_init(&stats->references, 1);
|
#if ISC_STATS_LOCKCOUNTERS
|
||||||
|
result = isc_rwlock_init(&stats->counterlock, 0, 0);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto clean_copiedcounters;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
stats->references = 1;
|
||||||
memset(stats->counters, 0, sizeof(isc_stat_t) * ncounters);
|
memset(stats->counters, 0, sizeof(isc_stat_t) * ncounters);
|
||||||
stats->mctx = NULL;
|
stats->mctx = NULL;
|
||||||
isc_mem_attach(mctx, &stats->mctx);
|
isc_mem_attach(mctx, &stats->mctx);
|
||||||
@@ -147,22 +177,215 @@ isc_stats_create(isc_mem_t *mctx, isc_stats_t **statsp, int ncounters) {
|
|||||||
clean_counters:
|
clean_counters:
|
||||||
isc_mem_put(mctx, stats->counters, sizeof(isc_stat_t) * ncounters);
|
isc_mem_put(mctx, stats->counters, sizeof(isc_stat_t) * ncounters);
|
||||||
|
|
||||||
|
#if ISC_STATS_LOCKCOUNTERS
|
||||||
|
clean_copiedcounters:
|
||||||
|
isc_mem_put(mctx, stats->copiedcounters,
|
||||||
|
sizeof(isc_stat_t) * ncounters);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
clean_mutex:
|
||||||
|
DESTROYLOCK(&stats->lock);
|
||||||
|
|
||||||
clean_stats:
|
clean_stats:
|
||||||
isc_mem_put(mctx, stats, sizeof(*stats));
|
isc_mem_put(mctx, stats, sizeof(*stats));
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
isc_stats_attach(isc_stats_t *stats, isc_stats_t **statsp) {
|
||||||
|
REQUIRE(ISC_STATS_VALID(stats));
|
||||||
|
REQUIRE(statsp != NULL && *statsp == NULL);
|
||||||
|
|
||||||
|
LOCK(&stats->lock);
|
||||||
|
stats->references++;
|
||||||
|
UNLOCK(&stats->lock);
|
||||||
|
|
||||||
|
*statsp = stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
isc_stats_detach(isc_stats_t **statsp) {
|
||||||
|
isc_stats_t *stats;
|
||||||
|
|
||||||
|
REQUIRE(statsp != NULL && ISC_STATS_VALID(*statsp));
|
||||||
|
|
||||||
|
stats = *statsp;
|
||||||
|
*statsp = NULL;
|
||||||
|
|
||||||
|
LOCK(&stats->lock);
|
||||||
|
stats->references--;
|
||||||
|
|
||||||
|
if (stats->references == 0) {
|
||||||
|
isc_mem_put(stats->mctx, stats->copiedcounters,
|
||||||
|
sizeof(isc_stat_t) * stats->ncounters);
|
||||||
|
isc_mem_put(stats->mctx, stats->counters,
|
||||||
|
sizeof(isc_stat_t) * stats->ncounters);
|
||||||
|
UNLOCK(&stats->lock);
|
||||||
|
DESTROYLOCK(&stats->lock);
|
||||||
|
#if ISC_STATS_LOCKCOUNTERS
|
||||||
|
isc_rwlock_destroy(&stats->counterlock);
|
||||||
|
#endif
|
||||||
|
isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNLOCK(&stats->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
isc_stats_ncounters(isc_stats_t *stats) {
|
||||||
|
REQUIRE(ISC_STATS_VALID(stats));
|
||||||
|
|
||||||
|
return (stats->ncounters);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
incrementcounter(isc_stats_t *stats, int counter) {
|
||||||
|
isc_int32_t prev;
|
||||||
|
|
||||||
|
#if ISC_STATS_LOCKCOUNTERS
|
||||||
|
/*
|
||||||
|
* We use a "read" lock to prevent other threads from reading the
|
||||||
|
* counter while we "writing" a counter field. The write access itself
|
||||||
|
* is protected by the atomic operation.
|
||||||
|
*/
|
||||||
|
isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_read);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ISC_STATS_USEMULTIFIELDS
|
||||||
|
#if defined(ISC_STATS_HAVESTDATOMIC)
|
||||||
|
prev = atomic_fetch_add_explicit(&stats->counters[counter].lo, 1,
|
||||||
|
memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
prev = isc_atomic_xadd((isc_int32_t *)&stats->counters[counter].lo, 1);
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* If the lower 32-bit field overflows, increment the higher field.
|
||||||
|
* Note that it's *theoretically* possible that the lower field
|
||||||
|
* overlaps again before the higher field is incremented. It doesn't
|
||||||
|
* matter, however, because we don't read the value until
|
||||||
|
* isc_stats_copy() is called where the whole process is protected
|
||||||
|
* by the write (exclusive) lock.
|
||||||
|
*/
|
||||||
|
if (prev == (isc_int32_t)0xffffffff) {
|
||||||
|
#if defined(ISC_STATS_HAVESTDATOMIC)
|
||||||
|
atomic_fetch_add_explicit(&stats->counters[counter].hi, 1,
|
||||||
|
memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
isc_atomic_xadd((isc_int32_t *)&stats->counters[counter].hi, 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#elif ISC_STATS_HAVEATOMICQ
|
||||||
|
UNUSED(prev);
|
||||||
|
#if defined(ISC_STATS_HAVESTDATOMICQ)
|
||||||
|
atomic_fetch_add_explicit(&stats->counters[counter], 1,
|
||||||
|
memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
isc_atomic_xaddq((isc_int64_t *)&stats->counters[counter], 1);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
UNUSED(prev);
|
||||||
|
stats->counters[counter]++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ISC_STATS_LOCKCOUNTERS
|
||||||
|
isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_read);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
decrementcounter(isc_stats_t *stats, int counter) {
|
||||||
|
isc_int32_t prev;
|
||||||
|
|
||||||
|
#if ISC_STATS_LOCKCOUNTERS
|
||||||
|
isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_read);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ISC_STATS_USEMULTIFIELDS
|
||||||
|
#if defined(ISC_STATS_HAVESTDATOMIC)
|
||||||
|
prev = atomic_fetch_sub_explicit(&stats->counters[counter].lo, 1,
|
||||||
|
memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
prev = isc_atomic_xadd((isc_int32_t *)&stats->counters[counter].lo, -1);
|
||||||
|
#endif
|
||||||
|
if (prev == 0) {
|
||||||
|
#if defined(ISC_STATS_HAVESTDATOMIC)
|
||||||
|
atomic_fetch_sub_explicit(&stats->counters[counter].hi, 1,
|
||||||
|
memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
isc_atomic_xadd((isc_int32_t *)&stats->counters[counter].hi,
|
||||||
|
-1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#elif ISC_STATS_HAVEATOMICQ
|
||||||
|
UNUSED(prev);
|
||||||
|
#if defined(ISC_STATS_HAVESTDATOMICQ)
|
||||||
|
atomic_fetch_sub_explicit(&stats->counters[counter], 1,
|
||||||
|
memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
isc_atomic_xaddq((isc_int64_t *)&stats->counters[counter], -1);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
UNUSED(prev);
|
||||||
|
stats->counters[counter]--;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ISC_STATS_LOCKCOUNTERS
|
||||||
|
isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_read);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
copy_counters(isc_stats_t *stats) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
#if ISC_STATS_LOCKCOUNTERS
|
||||||
|
/*
|
||||||
|
* We use a "write" lock before "reading" the statistics counters as
|
||||||
|
* an exclusive lock.
|
||||||
|
*/
|
||||||
|
isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_write);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (i = 0; i < stats->ncounters; i++) {
|
||||||
|
#if ISC_STATS_USEMULTIFIELDS
|
||||||
|
stats->copiedcounters[i] =
|
||||||
|
(isc_uint64_t)(stats->counters[i].hi) << 32 |
|
||||||
|
stats->counters[i].lo;
|
||||||
|
#elif ISC_STATS_HAVEATOMICQ
|
||||||
|
#if defined(ISC_STATS_HAVESTDATOMICQ)
|
||||||
|
stats->copiedcounters[i] =
|
||||||
|
atomic_load_explicit(&stats->counters[i],
|
||||||
|
memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
/* use xaddq(..., 0) as an atomic load */
|
||||||
|
stats->copiedcounters[i] =
|
||||||
|
(isc_uint64_t)isc_atomic_xaddq((isc_int64_t *)&stats->counters[i], 0);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
stats->copiedcounters[i] = stats->counters[i];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ISC_STATS_LOCKCOUNTERS
|
||||||
|
isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_write);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_stats_create(isc_mem_t *mctx, isc_stats_t **statsp, int ncounters) {
|
||||||
|
REQUIRE(statsp != NULL && *statsp == NULL);
|
||||||
|
|
||||||
|
return (create_stats(mctx, ncounters, statsp));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
isc_stats_increment(isc_stats_t *stats, isc_statscounter_t counter) {
|
isc_stats_increment(isc_stats_t *stats, isc_statscounter_t counter) {
|
||||||
REQUIRE(ISC_STATS_VALID(stats));
|
REQUIRE(ISC_STATS_VALID(stats));
|
||||||
REQUIRE(counter < stats->ncounters);
|
REQUIRE(counter < stats->ncounters);
|
||||||
#ifdef ISC_PLATFORM_USETHREADS
|
|
||||||
atomic_fetch_add_explicit(&stats->counters[counter], 1,
|
incrementcounter(stats, (int)counter);
|
||||||
memory_order_release);
|
|
||||||
#else /* ISC_PLATFORM_USETHREADS */
|
|
||||||
stats->counters[counter]++;
|
|
||||||
#endif /* ISC_PLATFORM_USETHREADS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -170,12 +393,7 @@ isc_stats_decrement(isc_stats_t *stats, isc_statscounter_t counter) {
|
|||||||
REQUIRE(ISC_STATS_VALID(stats));
|
REQUIRE(ISC_STATS_VALID(stats));
|
||||||
REQUIRE(counter < stats->ncounters);
|
REQUIRE(counter < stats->ncounters);
|
||||||
|
|
||||||
#ifdef ISC_PLATFORM_USETHREADS
|
decrementcounter(stats, (int)counter);
|
||||||
atomic_fetch_sub_explicit(&stats->counters[counter], 1,
|
|
||||||
memory_order_release);
|
|
||||||
#else /* ISC_PLATFORM_USETHREADS */
|
|
||||||
stats->counters[counter]--;
|
|
||||||
#endif /* ISC_PLATFORM_USETHREADS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -186,12 +404,7 @@ isc_stats_dump(isc_stats_t *stats, isc_stats_dumper_t dump_fn,
|
|||||||
|
|
||||||
REQUIRE(ISC_STATS_VALID(stats));
|
REQUIRE(ISC_STATS_VALID(stats));
|
||||||
|
|
||||||
#ifdef ISC_PLATFORM_USETHREADS
|
copy_counters(stats);
|
||||||
for (i = 0; i < stats->ncounters; i++) {
|
|
||||||
stats->copiedcounters[i] =
|
|
||||||
atomic_load_explicit(&stats->counters[i],
|
|
||||||
memory_order_acquire);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < stats->ncounters; i++) {
|
for (i = 0; i < stats->ncounters; i++) {
|
||||||
if ((options & ISC_STATSDUMP_VERBOSE) == 0 &&
|
if ((options & ISC_STATSDUMP_VERBOSE) == 0 &&
|
||||||
@@ -199,14 +412,6 @@ isc_stats_dump(isc_stats_t *stats, isc_stats_dumper_t dump_fn,
|
|||||||
continue;
|
continue;
|
||||||
dump_fn((isc_statscounter_t)i, stats->copiedcounters[i], arg);
|
dump_fn((isc_statscounter_t)i, stats->copiedcounters[i], arg);
|
||||||
}
|
}
|
||||||
#else /* ISC_PLATFORM_USETHREADS */
|
|
||||||
for (i = 0; i < stats->ncounters; i++) {
|
|
||||||
if ((options & ISC_STATSDUMP_VERBOSE) == 0 &&
|
|
||||||
stats->counters[i] == 0)
|
|
||||||
continue;
|
|
||||||
dump_fn((isc_statscounter_t)i, stats->counters[i], arg);
|
|
||||||
}
|
|
||||||
#endif /* ISC_PLATFORM_USETHREADS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -216,10 +421,29 @@ isc_stats_set(isc_stats_t *stats, isc_uint64_t val,
|
|||||||
REQUIRE(ISC_STATS_VALID(stats));
|
REQUIRE(ISC_STATS_VALID(stats));
|
||||||
REQUIRE(counter < stats->ncounters);
|
REQUIRE(counter < stats->ncounters);
|
||||||
|
|
||||||
#ifdef ISC_PLATFORM_USETHREADS
|
#if ISC_STATS_LOCKCOUNTERS
|
||||||
|
/*
|
||||||
|
* We use a "write" lock before "reading" the statistics counters as
|
||||||
|
* an exclusive lock.
|
||||||
|
*/
|
||||||
|
isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_write);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ISC_STATS_USEMULTIFIELDS
|
||||||
|
stats->counters[counter].hi = (isc_uint32_t)((val >> 32) & 0xffffffff);
|
||||||
|
stats->counters[counter].lo = (isc_uint32_t)(val & 0xffffffff);
|
||||||
|
#elif ISC_STATS_HAVEATOMICQ
|
||||||
|
#if defined(ISC_STATS_HAVESTDATOMICQ)
|
||||||
atomic_store_explicit(&stats->counters[counter], val,
|
atomic_store_explicit(&stats->counters[counter], val,
|
||||||
memory_order_release);
|
memory_order_relaxed);
|
||||||
#else /* ISC_PLATFORM_USETHREADS */
|
#else
|
||||||
|
isc_atomic_storeq((isc_int64_t *)&stats->counters[counter], val);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
stats->counters[counter] = val;
|
stats->counters[counter] = val;
|
||||||
#endif /* ISC_PLATFORM_USETHREADS */
|
#endif
|
||||||
|
|
||||||
|
#if ISC_STATS_LOCKCOUNTERS
|
||||||
|
isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_write);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ syntax(2)
|
|||||||
test_suite('bind9')
|
test_suite('bind9')
|
||||||
|
|
||||||
atf_test_program{name='aes_test'}
|
atf_test_program{name='aes_test'}
|
||||||
|
atf_test_program{name='atomic_test'}
|
||||||
atf_test_program{name='buffer_test'}
|
atf_test_program{name='buffer_test'}
|
||||||
atf_test_program{name='counter_test'}
|
atf_test_program{name='counter_test'}
|
||||||
atf_test_program{name='errno_test'}
|
atf_test_program{name='errno_test'}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ ISCDEPLIBS = ../libisc.@A@
|
|||||||
LIBS = @LIBS@ @ATFLIBS@
|
LIBS = @LIBS@ @ATFLIBS@
|
||||||
|
|
||||||
OBJS = isctest.@O@
|
OBJS = isctest.@O@
|
||||||
SRCS = isctest.c aes_test.c buffer_test.c \
|
SRCS = isctest.c aes_test.c atomic_test.c buffer_test.c \
|
||||||
counter_test.c errno_test.c file_test.c hash_test.c \
|
counter_test.c errno_test.c file_test.c hash_test.c \
|
||||||
heap_test.c ht_test.c inet_ntop_test.c lex_test.c \
|
heap_test.c ht_test.c inet_ntop_test.c lex_test.c \
|
||||||
mem_test.c netaddr_test.c parse_test.c pool_test.c \
|
mem_test.c netaddr_test.c parse_test.c pool_test.c \
|
||||||
@@ -38,7 +38,7 @@ SRCS = isctest.c aes_test.c buffer_test.c \
|
|||||||
taskpool_test.c time_test.c timer_test.c
|
taskpool_test.c time_test.c timer_test.c
|
||||||
|
|
||||||
SUBDIRS =
|
SUBDIRS =
|
||||||
TARGETS = aes_test@EXEEXT@ buffer_test@EXEEXT@ \
|
TARGETS = aes_test@EXEEXT@ atomic_test@EXEEXT@ buffer_test@EXEEXT@ \
|
||||||
counter_test@EXEEXT@ errno_test@EXEEXT@ file_test@EXEEXT@ \
|
counter_test@EXEEXT@ errno_test@EXEEXT@ file_test@EXEEXT@ \
|
||||||
hash_test@EXEEXT@ heap_test@EXEEXT@ ht_test@EXEEXT@ \
|
hash_test@EXEEXT@ heap_test@EXEEXT@ ht_test@EXEEXT@ \
|
||||||
inet_ntop_test@EXEEXT@ lex_test@EXEEXT@ mem_test@EXEEXT@ \
|
inet_ntop_test@EXEEXT@ lex_test@EXEEXT@ mem_test@EXEEXT@ \
|
||||||
@@ -51,6 +51,10 @@ TARGETS = aes_test@EXEEXT@ buffer_test@EXEEXT@ \
|
|||||||
|
|
||||||
@BIND9_MAKE_RULES@
|
@BIND9_MAKE_RULES@
|
||||||
|
|
||||||
|
atomic_test@EXEEXT@: atomic_test.@O@ isctest.@O@ ${ISCDEPLIBS}
|
||||||
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
|
||||||
|
atomic_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
|
||||||
|
|
||||||
aes_test@EXEEXT@: aes_test.@O@ ${ISCDEPLIBS}
|
aes_test@EXEEXT@: aes_test.@O@ ${ISCDEPLIBS}
|
||||||
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
|
||||||
aes_test.@O@ ${ISCLIBS} ${LIBS}
|
aes_test.@O@ ${ISCLIBS} ${LIBS}
|
||||||
|
|||||||
@@ -0,0 +1,352 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* See the COPYRIGHT file distributed with this work for additional
|
||||||
|
* information regarding copyright ownership.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <atf-c.h>
|
||||||
|
|
||||||
|
#include <isc/atomic.h>
|
||||||
|
#include <isc/print.h>
|
||||||
|
#include <isc/result.h>
|
||||||
|
|
||||||
|
#include "isctest.h"
|
||||||
|
|
||||||
|
#define TASKS 32
|
||||||
|
#define ITERATIONS 1000
|
||||||
|
#define COUNTS_PER_ITERATION 1000
|
||||||
|
#define INCREMENT_64 (isc_int64_t)0x0000000010000000
|
||||||
|
#define EXPECTED_COUNT_32 (TASKS * ITERATIONS * COUNTS_PER_ITERATION)
|
||||||
|
#define EXPECTED_COUNT_64 (TASKS * ITERATIONS * COUNTS_PER_ITERATION * INCREMENT_64)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
isc_uint32_t iteration;
|
||||||
|
} counter_t;
|
||||||
|
|
||||||
|
counter_t counters[TASKS];
|
||||||
|
|
||||||
|
#if defined(ISC_PLATFORM_HAVEXADD)
|
||||||
|
static isc_int32_t counter_32;
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_xadd(isc_task_t *task, isc_event_t *ev) {
|
||||||
|
counter_t *state = (counter_t *)ev->ev_arg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0 ; i < COUNTS_PER_ITERATION ; i++) {
|
||||||
|
isc_atomic_xadd(&counter_32, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
state->iteration++;
|
||||||
|
if (state->iteration < ITERATIONS) {
|
||||||
|
isc_task_send(task, &ev);
|
||||||
|
} else {
|
||||||
|
isc_event_free(&ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC(atomic_xadd);
|
||||||
|
ATF_TC_HEAD(atomic_xadd, tc) {
|
||||||
|
atf_tc_set_md_var(tc, "descr", "atomic XADD");
|
||||||
|
}
|
||||||
|
ATF_TC_BODY(atomic_xadd, tc) {
|
||||||
|
isc_result_t result;
|
||||||
|
isc_task_t *tasks[TASKS];
|
||||||
|
isc_event_t *event = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
UNUSED(tc);
|
||||||
|
|
||||||
|
result = isc_test_begin(NULL, ISC_TRUE, 0);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
memset(counters, 0, sizeof(counters));
|
||||||
|
counter_32 = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create our tasks, and allocate an event to get the counters going.
|
||||||
|
*/
|
||||||
|
for (i = 0 ; i < TASKS ; i++) {
|
||||||
|
tasks[i] = NULL;
|
||||||
|
ATF_REQUIRE_EQ(isc_task_create(taskmgr, 0, &tasks[i]),
|
||||||
|
ISC_R_SUCCESS);
|
||||||
|
event = isc_event_allocate(mctx, NULL, 1000, do_xadd,
|
||||||
|
&counters[i],
|
||||||
|
sizeof(struct isc_event));
|
||||||
|
ATF_REQUIRE(event != NULL);
|
||||||
|
isc_task_sendanddetach(&tasks[i], &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_test_end();
|
||||||
|
|
||||||
|
printf("32-bit counter %d, expected %d\n",
|
||||||
|
counter_32, EXPECTED_COUNT_32);
|
||||||
|
|
||||||
|
ATF_CHECK_EQ(counter_32, EXPECTED_COUNT_32);
|
||||||
|
counter_32 = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ISC_PLATFORM_HAVEXADDQ)
|
||||||
|
static isc_int64_t counter_64;
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_xaddq(isc_task_t *task, isc_event_t *ev) {
|
||||||
|
counter_t *state = (counter_t *)ev->ev_arg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0 ; i < COUNTS_PER_ITERATION ; i++) {
|
||||||
|
isc_atomic_xaddq(&counter_64, INCREMENT_64);
|
||||||
|
}
|
||||||
|
|
||||||
|
state->iteration++;
|
||||||
|
if (state->iteration < ITERATIONS) {
|
||||||
|
isc_task_send(task, &ev);
|
||||||
|
} else {
|
||||||
|
isc_event_free(&ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC(atomic_xaddq);
|
||||||
|
ATF_TC_HEAD(atomic_xaddq, tc) {
|
||||||
|
atf_tc_set_md_var(tc, "descr", "atomic XADDQ");
|
||||||
|
}
|
||||||
|
ATF_TC_BODY(atomic_xaddq, tc) {
|
||||||
|
isc_result_t result;
|
||||||
|
isc_task_t *tasks[TASKS];
|
||||||
|
isc_event_t *event = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
UNUSED(tc);
|
||||||
|
|
||||||
|
result = isc_test_begin(NULL, ISC_TRUE, 0);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
memset(counters, 0, sizeof(counters));
|
||||||
|
counter_64 = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create our tasks, and allocate an event to get the counters going.
|
||||||
|
*/
|
||||||
|
for (i = 0 ; i < TASKS ; i++) {
|
||||||
|
tasks[i] = NULL;
|
||||||
|
ATF_REQUIRE_EQ(isc_task_create(taskmgr, 0, &tasks[i]),
|
||||||
|
ISC_R_SUCCESS);
|
||||||
|
event = isc_event_allocate(mctx, NULL, 1000, do_xaddq,
|
||||||
|
&counters[i],
|
||||||
|
sizeof(struct isc_event));
|
||||||
|
ATF_REQUIRE(event != NULL);
|
||||||
|
isc_task_sendanddetach(&tasks[i], &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_test_end();
|
||||||
|
|
||||||
|
printf("64-bit counter %"ISC_PRINT_QUADFORMAT"d, "
|
||||||
|
"expected %"ISC_PRINT_QUADFORMAT"d\n",
|
||||||
|
counter_64, EXPECTED_COUNT_64);
|
||||||
|
|
||||||
|
ATF_CHECK_EQ(counter_64, EXPECTED_COUNT_64);
|
||||||
|
counter_32 = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ISC_PLATFORM_HAVEATOMICSTORE)
|
||||||
|
static isc_int32_t store_32;
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_store(isc_task_t *task, isc_event_t *ev) {
|
||||||
|
counter_t *state = (counter_t *)ev->ev_arg;
|
||||||
|
int i;
|
||||||
|
isc_uint32_t r;
|
||||||
|
isc_uint32_t val;
|
||||||
|
|
||||||
|
r = random() % 256;
|
||||||
|
val = (r << 24) | (r << 16) | (r << 8) | r;
|
||||||
|
|
||||||
|
for (i = 0 ; i < COUNTS_PER_ITERATION ; i++) {
|
||||||
|
isc_atomic_store(&store_32, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
state->iteration++;
|
||||||
|
if (state->iteration < ITERATIONS) {
|
||||||
|
isc_task_send(task, &ev);
|
||||||
|
} else {
|
||||||
|
isc_event_free(&ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC(atomic_store);
|
||||||
|
ATF_TC_HEAD(atomic_store, tc) {
|
||||||
|
atf_tc_set_md_var(tc, "descr", "atomic STORE");
|
||||||
|
}
|
||||||
|
ATF_TC_BODY(atomic_store, tc) {
|
||||||
|
isc_result_t result;
|
||||||
|
isc_task_t *tasks[TASKS];
|
||||||
|
isc_event_t *event = NULL;
|
||||||
|
isc_uint32_t val;
|
||||||
|
isc_uint32_t r;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
UNUSED(tc);
|
||||||
|
|
||||||
|
result = isc_test_begin(NULL, ISC_TRUE, 0);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
memset(counters, 0, sizeof(counters));
|
||||||
|
store_32 = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create our tasks, and allocate an event to get the counters
|
||||||
|
* going.
|
||||||
|
*/
|
||||||
|
for (i = 0 ; i < TASKS ; i++) {
|
||||||
|
tasks[i] = NULL;
|
||||||
|
ATF_REQUIRE_EQ(isc_task_create(taskmgr, 0, &tasks[i]),
|
||||||
|
ISC_R_SUCCESS);
|
||||||
|
event = isc_event_allocate(mctx, NULL, 1000, do_store,
|
||||||
|
&counters[i],
|
||||||
|
sizeof(struct isc_event));
|
||||||
|
ATF_REQUIRE(event != NULL);
|
||||||
|
isc_task_sendanddetach(&tasks[i], &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_test_end();
|
||||||
|
|
||||||
|
r = store_32 & 0xff;
|
||||||
|
val = (r << 24) | (r << 16) | (r << 8) | r;
|
||||||
|
|
||||||
|
printf("32-bit store 0x%x, expected 0x%x\n",
|
||||||
|
(isc_uint32_t) store_32, val);
|
||||||
|
|
||||||
|
ATF_CHECK_EQ((isc_uint32_t) store_32, val);
|
||||||
|
store_32 = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ISC_PLATFORM_HAVEATOMICSTOREQ)
|
||||||
|
static isc_int64_t store_64;
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_storeq(isc_task_t *task, isc_event_t *ev) {
|
||||||
|
counter_t *state = (counter_t *)ev->ev_arg;
|
||||||
|
int i;
|
||||||
|
isc_uint8_t r;
|
||||||
|
isc_uint64_t val;
|
||||||
|
|
||||||
|
r = random() % 256;
|
||||||
|
val = (((isc_uint64_t) r << 24) |
|
||||||
|
((isc_uint64_t) r << 16) |
|
||||||
|
((isc_uint64_t) r << 8) |
|
||||||
|
(isc_uint64_t) r);
|
||||||
|
val |= ((isc_uint64_t) val << 32);
|
||||||
|
|
||||||
|
for (i = 0 ; i < COUNTS_PER_ITERATION ; i++) {
|
||||||
|
isc_atomic_storeq(&store_64, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
state->iteration++;
|
||||||
|
if (state->iteration < ITERATIONS) {
|
||||||
|
isc_task_send(task, &ev);
|
||||||
|
} else {
|
||||||
|
isc_event_free(&ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC(atomic_storeq);
|
||||||
|
ATF_TC_HEAD(atomic_storeq, tc) {
|
||||||
|
atf_tc_set_md_var(tc, "descr", "atomic STOREQ");
|
||||||
|
}
|
||||||
|
ATF_TC_BODY(atomic_storeq, tc) {
|
||||||
|
isc_result_t result;
|
||||||
|
isc_task_t *tasks[TASKS];
|
||||||
|
isc_event_t *event = NULL;
|
||||||
|
isc_uint64_t val;
|
||||||
|
isc_uint32_t r;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
UNUSED(tc);
|
||||||
|
|
||||||
|
result = isc_test_begin(NULL, ISC_TRUE, 0);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
memset(counters, 0, sizeof(counters));
|
||||||
|
store_64 = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create our tasks, and allocate an event to get the counters
|
||||||
|
* going.
|
||||||
|
*/
|
||||||
|
for (i = 0 ; i < TASKS ; i++) {
|
||||||
|
tasks[i] = NULL;
|
||||||
|
ATF_REQUIRE_EQ(isc_task_create(taskmgr, 0, &tasks[i]),
|
||||||
|
ISC_R_SUCCESS);
|
||||||
|
event = isc_event_allocate(mctx, NULL, 1000, do_storeq,
|
||||||
|
&counters[i],
|
||||||
|
sizeof(struct isc_event));
|
||||||
|
ATF_REQUIRE(event != NULL);
|
||||||
|
isc_task_sendanddetach(&tasks[i], &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_test_end();
|
||||||
|
|
||||||
|
r = store_64 & 0xff;
|
||||||
|
val = (((isc_uint64_t) r << 24) |
|
||||||
|
((isc_uint64_t) r << 16) |
|
||||||
|
((isc_uint64_t) r << 8) |
|
||||||
|
(isc_uint64_t) r);
|
||||||
|
val |= ((isc_uint64_t) val << 32);
|
||||||
|
|
||||||
|
printf("64-bit store 0x%"ISC_PRINT_QUADFORMAT"x, "
|
||||||
|
"expected 0x%"ISC_PRINT_QUADFORMAT"x\n",
|
||||||
|
(isc_uint64_t) store_64, val);
|
||||||
|
|
||||||
|
ATF_CHECK_EQ((isc_uint64_t) store_64, val);
|
||||||
|
store_64 = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ISC_PLATFORM_HAVEXADD) && \
|
||||||
|
!defined(ISC_PLATFORM_HAVEXADDQ) && \
|
||||||
|
!defined(ISC_PLATFORM_HAVEATOMICSTOREQ)
|
||||||
|
ATF_TC(untested);
|
||||||
|
ATF_TC_HEAD(untested, tc) {
|
||||||
|
atf_tc_set_md_var(tc, "descr", "skipping aes test");
|
||||||
|
}
|
||||||
|
ATF_TC_BODY(untested, tc) {
|
||||||
|
UNUSED(tc);
|
||||||
|
atf_tc_skip("AES not available");
|
||||||
|
}
|
||||||
|
#endif /* !HAVEXADD, !HAVEXADDQ, !HAVEATOMICSTOREQ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Main
|
||||||
|
*/
|
||||||
|
ATF_TP_ADD_TCS(tp) {
|
||||||
|
#if defined(ISC_PLATFORM_HAVEXADD)
|
||||||
|
ATF_TP_ADD_TC(tp, atomic_xadd);
|
||||||
|
#endif
|
||||||
|
#if defined(ISC_PLATFORM_HAVEXADDQ)
|
||||||
|
ATF_TP_ADD_TC(tp, atomic_xaddq);
|
||||||
|
#endif
|
||||||
|
#ifdef ISC_PLATFORM_HAVEATOMICSTORE
|
||||||
|
ATF_TP_ADD_TC(tp, atomic_store);
|
||||||
|
#endif
|
||||||
|
#if defined(ISC_PLATFORM_HAVEATOMICSTOREQ)
|
||||||
|
ATF_TP_ADD_TC(tp, atomic_storeq);
|
||||||
|
#endif
|
||||||
|
#if !defined(ISC_PLATFORM_HAVEXADD) && \
|
||||||
|
!defined(ISC_PLATFORM_HAVEXADDQ) && \
|
||||||
|
!defined(ISC_PLATFORM_HAVEATOMICSTOREQ)
|
||||||
|
ATF_TP_ADD_TC(tp, untested);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (atf_no_error());
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* See the COPYRIGHT file distributed with this work for additional
|
||||||
|
* information regarding copyright ownership.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ISC_ATOMIC_H
|
||||||
|
#define ISC_ATOMIC_H 1
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <isc/platform.h>
|
||||||
|
#include <isc/types.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine atomically increments the value stored in 'p' by 'val', and
|
||||||
|
* returns the previous value.
|
||||||
|
*/
|
||||||
|
#ifdef ISC_PLATFORM_HAVEXADD
|
||||||
|
static __inline isc_int32_t
|
||||||
|
isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
return (isc_int32_t) _InterlockedExchangeAdd((long *)p, (long)val);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ISC_PLATFORM_HAVEXADDQ
|
||||||
|
static __inline isc_int64_t
|
||||||
|
isc_atomic_xaddq(isc_int64_t *p, isc_int64_t val) {
|
||||||
|
return (isc_int64_t) _InterlockedExchangeAdd64((__int64 *)p,
|
||||||
|
(__int64) val);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine atomically stores the value 'val' in 'p' (32-bit version).
|
||||||
|
*/
|
||||||
|
#ifdef ISC_PLATFORM_HAVEATOMICSTORE
|
||||||
|
static __inline void
|
||||||
|
isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
(void) _InterlockedExchange((long *)p, (long)val);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine atomically stores the value 'val' in 'p' (64-bit version).
|
||||||
|
*/
|
||||||
|
#ifdef ISC_PLATFORM_HAVEATOMICSTOREQ
|
||||||
|
static __inline void
|
||||||
|
isc_atomic_storeq(isc_int64_t *p, isc_int64_t val) {
|
||||||
|
(void) _InterlockedExchange64((__int64 *)p, (__int64)val);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine atomically replaces the value in 'p' with 'val', if the
|
||||||
|
* original value is equal to 'cmpval'. The original value is returned in any
|
||||||
|
* case.
|
||||||
|
*/
|
||||||
|
#ifdef ISC_PLATFORM_HAVECMPXCHG
|
||||||
|
static __inline isc_int32_t
|
||||||
|
isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
|
||||||
|
/* beware: swap arguments */
|
||||||
|
return (isc_int32_t) _InterlockedCompareExchange((long *)p,
|
||||||
|
(long)val,
|
||||||
|
(long)cmpval);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ISC_ATOMIC_H */
|
||||||
@@ -97,6 +97,30 @@
|
|||||||
*/
|
*/
|
||||||
@ISC_PLATFORM_WANTAES@
|
@ISC_PLATFORM_WANTAES@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the "xadd" operation is available on this architecture,
|
||||||
|
* ISC_PLATFORM_HAVEXADD will be defined.
|
||||||
|
*/
|
||||||
|
@ISC_PLATFORM_HAVEXADD@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the "xaddq" operation (64bit xadd) is available on this architecture,
|
||||||
|
* ISC_PLATFORM_HAVEXADDQ will be defined.
|
||||||
|
*/
|
||||||
|
@ISC_PLATFORM_HAVEXADDQ@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the "atomic swap" operation is available on this architecture,
|
||||||
|
* ISC_PLATFORM_HAVEATOMICSTORE" will be defined.
|
||||||
|
*/
|
||||||
|
@ISC_PLATFORM_HAVEATOMICSTORE@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the "compare-and-exchange" operation is available on this architecture,
|
||||||
|
* ISC_PLATFORM_HAVECMPXCHG will be defined.
|
||||||
|
*/
|
||||||
|
@ISC_PLATFORM_HAVECMPXCHG@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define with the busy wait nop asm or function call.
|
* Define with the busy wait nop asm or function call.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -374,6 +374,11 @@
|
|||||||
<Filter>Win32 Header Files</Filter>
|
<Filter>Win32 Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@END PKCS11
|
@END PKCS11
|
||||||
|
@IF ATOMIC
|
||||||
|
<ClInclude Include="include\isc\atomic.h">
|
||||||
|
@ELSE ATOMIC
|
||||||
|
<ClInclude Include="..\noatomic\include\isc\atomic.h">
|
||||||
|
@END ATOMIC
|
||||||
<Filter>Library Header Files</Filter>
|
<Filter>Library Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\..\config.h">
|
<ClInclude Include="..\..\..\config.h">
|
||||||
@@ -592,6 +597,9 @@
|
|||||||
<ClCompile Include="..\ratelimiter.c">
|
<ClCompile Include="..\ratelimiter.c">
|
||||||
<Filter>Library Source Files</Filter>
|
<Filter>Library Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\refcount.c">
|
||||||
|
<Filter>Library Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\regex.c">
|
<ClCompile Include="..\regex.c">
|
||||||
<Filter>Library Source Files</Filter>
|
<Filter>Library Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@@ -386,6 +386,11 @@ copy InstallFiles ..\Build\Release\
|
|||||||
<ClInclude Include="..\include\pkcs11\pkcs11f.h" />
|
<ClInclude Include="..\include\pkcs11\pkcs11f.h" />
|
||||||
<ClInclude Include="..\include\pkcs11\pkcs11t.h" />
|
<ClInclude Include="..\include\pkcs11\pkcs11t.h" />
|
||||||
@END PKCS11
|
@END PKCS11
|
||||||
|
@IF ATOMIC
|
||||||
|
<ClInclude Include="include\isc\atomic.h" />
|
||||||
|
@ELSE ATOMIC
|
||||||
|
<ClInclude Include="..\noatomic\include\isc\atomic.h" />
|
||||||
|
@END ATOMIC
|
||||||
<ClInclude Include="errno2result.h" />
|
<ClInclude Include="errno2result.h" />
|
||||||
<ClInclude Include="include\isc\bindevt.h" />
|
<ClInclude Include="include\isc\bindevt.h" />
|
||||||
<ClInclude Include="include\isc\bind_registry.h" />
|
<ClInclude Include="include\isc\bind_registry.h" />
|
||||||
@@ -460,6 +465,7 @@ copy InstallFiles ..\Build\Release\
|
|||||||
<ClCompile Include="..\radix.c" />
|
<ClCompile Include="..\radix.c" />
|
||||||
<ClCompile Include="..\random.c" />
|
<ClCompile Include="..\random.c" />
|
||||||
<ClCompile Include="..\ratelimiter.c" />
|
<ClCompile Include="..\ratelimiter.c" />
|
||||||
|
<ClCompile Include="..\refcount.c" />
|
||||||
<ClCompile Include="..\regex.c" />
|
<ClCompile Include="..\regex.c" />
|
||||||
<ClCompile Include="..\region.c" />
|
<ClCompile Include="..\region.c" />
|
||||||
<ClCompile Include="..\result.c" />
|
<ClCompile Include="..\result.c" />
|
||||||
|
|||||||
@@ -1,179 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*
|
|
||||||
* See the COPYRIGHT file distributed with this work for additional
|
|
||||||
* information regarding copyright ownership.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
/** \file
|
|
||||||
* \brief a light stdatomic.h compatibility wrapper for Win32
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
/* does nothing */
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
memory_order_relaxed,
|
|
||||||
memory_order_consume,
|
|
||||||
memory_order_acquire,
|
|
||||||
memory_order_release,
|
|
||||||
memory_order_acq_rel,
|
|
||||||
memory_order_seq_cst
|
|
||||||
} memory_order;
|
|
||||||
|
|
||||||
typedef intptr_t atomic_flag;
|
|
||||||
typedef intptr_t atomic_bool;
|
|
||||||
typedef intptr_t atomic_char;
|
|
||||||
typedef intptr_t atomic_schar;
|
|
||||||
typedef intptr_t atomic_uchar;
|
|
||||||
typedef intptr_t atomic_short;
|
|
||||||
typedef intptr_t atomic_ushort;
|
|
||||||
typedef intptr_t atomic_int;
|
|
||||||
typedef intptr_t atomic_uint;
|
|
||||||
typedef intptr_t atomic_long;
|
|
||||||
typedef intptr_t atomic_ulong;
|
|
||||||
typedef intptr_t atomic_llong;
|
|
||||||
typedef intptr_t atomic_ullong;
|
|
||||||
typedef intptr_t atomic_wchar_t;
|
|
||||||
typedef intptr_t atomic_int_least8_t;
|
|
||||||
typedef intptr_t atomic_uint_least8_t;
|
|
||||||
typedef intptr_t atomic_int_least16_t;
|
|
||||||
typedef intptr_t atomic_uint_least16_t;
|
|
||||||
typedef intptr_t atomic_int_least32_t;
|
|
||||||
typedef intptr_t atomic_uint_least32_t;
|
|
||||||
typedef intptr_t atomic_int_least64_t;
|
|
||||||
typedef intptr_t atomic_uint_least64_t;
|
|
||||||
typedef intptr_t atomic_int_fast8_t;
|
|
||||||
typedef intptr_t atomic_uint_fast8_t;
|
|
||||||
typedef intptr_t atomic_int_fast16_t;
|
|
||||||
typedef intptr_t atomic_uint_fast16_t;
|
|
||||||
typedef intptr_t atomic_int_fast32_t;
|
|
||||||
typedef intptr_t atomic_uint_fast32_t;
|
|
||||||
typedef intptr_t atomic_int_fast64_t;
|
|
||||||
typedef intptr_t atomic_uint_fast64_t;
|
|
||||||
typedef intptr_t atomic_intptr_t;
|
|
||||||
typedef intptr_t atomic_uintptr_t;
|
|
||||||
typedef intptr_t atomic_size_t;
|
|
||||||
typedef intptr_t atomic_ptrdiff_t;
|
|
||||||
typedef intptr_t atomic_intmax_t;
|
|
||||||
typedef intptr_t atomic_uintmax_t;
|
|
||||||
|
|
||||||
#define ATOMIC_VAR_INIT(value) \
|
|
||||||
(value)
|
|
||||||
|
|
||||||
#define atomic_init(object, value) \
|
|
||||||
atomic_store(object, value)
|
|
||||||
|
|
||||||
#define kill_dependency(y) ((void)0)
|
|
||||||
|
|
||||||
#define atomic_thread_fence(order) \
|
|
||||||
MemoryBarrier();
|
|
||||||
|
|
||||||
#define atomic_signal_fence(order) \
|
|
||||||
((void)NULL)
|
|
||||||
|
|
||||||
#define atomic_is_lock_free(obj) 0
|
|
||||||
|
|
||||||
#define atomic_store(object, desired) \
|
|
||||||
do { \
|
|
||||||
*(object) = (desired); \
|
|
||||||
MemoryBarrier(); \
|
|
||||||
} while(0);
|
|
||||||
#define atomic_store_explicit(object, desired, order) \
|
|
||||||
atomic_store(object, desired)
|
|
||||||
|
|
||||||
#define atomic_load(object) \
|
|
||||||
(MemoryBarrier(), *(object))
|
|
||||||
#define atomic_load_explicit(object, order) \
|
|
||||||
atomic_load(object)
|
|
||||||
|
|
||||||
#define atomic_exchange_explicit(object, desired) \
|
|
||||||
InterlockedExchangePointer(object, desired);
|
|
||||||
#define atomic_exchange_explicit(object, desired, order) \
|
|
||||||
atomic_exchange(object, desired)
|
|
||||||
|
|
||||||
static inline bool atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected,
|
|
||||||
intptr_t desired)
|
|
||||||
{
|
|
||||||
intptr_t stored = *expected;
|
|
||||||
*expected = (intptr_t)InterlockedCompareExchangePointer((PVOID *)object,
|
|
||||||
(PVOID)desired, (PVOID)stored);
|
|
||||||
return !!(*expected == stored);
|
|
||||||
}
|
|
||||||
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
|
||||||
atomic_compare_exchange_strong(object, expected, desired)
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_weak(object, expected, desired) \
|
|
||||||
atomic_compare_exchange_strong(object, expected, desired)
|
|
||||||
|
|
||||||
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
|
||||||
atomic_compare_exchange_weak(object, expected, desired)
|
|
||||||
|
|
||||||
#ifdef _WIN64
|
|
||||||
#define atomic_fetch_add(object, operand) \
|
|
||||||
InterlockedExchangeAdd64(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_sub(object, operand) \
|
|
||||||
InterlockedExchangeAdd64(object, -(operand))
|
|
||||||
|
|
||||||
#define atomic_fetch_or(object, operand) \
|
|
||||||
InterlockedOr64(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_xor(object, operand) \
|
|
||||||
InterlockedXor64(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_and(object, operand) \
|
|
||||||
InterlockedAnd64(object, operand)
|
|
||||||
#else /* _WIN64 */
|
|
||||||
#define atomic_fetch_add(object, operand) \
|
|
||||||
InterlockedExchangeAdd(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_sub(object, operand) \
|
|
||||||
InterlockedExchangeAdd(object, -(operand))
|
|
||||||
|
|
||||||
#define atomic_fetch_or(object, operand) \
|
|
||||||
InterlockedOr(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_xor(object, operand) \
|
|
||||||
InterlockedXor(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_and(object, operand) \
|
|
||||||
InterlockedAnd(object, operand)
|
|
||||||
#endif /* _WIN64 */
|
|
||||||
|
|
||||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_add(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_sub(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_or(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_sub(object, operand)
|
|
||||||
|
|
||||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
|
||||||
atomic_fetch_and(object, operand)
|
|
||||||
|
|
||||||
#define atomic_flag_test_and_set(object) \
|
|
||||||
atomic_exchange(object, 1)
|
|
||||||
|
|
||||||
#define atomic_flag_test_and_set_explicit(object, order) \
|
|
||||||
atomic_flag_test_and_set(object)
|
|
||||||
|
|
||||||
#define atomic_flag_clear(object) \
|
|
||||||
atomic_store(object, 0)
|
|
||||||
|
|
||||||
#define atomic_flag_clear_explicit(object, order) \
|
|
||||||
atomic_flag_clear(object)
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SUBDIRS = include
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SUBDIRS = isc
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
VERSION=@BIND9_VERSION@
|
||||||
|
|
||||||
|
HEADERS = atomic.h
|
||||||
|
|
||||||
|
SUBDIRS =
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
|
|
||||||
|
installdirs:
|
||||||
|
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc
|
||||||
|
|
||||||
|
install:: installdirs
|
||||||
|
for i in ${HEADERS}; do \
|
||||||
|
${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall::
|
||||||
|
for i in ${HEADERS}; do \
|
||||||
|
rm -f ${DESTDIR}${includedir}/isc/$$i ; \
|
||||||
|
done
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* See the COPYRIGHT file distributed with this work for additional
|
||||||
|
* information regarding copyright ownership.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ISC_ATOMIC_H
|
||||||
|
#define ISC_ATOMIC_H 1
|
||||||
|
|
||||||
|
#include <isc/platform.h>
|
||||||
|
#include <isc/types.h>
|
||||||
|
|
||||||
|
#ifdef ISC_PLATFORM_USEGCCASM
|
||||||
|
/*
|
||||||
|
* This routine atomically increments the value stored in 'p' by 'val', and
|
||||||
|
* returns the previous value.
|
||||||
|
*/
|
||||||
|
static __inline__ isc_int32_t
|
||||||
|
isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
isc_int32_t prev = val;
|
||||||
|
|
||||||
|
__asm__ volatile(
|
||||||
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
"lock;"
|
||||||
|
#endif
|
||||||
|
"xadd %0, %1"
|
||||||
|
:"=q"(prev)
|
||||||
|
:"m"(*p), "0"(prev)
|
||||||
|
:"memory", "cc");
|
||||||
|
|
||||||
|
return (prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ISC_PLATFORM_HAVEXADDQ
|
||||||
|
static __inline__ isc_int64_t
|
||||||
|
isc_atomic_xaddq(isc_int64_t *p, isc_int64_t val) {
|
||||||
|
isc_int64_t prev = val;
|
||||||
|
|
||||||
|
__asm__ volatile(
|
||||||
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
"lock;"
|
||||||
|
#endif
|
||||||
|
"xaddq %0, %1"
|
||||||
|
:"=q"(prev)
|
||||||
|
:"m"(*p), "0"(prev)
|
||||||
|
:"memory", "cc");
|
||||||
|
|
||||||
|
return (prev);
|
||||||
|
}
|
||||||
|
#endif /* ISC_PLATFORM_HAVEXADDQ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine atomically stores the value 'val' in 'p' (32-bit version).
|
||||||
|
*/
|
||||||
|
static __inline__ void
|
||||||
|
isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
__asm__ volatile(
|
||||||
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
/*
|
||||||
|
* xchg should automatically lock memory, but we add it
|
||||||
|
* explicitly just in case (it at least doesn't harm)
|
||||||
|
*/
|
||||||
|
"lock;"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
"xchgl %1, %0"
|
||||||
|
:
|
||||||
|
: "r"(val), "m"(*p)
|
||||||
|
: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ISC_PLATFORM_HAVEATOMICSTOREQ
|
||||||
|
/*
|
||||||
|
* This routine atomically stores the value 'val' in 'p' (64-bit version).
|
||||||
|
*/
|
||||||
|
static __inline__ void
|
||||||
|
isc_atomic_storeq(isc_int64_t *p, isc_int64_t val) {
|
||||||
|
__asm__ volatile(
|
||||||
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
/*
|
||||||
|
* xchg should automatically lock memory, but we add it
|
||||||
|
* explicitly just in case (it at least doesn't harm)
|
||||||
|
*/
|
||||||
|
"lock;"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
"xchgq %1, %0"
|
||||||
|
:
|
||||||
|
: "r"(val), "m"(*p)
|
||||||
|
: "memory");
|
||||||
|
}
|
||||||
|
#endif /* ISC_PLATFORM_HAVEATOMICSTOREQ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This routine atomically replaces the value in 'p' with 'val', if the
|
||||||
|
* original value is equal to 'cmpval'. The original value is returned in any
|
||||||
|
* case.
|
||||||
|
*/
|
||||||
|
static __inline__ isc_int32_t
|
||||||
|
isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
|
||||||
|
__asm__ volatile(
|
||||||
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
"lock;"
|
||||||
|
#endif
|
||||||
|
"cmpxchgl %1, %2"
|
||||||
|
: "=a"(cmpval)
|
||||||
|
: "r"(val), "m"(*p), "a"(cmpval)
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
return (cmpval);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(ISC_PLATFORM_USESTDASM)
|
||||||
|
/*
|
||||||
|
* The followings are "generic" assembly code which implements the same
|
||||||
|
* functionality in case the gcc extension cannot be used. It should be
|
||||||
|
* better to avoid inlining below, since we directly refer to specific
|
||||||
|
* positions of the stack frame, which would not actually point to the
|
||||||
|
* intended address in the embedded mnemonic.
|
||||||
|
*/
|
||||||
|
static isc_int32_t
|
||||||
|
isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
(void)(p);
|
||||||
|
(void)(val);
|
||||||
|
|
||||||
|
__asm (
|
||||||
|
"movl 8(%ebp), %ecx\n"
|
||||||
|
"movl 12(%ebp), %edx\n"
|
||||||
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
"lock;"
|
||||||
|
#endif
|
||||||
|
"xadd %edx, (%ecx)\n"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set the return value directly in the register so that we
|
||||||
|
* can avoid guessing the correct position in the stack for a
|
||||||
|
* local variable.
|
||||||
|
*/
|
||||||
|
"movl %edx, %eax"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
(void)(p);
|
||||||
|
(void)(val);
|
||||||
|
|
||||||
|
__asm (
|
||||||
|
"movl 8(%ebp), %ecx\n"
|
||||||
|
"movl 12(%ebp), %edx\n"
|
||||||
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
"lock;"
|
||||||
|
#endif
|
||||||
|
"xchgl (%ecx), %edx\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static isc_int32_t
|
||||||
|
isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
|
||||||
|
(void)(p);
|
||||||
|
(void)(cmpval);
|
||||||
|
(void)(val);
|
||||||
|
|
||||||
|
__asm (
|
||||||
|
"movl 8(%ebp), %ecx\n"
|
||||||
|
"movl 12(%ebp), %eax\n" /* must be %eax for cmpxchgl */
|
||||||
|
"movl 16(%ebp), %edx\n"
|
||||||
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
"lock;"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If (%ecx) == %eax then (%ecx) := %edx.
|
||||||
|
% %eax is set to old (%ecx), which will be the return value.
|
||||||
|
*/
|
||||||
|
"cmpxchgl %edx, (%ecx)"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#else /* !ISC_PLATFORM_USEGCCASM && !ISC_PLATFORM_USESTDASM */
|
||||||
|
|
||||||
|
#error "unsupported compiler. disable atomic ops by --disable-atomic"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif /* ISC_ATOMIC_H */
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SUBDIRS = include
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SUBDIRS = isc
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
VERSION=@BIND9_VERSION@
|
||||||
|
|
||||||
|
HEADERS = atomic.h
|
||||||
|
|
||||||
|
SUBDIRS =
|
||||||
|
TARGETS =
|
||||||
|
|
||||||
|
@BIND9_MAKE_RULES@
|
||||||
|
|
||||||
|
installdirs:
|
||||||
|
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc
|
||||||
|
|
||||||
|
install:: installdirs
|
||||||
|
for i in ${HEADERS}; do \
|
||||||
|
${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall::
|
||||||
|
for i in ${HEADERS}; do \
|
||||||
|
rm -f ${DESTDIR}${includedir}/isc/$$i ; \
|
||||||
|
done
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* See the COPYRIGHT file distributed with this work for additional
|
||||||
|
* information regarding copyright ownership.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ISC_ATOMIC_H
|
||||||
|
#define ISC_ATOMIC_H 1
|
||||||
|
|
||||||
|
#include <isc/platform.h>
|
||||||
|
#include <isc/types.h>
|
||||||
|
|
||||||
|
#ifdef ISC_PLATFORM_USEGCCASM
|
||||||
|
|
||||||
|
/* We share the gcc-version with x86_32 */
|
||||||
|
#error "impossible case. check build configuration"
|
||||||
|
|
||||||
|
#elif defined(ISC_PLATFORM_USESTDASM)
|
||||||
|
/*
|
||||||
|
* The followings are "generic" assembly code which implements the same
|
||||||
|
* functionality in case the gcc extension cannot be used. It should be
|
||||||
|
* better to avoid inlining below, since we directly refer to specific
|
||||||
|
* registers for arguments, which would not actually correspond to the
|
||||||
|
* intended address or value in the embedded mnemonic.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static isc_int32_t
|
||||||
|
isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
(void)(p);
|
||||||
|
(void)(val);
|
||||||
|
|
||||||
|
__asm (
|
||||||
|
"movq %rdi, %rdx\n"
|
||||||
|
"movl %esi, %eax\n"
|
||||||
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
"lock;"
|
||||||
|
#endif
|
||||||
|
"xadd %eax, (%rdx)\n"
|
||||||
|
/*
|
||||||
|
* XXX: assume %eax will be used as the return value.
|
||||||
|
*/
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ISC_PLATFORM_HAVEXADDQ
|
||||||
|
static isc_int64_t
|
||||||
|
isc_atomic_xaddq(isc_int64_t *p, isc_int64_t val) {
|
||||||
|
(void)(p);
|
||||||
|
(void)(val);
|
||||||
|
|
||||||
|
__asm (
|
||||||
|
"movq %rdi, %rdx\n"
|
||||||
|
"movq %rsi, %rax\n"
|
||||||
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
"lock;"
|
||||||
|
#endif
|
||||||
|
"xaddq %rax, (%rdx)\n"
|
||||||
|
/*
|
||||||
|
* XXX: assume %rax will be used as the return value.
|
||||||
|
*/
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
|
||||||
|
(void)(p);
|
||||||
|
(void)(val);
|
||||||
|
|
||||||
|
__asm (
|
||||||
|
"movq %rdi, %rax\n"
|
||||||
|
"movl %esi, %edx\n"
|
||||||
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
"lock;"
|
||||||
|
#endif
|
||||||
|
"xchgl (%rax), %edx\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ISC_PLATFORM_HAVEATOMICSTOREQ
|
||||||
|
static void
|
||||||
|
isc_atomic_storeq(isc_int64_t *p, isc_int64_t val) {
|
||||||
|
(void)(p);
|
||||||
|
(void)(val);
|
||||||
|
|
||||||
|
__asm (
|
||||||
|
"movq %rdi, %rax\n"
|
||||||
|
"movq %rsi, %rdx\n"
|
||||||
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
"lock;"
|
||||||
|
#endif
|
||||||
|
"xchgq (%rax), %rdx\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static isc_int32_t
|
||||||
|
isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
|
||||||
|
(void)(p);
|
||||||
|
(void)(cmpval);
|
||||||
|
(void)(val);
|
||||||
|
|
||||||
|
__asm (
|
||||||
|
/*
|
||||||
|
* p is %rdi, cmpval is %esi, val is %edx.
|
||||||
|
*/
|
||||||
|
"movl %edx, %ecx\n"
|
||||||
|
"movl %esi, %eax\n"
|
||||||
|
"movq %rdi, %rdx\n"
|
||||||
|
|
||||||
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
"lock;"
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* If [%rdi] == %eax then [%rdi] := %ecx (equal to %edx
|
||||||
|
* from above), and %eax is untouched (equal to %esi)
|
||||||
|
* from above.
|
||||||
|
*
|
||||||
|
* Else if [%rdi] != %eax then [%rdi] := [%rdi]
|
||||||
|
* (rewritten in write cycle) and %eax := [%rdi].
|
||||||
|
*/
|
||||||
|
"cmpxchgl %ecx, (%rdx)"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* !ISC_PLATFORM_USEGCCASM && !ISC_PLATFORM_USESTDASM */
|
||||||
|
|
||||||
|
#error "unsupported compiler. disable atomic ops by --disable-atomic"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif /* ISC_ATOMIC_H */
|
||||||
@@ -68,7 +68,7 @@ cfg_aclconfctx_attach(cfg_aclconfctx_t *src, cfg_aclconfctx_t **dest) {
|
|||||||
REQUIRE(src != NULL);
|
REQUIRE(src != NULL);
|
||||||
REQUIRE(dest != NULL && *dest == NULL);
|
REQUIRE(dest != NULL && *dest == NULL);
|
||||||
|
|
||||||
isc_refcount_increment(&src->references);
|
isc_refcount_increment(&src->references, NULL);
|
||||||
*dest = src;
|
*dest = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,14 +76,14 @@ void
|
|||||||
cfg_aclconfctx_detach(cfg_aclconfctx_t **actxp) {
|
cfg_aclconfctx_detach(cfg_aclconfctx_t **actxp) {
|
||||||
cfg_aclconfctx_t *actx;
|
cfg_aclconfctx_t *actx;
|
||||||
dns_acl_t *dacl, *next;
|
dns_acl_t *dacl, *next;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
|
|
||||||
REQUIRE(actxp != NULL && *actxp != NULL);
|
REQUIRE(actxp != NULL && *actxp != NULL);
|
||||||
|
|
||||||
actx = *actxp;
|
actx = *actxp;
|
||||||
|
|
||||||
refs = isc_refcount_decrement(&actx->references);
|
isc_refcount_decrement(&actx->references, &refs);
|
||||||
if (refs == 1) {
|
if (refs == 0) {
|
||||||
for (dacl = ISC_LIST_HEAD(actx->named_acl_cache);
|
for (dacl = ISC_LIST_HEAD(actx->named_acl_cache);
|
||||||
dacl != NULL;
|
dacl != NULL;
|
||||||
dacl = next)
|
dacl = next)
|
||||||
|
|||||||
+11
-11
@@ -657,22 +657,22 @@ cfg_parser_attach(cfg_parser_t *src, cfg_parser_t **dest) {
|
|||||||
REQUIRE(src != NULL);
|
REQUIRE(src != NULL);
|
||||||
REQUIRE(dest != NULL && *dest == NULL);
|
REQUIRE(dest != NULL && *dest == NULL);
|
||||||
|
|
||||||
isc_refcount_increment(&src->references);
|
isc_refcount_increment(&src->references, NULL);
|
||||||
*dest = src;
|
*dest = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cfg_parser_destroy(cfg_parser_t **pctxp) {
|
cfg_parser_destroy(cfg_parser_t **pctxp) {
|
||||||
cfg_parser_t *pctx;
|
cfg_parser_t *pctx;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
|
|
||||||
REQUIRE(pctxp != NULL && *pctxp != NULL);
|
REQUIRE(pctxp != NULL && *pctxp != NULL);
|
||||||
|
|
||||||
pctx = *pctxp;
|
pctx = *pctxp;
|
||||||
*pctxp = NULL;
|
*pctxp = NULL;
|
||||||
|
|
||||||
refs = isc_refcount_decrement(&pctx->references);
|
isc_refcount_decrement(&pctx->references, &refs);
|
||||||
if (refs == 1) {
|
if (refs == 0) {
|
||||||
isc_lex_destroy(&pctx->lexer);
|
isc_lex_destroy(&pctx->lexer);
|
||||||
/*
|
/*
|
||||||
* Cleaning up open_files does not
|
* Cleaning up open_files does not
|
||||||
@@ -3125,15 +3125,15 @@ cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type) {
|
|||||||
void
|
void
|
||||||
cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **objp) {
|
cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **objp) {
|
||||||
cfg_obj_t *obj;
|
cfg_obj_t *obj;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
|
|
||||||
REQUIRE(objp != NULL && *objp != NULL);
|
REQUIRE(objp != NULL && *objp != NULL);
|
||||||
REQUIRE(pctx != NULL);
|
REQUIRE(pctx != NULL);
|
||||||
|
|
||||||
obj = *objp;
|
obj = *objp;
|
||||||
|
|
||||||
refs = isc_refcount_decrement(&obj->references);
|
isc_refcount_decrement(&obj->references, &refs);
|
||||||
if (refs == 1) {
|
if (refs == 0) {
|
||||||
obj->type->rep->free(pctx, obj);
|
obj->type->rep->free(pctx, obj);
|
||||||
isc_refcount_destroy(&obj->references);
|
isc_refcount_destroy(&obj->references);
|
||||||
isc_mem_put(pctx->mctx, obj, sizeof(cfg_obj_t));
|
isc_mem_put(pctx->mctx, obj, sizeof(cfg_obj_t));
|
||||||
@@ -3143,11 +3143,11 @@ cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **objp) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
cfg_obj_attach(cfg_obj_t *src, cfg_obj_t **dest) {
|
cfg_obj_attach(cfg_obj_t *src, cfg_obj_t **dest) {
|
||||||
REQUIRE(src != NULL);
|
REQUIRE(src != NULL);
|
||||||
REQUIRE(dest != NULL && *dest == NULL);
|
REQUIRE(dest != NULL && *dest == NULL);
|
||||||
|
|
||||||
isc_refcount_increment(&src->references);
|
isc_refcount_increment(&src->references, NULL);
|
||||||
*dest = src;
|
*dest = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
+1
-1
@@ -5172,7 +5172,7 @@ root_key_sentinel_detect(query_ctx_t *qctx) {
|
|||||||
NS_LOGMODULE_QUERY, ISC_LOG_INFO,
|
NS_LOGMODULE_QUERY, ISC_LOG_INFO,
|
||||||
"root-key-sentinel-is-ta query label found");
|
"root-key-sentinel-is-ta query label found");
|
||||||
} else if (qctx->client->query.qname->length > 31 && ndata[0] == 30 &&
|
} else if (qctx->client->query.qname->length > 31 && ndata[0] == 30 &&
|
||||||
strncasecmp(ndata + 1, "root-key-sentinel-not-ta-", 25) == 0)
|
strncasecmp(ndata + 1, "root-key-sentinel-not-ta-", 25) == 0)
|
||||||
{
|
{
|
||||||
if (!get_root_key_sentinel_id(qctx, ndata + 26)) {
|
if (!get_root_key_sentinel_id(qctx, ndata + 26)) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
+4
-4
@@ -122,7 +122,7 @@ ns_server_attach(ns_server_t *src, ns_server_t **dest) {
|
|||||||
REQUIRE(SCTX_VALID(src));
|
REQUIRE(SCTX_VALID(src));
|
||||||
REQUIRE(dest != NULL && *dest == NULL);
|
REQUIRE(dest != NULL && *dest == NULL);
|
||||||
|
|
||||||
isc_refcount_increment(&src->references);
|
isc_refcount_increment(&src->references, NULL);
|
||||||
|
|
||||||
*dest = src;
|
*dest = src;
|
||||||
}
|
}
|
||||||
@@ -130,14 +130,14 @@ ns_server_attach(ns_server_t *src, ns_server_t **dest) {
|
|||||||
void
|
void
|
||||||
ns_server_detach(ns_server_t **sctxp) {
|
ns_server_detach(ns_server_t **sctxp) {
|
||||||
ns_server_t *sctx;
|
ns_server_t *sctx;
|
||||||
int_fast32_t refs;
|
unsigned int refs;
|
||||||
|
|
||||||
REQUIRE(sctxp != NULL);
|
REQUIRE(sctxp != NULL);
|
||||||
sctx = *sctxp;
|
sctx = *sctxp;
|
||||||
REQUIRE(SCTX_VALID(sctx));
|
REQUIRE(SCTX_VALID(sctx));
|
||||||
|
|
||||||
refs = isc_refcount_decrement(&sctx->references);
|
isc_refcount_decrement(&sctx->references, &refs);
|
||||||
if (refs == 1) {
|
if (refs == 0) {
|
||||||
ns_altsecret_t *altsecret;
|
ns_altsecret_t *altsecret;
|
||||||
|
|
||||||
sctx->magic = 0;
|
sctx->magic = 0;
|
||||||
|
|||||||
+2
-1
@@ -17,7 +17,8 @@ ISC_INCLUDES = @BIND9_ISC_BUILDINCLUDE@ \
|
|||||||
-I${top_srcdir}/lib/isc \
|
-I${top_srcdir}/lib/isc \
|
||||||
-I${top_srcdir}/lib/isc/include \
|
-I${top_srcdir}/lib/isc/include \
|
||||||
-I${top_srcdir}/lib/isc/unix/include \
|
-I${top_srcdir}/lib/isc/unix/include \
|
||||||
-I${top_srcdir}/lib/isc/@ISC_THREAD_DIR@/include
|
-I${top_srcdir}/lib/isc/@ISC_THREAD_DIR@/include \
|
||||||
|
-I${top_srcdir}/lib/isc/@ISC_ARCH_DIR@/include
|
||||||
|
|
||||||
ISCCC_INCLUDES = @BIND9_ISCCC_BUILDINCLUDE@ \
|
ISCCC_INCLUDES = @BIND9_ISCCC_BUILDINCLUDE@ \
|
||||||
-I${top_srcdir}/lib/isccc/include
|
-I${top_srcdir}/lib/isccc/include
|
||||||
|
|||||||
+2
-17
@@ -24,11 +24,11 @@ $\ = "\n"; # set output record separator
|
|||||||
|
|
||||||
$change = 0;
|
$change = 0;
|
||||||
$status = 0;
|
$status = 0;
|
||||||
$wasblank = 1;
|
|
||||||
|
|
||||||
line: while (<>) {
|
line: while (<>) {
|
||||||
($Fld1,$Fld2,$Fld3,$Fld4) = split(' ', $_, 9999);
|
($Fld1,$Fld2,$Fld3,$Fld4) = split(' ', $_, 9999);
|
||||||
$change = 0 if (!$master && /^\s+--- .* ---$/);
|
$change = 0 if (!$master && $Fld1 eq "---" &&
|
||||||
|
$Fld3 eq "released" && $Fld4 eq "---");
|
||||||
if ($Fld1 =~ /^[1-9][0-9]*\.$/ && $Fld2 =~ /^\[.*\]$/) {
|
if ($Fld1 =~ /^[1-9][0-9]*\.$/ && $Fld2 =~ /^\[.*\]$/) {
|
||||||
if ($change != 0 && $Fld1 >= $change) {
|
if ($change != 0 && $Fld1 >= $change) {
|
||||||
print 'bad change number', $Fld1;
|
print 'bad change number', $Fld1;
|
||||||
@@ -39,21 +39,6 @@ line: while (<>) {
|
|||||||
$status = 1;
|
$status = 1;
|
||||||
}
|
}
|
||||||
$change = $Fld1;
|
$change = $Fld1;
|
||||||
if (!$wasblank) {
|
|
||||||
print 'missing blank line before change', $Fld1;
|
|
||||||
$status = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (/^\s+--- .* ---$/) {
|
|
||||||
if (!$wasblank) {
|
|
||||||
print 'missing blank line before release marker for', $Fld2;
|
|
||||||
$status = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($Fld1 eq "") {
|
|
||||||
$wasblank = 1;
|
|
||||||
} else {
|
|
||||||
$wasblank = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -1,3 +1,4 @@
|
|||||||
|
./.clang-format X 2018
|
||||||
./.gitattributes X 2015,2017,2018
|
./.gitattributes X 2015,2017,2018
|
||||||
./.gitignore X 2012,2013,2014,2015,2016,2017,2018
|
./.gitignore X 2012,2013,2014,2015,2016,2017,2018
|
||||||
./.gitlab-ci.yml X 2018
|
./.gitlab-ci.yml X 2018
|
||||||
@@ -2787,7 +2788,6 @@
|
|||||||
./doc/arm/notes.conf X 2015,2018
|
./doc/arm/notes.conf X 2015,2018
|
||||||
./doc/arm/notes.html X 2014,2015,2016,2017,2018
|
./doc/arm/notes.html X 2014,2015,2016,2017,2018
|
||||||
./doc/arm/notes.pdf X 2014,2015,2016,2017,2018
|
./doc/arm/notes.pdf X 2014,2015,2016,2017,2018
|
||||||
./doc/arm/notes.txt X 2018
|
|
||||||
./doc/arm/notes.xml SGML 2014,2015,2016,2017,2018
|
./doc/arm/notes.xml SGML 2014,2015,2016,2017,2018
|
||||||
./doc/arm/noteversion.xml.in SGML 2015,2016,2018
|
./doc/arm/noteversion.xml.in SGML 2015,2016,2018
|
||||||
./doc/arm/options.grammar.xml SGML 2018
|
./doc/arm/options.grammar.xml SGML 2018
|
||||||
@@ -3309,6 +3309,7 @@
|
|||||||
./lib/dns/tests/dnstest.c C 2011,2012,2013,2014,2015,2016,2017,2018
|
./lib/dns/tests/dnstest.c C 2011,2012,2013,2014,2015,2016,2017,2018
|
||||||
./lib/dns/tests/dnstest.h C 2011,2012,2014,2015,2016,2017,2018
|
./lib/dns/tests/dnstest.h C 2011,2012,2014,2015,2016,2017,2018
|
||||||
./lib/dns/tests/dst_test.c C 2018
|
./lib/dns/tests/dst_test.c C 2018
|
||||||
|
./lib/dns/tests/dstrandom_test.c C 2017,2018
|
||||||
./lib/dns/tests/geoip_test.c C 2013,2014,2015,2016,2017,2018
|
./lib/dns/tests/geoip_test.c C 2013,2014,2015,2016,2017,2018
|
||||||
./lib/dns/tests/gost_test.c C 2014,2015,2016,2017,2018
|
./lib/dns/tests/gost_test.c C 2014,2015,2016,2017,2018
|
||||||
./lib/dns/tests/keytable_test.c C 2014,2015,2016,2017,2018
|
./lib/dns/tests/keytable_test.c C 2014,2015,2016,2017,2018
|
||||||
@@ -3479,6 +3480,7 @@
|
|||||||
./lib/isc/bind9.c C 2013,2016,2018
|
./lib/isc/bind9.c C 2013,2016,2018
|
||||||
./lib/isc/buffer.c C 1998,1999,2000,2001,2002,2004,2005,2006,2007,2008,2012,2014,2015,2016,2017,2018
|
./lib/isc/buffer.c C 1998,1999,2000,2001,2002,2004,2005,2006,2007,2008,2012,2014,2015,2016,2017,2018
|
||||||
./lib/isc/bufferlist.c C 1999,2000,2001,2004,2005,2007,2016,2018
|
./lib/isc/bufferlist.c C 1999,2000,2001,2004,2005,2007,2016,2018
|
||||||
|
./lib/isc/chacha_private.h X 2014,2018
|
||||||
./lib/isc/commandline.c C.PORTION 1999,2000,2001,2004,2005,2007,2008,2014,2015,2016,2018
|
./lib/isc/commandline.c C.PORTION 1999,2000,2001,2004,2005,2007,2008,2014,2015,2016,2018
|
||||||
./lib/isc/counter.c C 2014,2016,2018
|
./lib/isc/counter.c C 2014,2016,2018
|
||||||
./lib/isc/crc64.c C 2013,2016,2018
|
./lib/isc/crc64.c C 2013,2016,2018
|
||||||
@@ -3809,7 +3811,6 @@
|
|||||||
./lib/isc/win32/pk11_api.c C 2014,2016,2018
|
./lib/isc/win32/pk11_api.c C 2014,2016,2018
|
||||||
./lib/isc/win32/resource.c C 2000,2001,2004,2007,2008,2016,2018
|
./lib/isc/win32/resource.c C 2000,2001,2004,2007,2008,2016,2018
|
||||||
./lib/isc/win32/socket.c C 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018
|
./lib/isc/win32/socket.c C 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018
|
||||||
./lib/isc/win32/stdatomic.h C 2018
|
|
||||||
./lib/isc/win32/stdio.c C 2000,2001,2004,2007,2013,2016,2018
|
./lib/isc/win32/stdio.c C 2000,2001,2004,2007,2013,2016,2018
|
||||||
./lib/isc/win32/stdtime.c C 1999,2000,2001,2004,2007,2013,2016,2018
|
./lib/isc/win32/stdtime.c C 1999,2000,2001,2004,2007,2013,2016,2018
|
||||||
./lib/isc/win32/strerror.c C 2001,2002,2004,2007,2016,2018
|
./lib/isc/win32/strerror.c C 2001,2002,2004,2007,2016,2018
|
||||||
|
|||||||
@@ -229,6 +229,11 @@ my @substdefh = ("AES_CC",
|
|||||||
my %configdefp;
|
my %configdefp;
|
||||||
|
|
||||||
my @substdefp = ("ISC_PLATFORM_BUSYWAITNOP",
|
my @substdefp = ("ISC_PLATFORM_BUSYWAITNOP",
|
||||||
|
"ISC_PLATFORM_HAVEATOMICSTORE",
|
||||||
|
"ISC_PLATFORM_HAVEATOMICSTOREQ",
|
||||||
|
"ISC_PLATFORM_HAVECMPXCHG",
|
||||||
|
"ISC_PLATFORM_HAVEXADD",
|
||||||
|
"ISC_PLATFORM_HAVEXADDQ",
|
||||||
"ISC_PLATFORM_NEEDSTRCASESTR",
|
"ISC_PLATFORM_NEEDSTRCASESTR",
|
||||||
"ISC_PLATFORM_USEBACKTRACE",
|
"ISC_PLATFORM_USEBACKTRACE",
|
||||||
"ISC_PLATFORM_WANTAES");
|
"ISC_PLATFORM_WANTAES");
|
||||||
@@ -333,6 +338,7 @@ my @substdefd = ("CRYPTO",
|
|||||||
my %configcond;
|
my %configcond;
|
||||||
|
|
||||||
my @substcond = ("AES",
|
my @substcond = ("AES",
|
||||||
|
"ATOMIC",
|
||||||
"GSSAPI",
|
"GSSAPI",
|
||||||
"GEOIP",
|
"GEOIP",
|
||||||
"IDNKIT",
|
"IDNKIT",
|
||||||
@@ -1282,8 +1288,16 @@ EOF
|
|||||||
|
|
||||||
# enable-intrinsics
|
# enable-intrinsics
|
||||||
if ($enable_intrinsics eq "yes") {
|
if ($enable_intrinsics eq "yes") {
|
||||||
|
$configcond{"ATOMIC"} = 1;
|
||||||
$configvar{"INTRINSIC"} = "true";
|
$configvar{"INTRINSIC"} = "true";
|
||||||
$configvar{"COPTI"} = "/Oi";
|
$configvar{"COPTI"} = "/Oi";
|
||||||
|
$configdefp{"ISC_PLATFORM_HAVEXADD"} = 1;
|
||||||
|
if ($want_x64 eq "yes") {
|
||||||
|
$configdefp{"ISC_PLATFORM_HAVEXADDQ"} = 1;
|
||||||
|
$configdefp{"ISC_PLATFORM_HAVEATOMICSTOREQ"} = 1;
|
||||||
|
}
|
||||||
|
$configdefp{"ISC_PLATFORM_HAVEATOMICSTORE"} = 1;
|
||||||
|
$configdefp{"ISC_PLATFORM_HAVECMPXCHG"} = 1;
|
||||||
} else {
|
} else {
|
||||||
$configvar{"INTRINSIC"} = "false";
|
$configvar{"INTRINSIC"} = "false";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BINDInstall", "..\bin\win32
|
|||||||
{403FD4B1-A4F9-4159-9013-5860E3A4417D} = {403FD4B1-A4F9-4159-9013-5860E3A4417D}
|
{403FD4B1-A4F9-4159-9013-5860E3A4417D} = {403FD4B1-A4F9-4159-9013-5860E3A4417D}
|
||||||
@END PKCS11
|
@END PKCS11
|
||||||
@IF TESTS
|
@IF TESTS
|
||||||
|
@IF ATOMIC
|
||||||
|
{EC6ECB35-58C0-48EC-BAC9-9A652D9406C9} = {EC6ECB35-58C0-48EC-BAC9-9A652D9406C9}
|
||||||
|
@END ATOMIC
|
||||||
{E6338E67-3224-4E66-9463-7AD719DA9346} = {E6338E67-3224-4E66-9463-7AD719DA9346}
|
{E6338E67-3224-4E66-9463-7AD719DA9346} = {E6338E67-3224-4E66-9463-7AD719DA9346}
|
||||||
{EE9B94CF-7C33-4F3B-A674-FB756D422C54} = {EE9B94CF-7C33-4F3B-A674-FB756D422C54}
|
{EE9B94CF-7C33-4F3B-A674-FB756D422C54} = {EE9B94CF-7C33-4F3B-A674-FB756D422C54}
|
||||||
{5DC2F8D3-9373-41BB-B3AB-78F2E12F1E5E} = {5DC2F8D3-9373-41BB-B3AB-78F2E12F1E5E}
|
{5DC2F8D3-9373-41BB-B3AB-78F2E12F1E5E} = {5DC2F8D3-9373-41BB-B3AB-78F2E12F1E5E}
|
||||||
@@ -788,6 +791,12 @@ Global
|
|||||||
{403FD4B1-A4F9-4159-9013-5860E3A4417D}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@
|
{403FD4B1-A4F9-4159-9013-5860E3A4417D}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@
|
||||||
@END PKCS11
|
@END PKCS11
|
||||||
@IF TESTS
|
@IF TESTS
|
||||||
|
@IF ATOMIC
|
||||||
|
{EC6ECB35-58C0-48EC-BAC9-9A652D9406C9}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@
|
||||||
|
{EC6ECB35-58C0-48EC-BAC9-9A652D9406C9}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@
|
||||||
|
{EC6ECB35-58C0-48EC-BAC9-9A652D9406C9}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@
|
||||||
|
{EC6ECB35-58C0-48EC-BAC9-9A652D9406C9}.Release|@PLATFORM@.Build.0 = Release|@PLATFORM@
|
||||||
|
@END ATOMIC
|
||||||
{E6338E67-3224-4E66-9463-7AD719DA9346}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@
|
{E6338E67-3224-4E66-9463-7AD719DA9346}.Debug|@PLATFORM@.ActiveCfg = Debug|@PLATFORM@
|
||||||
{E6338E67-3224-4E66-9463-7AD719DA9346}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@
|
{E6338E67-3224-4E66-9463-7AD719DA9346}.Debug|@PLATFORM@.Build.0 = Debug|@PLATFORM@
|
||||||
{E6338E67-3224-4E66-9463-7AD719DA9346}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@
|
{E6338E67-3224-4E66-9463-7AD719DA9346}.Release|@PLATFORM@.ActiveCfg = Release|@PLATFORM@
|
||||||
|
|||||||
Reference in New Issue
Block a user