Compare commits
9 Commits
v9.15.7
...
wpk-isc_re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
074afd291b | ||
|
|
3a99a83517 | ||
|
|
7f602075bd | ||
|
|
75d60b04a8 | ||
|
|
0520dcafdb | ||
|
|
15e45ec5e0 | ||
|
|
d304f09f53 | ||
|
|
0ce7879b35 | ||
|
|
9ad2b15b13 |
@@ -480,6 +480,9 @@
|
||||
/* Define to allow building of objects for dlopen(). */
|
||||
#undef ISC_DLZ_DLOPEN
|
||||
|
||||
/* Define to emulate atomic variables with mutexes. */
|
||||
#undef ISC_MUTEX_ATOMICS
|
||||
|
||||
/* define if the linker supports --wrap option */
|
||||
#undef LD_WRAP
|
||||
|
||||
|
||||
54
configure
vendored
54
configure
vendored
@@ -850,6 +850,7 @@ infodir
|
||||
docdir
|
||||
oldincludedir
|
||||
includedir
|
||||
runstatedir
|
||||
localstatedir
|
||||
sharedstatedir
|
||||
sysconfdir
|
||||
@@ -897,6 +898,7 @@ enable_warn_shadow
|
||||
enable_warn_error
|
||||
enable_developer
|
||||
enable_fuzzing
|
||||
enable_mutex_atomics
|
||||
with_python
|
||||
with_python_install_dir
|
||||
enable_kqueue
|
||||
@@ -1018,6 +1020,7 @@ datadir='${datarootdir}'
|
||||
sysconfdir='${prefix}/etc'
|
||||
sharedstatedir='${prefix}/com'
|
||||
localstatedir='${prefix}/var'
|
||||
runstatedir='${localstatedir}/run'
|
||||
includedir='${prefix}/include'
|
||||
oldincludedir='/usr/include'
|
||||
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
|
||||
@@ -1270,6 +1273,15 @@ do
|
||||
| -silent | --silent | --silen | --sile | --sil)
|
||||
silent=yes ;;
|
||||
|
||||
-runstatedir | --runstatedir | --runstatedi | --runstated \
|
||||
| --runstate | --runstat | --runsta | --runst | --runs \
|
||||
| --run | --ru | --r)
|
||||
ac_prev=runstatedir ;;
|
||||
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
||||
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
||||
| --run=* | --ru=* | --r=*)
|
||||
runstatedir=$ac_optarg ;;
|
||||
|
||||
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
||||
ac_prev=sbindir ;;
|
||||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
||||
@@ -1407,7 +1419,7 @@ fi
|
||||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
||||
datadir sysconfdir sharedstatedir localstatedir includedir \
|
||||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
||||
libdir localedir mandir
|
||||
libdir localedir mandir runstatedir
|
||||
do
|
||||
eval ac_val=\$$ac_var
|
||||
# Remove trailing slashes.
|
||||
@@ -1560,6 +1572,7 @@ Fine tuning of the installation directories:
|
||||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||
--includedir=DIR C header files [PREFIX/include]
|
||||
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||
@@ -1611,6 +1624,8 @@ Optional Features:
|
||||
--enable-fuzzing=<afl|libfuzzer>
|
||||
Enable fuzzing using American Fuzzy Lop or libFuzzer
|
||||
(default=no)
|
||||
--enable-mutex-atomics emulate atomics by mutex-locked variables, useful
|
||||
for debugging [default=no]
|
||||
--enable-kqueue use BSD kqueue when available [default=yes]
|
||||
--enable-epoll use Linux epoll when available [default=auto]
|
||||
--enable-devpoll use /dev/poll when available [default=yes]
|
||||
@@ -3998,7 +4013,7 @@ else
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@@ -4044,7 +4059,7 @@ else
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@@ -4068,7 +4083,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@@ -4113,7 +4128,7 @@ else
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@@ -4137,7 +4152,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@@ -12314,6 +12329,33 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
|
||||
fi
|
||||
|
||||
# Check whether --enable-mutex_atomics was given.
|
||||
if test "${enable_mutex_atomics+set}" = set; then :
|
||||
enableval=$enable_mutex_atomics;
|
||||
else
|
||||
enable_mutex_atomics=no
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to emulate atomics with mutexes" >&5
|
||||
$as_echo_n "checking whether to emulate atomics with mutexes... " >&6; }
|
||||
case "$enable_mutex_atomics" in
|
||||
yes)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
|
||||
$as_echo "#define ISC_MUTEX_ATOMICS 1" >>confdefs.h
|
||||
|
||||
;;
|
||||
no)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
;;
|
||||
*)
|
||||
as_fn_error $? "\"--enable-mutex-atomics requires yes or no\"" "$LINENO" 5
|
||||
;;
|
||||
esac
|
||||
|
||||
#
|
||||
# Make very sure that these are the first files processed by
|
||||
# config.status, since we use the processed output as the input for
|
||||
|
||||
21
configure.ac
21
configure.ac
@@ -132,6 +132,27 @@ AS_IF([test "$enable_fuzzing" = "afl"],
|
||||
[AC_MSG_ERROR([set CC=afl-<gcc|clang> when --enable-fuzzing=afl is used])])
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE(mutex_atomics,
|
||||
AS_HELP_STRING([--enable-mutex-atomics],
|
||||
[emulate atomics by mutex-locked variables, useful for debugging
|
||||
[default=no]]),
|
||||
[],
|
||||
[enable_mutex_atomics=no])
|
||||
|
||||
AC_MSG_CHECKING([whether to emulate atomics with mutexes])
|
||||
case "$enable_mutex_atomics" in
|
||||
yes)
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(ISC_MUTEX_ATOMICS, 1, [Define to emulate atomic variables with mutexes.])
|
||||
;;
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR("--enable-mutex-atomics requires yes or no")
|
||||
;;
|
||||
esac
|
||||
|
||||
#
|
||||
# Make very sure that these are the first files processed by
|
||||
# config.status, since we use the processed output as the input for
|
||||
|
||||
@@ -174,7 +174,7 @@ struct dispsocket {
|
||||
*/
|
||||
struct dispportentry {
|
||||
in_port_t port;
|
||||
unsigned int refs;
|
||||
isc_refcount_t refs;
|
||||
ISC_LINK(struct dispportentry) link;
|
||||
};
|
||||
|
||||
@@ -578,7 +578,7 @@ new_portentry(dns_dispatch_t *disp, in_port_t port) {
|
||||
return (portentry);
|
||||
|
||||
portentry->port = port;
|
||||
portentry->refs = 1;
|
||||
isc_refcount_init(&portentry->refs, 1);
|
||||
ISC_LINK_INIT(portentry, link);
|
||||
qid = DNS_QID(disp);
|
||||
LOCK(&qid->lock);
|
||||
@@ -598,26 +598,25 @@ deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) {
|
||||
dns_qid_t *qid;
|
||||
|
||||
REQUIRE(disp->port_table != NULL);
|
||||
REQUIRE(portentry != NULL && portentry->refs > 0);
|
||||
REQUIRE(portentry != NULL && isc_refcount_current(&portentry->refs) > 0);
|
||||
|
||||
qid = DNS_QID(disp);
|
||||
LOCK(&qid->lock);
|
||||
portentry->refs--;
|
||||
|
||||
if (portentry->refs == 0) {
|
||||
if (isc_refcount_decrement(&portentry->refs) == 1) {
|
||||
qid = DNS_QID(disp);
|
||||
LOCK(&qid->lock);
|
||||
ISC_LIST_UNLINK(disp->port_table[portentry->port %
|
||||
DNS_DISPATCH_PORTTABLESIZE],
|
||||
portentry, link);
|
||||
isc_mempool_put(disp->portpool, portentry);
|
||||
UNLOCK(&qid->lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXXWPK TODO: is it really necessary?
|
||||
* Set '*portentryp' to NULL inside the lock so that
|
||||
* dispsock->portentry does not change in socket_search.
|
||||
*/
|
||||
*portentryp = NULL;
|
||||
|
||||
UNLOCK(&qid->lock);
|
||||
}
|
||||
|
||||
/*%
|
||||
@@ -736,9 +735,7 @@ get_dispsocket(dns_dispatch_t *disp, const isc_sockaddr_t *dest,
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
LOCK(&qid->lock);
|
||||
portentry->refs++;
|
||||
UNLOCK(&qid->lock);
|
||||
isc_refcount_increment(&portentry->refs);
|
||||
}
|
||||
break;
|
||||
} else if (result == ISC_R_NOPERM) {
|
||||
|
||||
@@ -310,7 +310,7 @@ typedef ISC_LIST(dns_rbtnode_t) rbtnodelist_t;
|
||||
(((header)->rdh_ttl > (now)) || \
|
||||
((header)->rdh_ttl == (now) && ZEROTTL(header)))
|
||||
|
||||
#define DEFAULT_NODE_LOCK_COUNT 7 /*%< Should be prime. */
|
||||
#define DEFAULT_NODE_LOCK_COUNT 31 /*%< Should be prime. */
|
||||
#define RBTDB_GLUE_TABLE_INIT_SIZE 2U
|
||||
|
||||
/*%
|
||||
@@ -330,7 +330,7 @@ typedef ISC_LIST(dns_rbtnode_t) rbtnodelist_t;
|
||||
#define DEFAULT_CACHE_NODE_LOCK_COUNT DNS_RBTDB_CACHE_NODE_LOCK_COUNT
|
||||
#endif
|
||||
#else
|
||||
#define DEFAULT_CACHE_NODE_LOCK_COUNT 16
|
||||
#define DEFAULT_CACHE_NODE_LOCK_COUNT 64
|
||||
#endif /* DNS_RBTDB_CACHE_NODE_LOCK_COUNT */
|
||||
|
||||
typedef struct {
|
||||
|
||||
40
lib/dns/zt.c
40
lib/dns/zt.c
@@ -45,9 +45,9 @@ struct dns_zt {
|
||||
dns_zt_allloaded_t loaddone;
|
||||
void * loaddone_arg;
|
||||
struct zt_load_params *loadparams;
|
||||
isc_refcount_t references;
|
||||
/* Locked by lock. */
|
||||
bool flush;
|
||||
uint32_t references;
|
||||
unsigned int loads_pending;
|
||||
dns_rbt_t *table;
|
||||
};
|
||||
@@ -93,7 +93,7 @@ dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp) {
|
||||
|
||||
zt->mctx = NULL;
|
||||
isc_mem_attach(mctx, &zt->mctx);
|
||||
zt->references = 1;
|
||||
isc_refcount_init(&zt->references, 1);
|
||||
zt->flush = false;
|
||||
zt->rdclass = rdclass;
|
||||
zt->magic = ZTMAGIC;
|
||||
@@ -209,13 +209,7 @@ dns_zt_attach(dns_zt_t *zt, dns_zt_t **ztp) {
|
||||
REQUIRE(VALID_ZT(zt));
|
||||
REQUIRE(ztp != NULL && *ztp == NULL);
|
||||
|
||||
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||
|
||||
INSIST(zt->references > 0);
|
||||
zt->references++;
|
||||
INSIST(zt->references != 0);
|
||||
|
||||
RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||
isc_refcount_increment(&zt->references);
|
||||
|
||||
*ztp = zt;
|
||||
}
|
||||
@@ -238,26 +232,17 @@ zt_destroy(dns_zt_t *zt) {
|
||||
|
||||
static void
|
||||
zt_flushanddetach(dns_zt_t **ztp, bool need_flush) {
|
||||
bool destroy = false;
|
||||
dns_zt_t *zt;
|
||||
|
||||
REQUIRE(ztp != NULL && VALID_ZT(*ztp));
|
||||
|
||||
zt = *ztp;
|
||||
|
||||
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||
|
||||
INSIST(zt->references > 0);
|
||||
zt->references--;
|
||||
if (zt->references == 0)
|
||||
destroy = true;
|
||||
if (need_flush)
|
||||
if (need_flush) {
|
||||
zt->flush = true;
|
||||
|
||||
RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||
|
||||
if (destroy)
|
||||
}
|
||||
if (isc_refcount_decrement(&zt->references) == 1) {
|
||||
zt_destroy(zt);
|
||||
}
|
||||
|
||||
*ztp = NULL;
|
||||
}
|
||||
@@ -340,15 +325,13 @@ asyncload(dns_zone_t *zone, void *zt_) {
|
||||
isc_result_t result;
|
||||
struct dns_zt *zt = (dns_zt_t*) zt_;
|
||||
REQUIRE(zone != NULL);
|
||||
INSIST(zt->references > 0);
|
||||
zt->references++;
|
||||
INSIST(isc_refcount_increment(&zt->references) > 0);
|
||||
zt->loads_pending++;
|
||||
|
||||
result = dns_zone_asyncload(zone, zt->loadparams->newonly, *zt->loadparams->dl, zt);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
zt->references--;
|
||||
INSIST(isc_refcount_decrement(&zt->references) > 1);
|
||||
zt->loads_pending--;
|
||||
INSIST(zt->references > 0);
|
||||
}
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
@@ -548,10 +531,9 @@ doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) {
|
||||
|
||||
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||
INSIST(zt->loads_pending != 0);
|
||||
INSIST(zt->references != 0);
|
||||
zt->references--;
|
||||
if (zt->references == 0)
|
||||
if (isc_refcount_decrement(&zt->references) == 1) {
|
||||
destroy = true;
|
||||
}
|
||||
zt->loads_pending--;
|
||||
if (zt->loads_pending == 0) {
|
||||
alldone = zt->loaddone;
|
||||
|
||||
@@ -44,9 +44,9 @@ isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp) {
|
||||
counter->mctx = NULL;
|
||||
isc_mem_attach(mctx, &counter->mctx);
|
||||
|
||||
atomic_store(&counter->references, 1);
|
||||
atomic_store(&counter->limit, limit);
|
||||
atomic_store(&counter->used, 0);
|
||||
atomic_init(&counter->references, 1);
|
||||
atomic_init(&counter->limit, limit);
|
||||
atomic_init(&counter->used, 0);
|
||||
|
||||
counter->magic = COUNTER_MAGIC;
|
||||
*counterp = counter;
|
||||
|
||||
@@ -11,11 +11,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef ISC_MUTEX_ATOMICS
|
||||
#include <isc/mutexatomic.h>
|
||||
#else
|
||||
#if HAVE_STDATOMIC_H
|
||||
#include <stdatomic.h>
|
||||
#else
|
||||
#include <isc/stdatomic.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We define a few additional macros to make things easier
|
||||
|
||||
132
lib/isc/include/isc/mutexatomic.h
Normal file
132
lib/isc/include/isc/mutexatomic.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <isc/mutex.h>
|
||||
|
||||
#if !defined(__has_feature)
|
||||
#define __has_feature(x) 0
|
||||
#endif
|
||||
|
||||
#if !defined(__has_extension)
|
||||
#define __has_extension(x) __has_feature(x)
|
||||
#endif
|
||||
|
||||
#if !defined(__GNUC_PREREQ__)
|
||||
#if defined(__GNUC__) && defined(__GNUC_MINOR__)
|
||||
#define __GNUC_PREREQ__(maj, min) \
|
||||
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
|
||||
#else
|
||||
#define __GNUC_PREREQ__(maj, min) 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(__CLANG_ATOMICS) && !defined(__GNUC_ATOMICS)
|
||||
#if __has_extension(c_atomic) || __has_extension(cxx_atomic)
|
||||
#define __CLANG_ATOMICS
|
||||
#elif __GNUC_PREREQ__(4, 7)
|
||||
#define __GNUC_ATOMICS
|
||||
#elif !defined(__GNUC__)
|
||||
#error "isc/stdatomic.h does not support your compiler"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __ATOMIC_RELAXED
|
||||
#define __ATOMIC_RELAXED 0
|
||||
#endif
|
||||
#ifndef __ATOMIC_CONSUME
|
||||
#define __ATOMIC_CONSUME 1
|
||||
#endif
|
||||
#ifndef __ATOMIC_ACQUIRE
|
||||
#define __ATOMIC_ACQUIRE 2
|
||||
#endif
|
||||
#ifndef __ATOMIC_RELEASE
|
||||
#define __ATOMIC_RELEASE 3
|
||||
#endif
|
||||
#ifndef __ATOMIC_ACQ_REL
|
||||
#define __ATOMIC_ACQ_REL 4
|
||||
#endif
|
||||
#ifndef __ATOMIC_SEQ_CST
|
||||
#define __ATOMIC_SEQ_CST 5
|
||||
#endif
|
||||
|
||||
|
||||
enum memory_order {
|
||||
memory_order_relaxed = __ATOMIC_RELAXED,
|
||||
memory_order_consume = __ATOMIC_CONSUME,
|
||||
memory_order_acquire = __ATOMIC_ACQUIRE,
|
||||
memory_order_release = __ATOMIC_RELEASE,
|
||||
memory_order_acq_rel = __ATOMIC_ACQ_REL,
|
||||
memory_order_seq_cst = __ATOMIC_SEQ_CST
|
||||
};
|
||||
|
||||
typedef enum memory_order memory_order;
|
||||
|
||||
typedef struct atomic_int_fast32 {
|
||||
isc_mutex_t m;
|
||||
int32_t v;
|
||||
} atomic_int_fast32_t;
|
||||
|
||||
typedef struct atomic_int_fast64 {
|
||||
isc_mutex_t m;
|
||||
int64_t v;
|
||||
} atomic_int_fast64_t;
|
||||
|
||||
typedef struct atomic_uint_fast32 {
|
||||
isc_mutex_t m;
|
||||
uint32_t v;
|
||||
} atomic_uint_fast32_t;
|
||||
|
||||
typedef struct atomic_uint_fast64 {
|
||||
isc_mutex_t m;
|
||||
uint64_t v;
|
||||
} atomic_uint_fast64_t;
|
||||
|
||||
|
||||
typedef struct atomic_bool_s {
|
||||
isc_mutex_t m;
|
||||
bool v;
|
||||
} atomic_bool;
|
||||
|
||||
|
||||
#define atomic_init(obj, desired) \
|
||||
{ isc_mutex_init(&(obj)->m); isc_mutex_lock(&(obj)->m); (obj)->v = desired; isc_mutex_unlock(&(obj)->m); }
|
||||
#define atomic_load_explicit(obj, order) \
|
||||
({ typeof((obj)->v) __v; isc_mutex_lock(&(obj)->m); __v= (obj)->v; isc_mutex_unlock(&(obj)->m); __v;} )
|
||||
#define atomic_store_explicit(obj, desired, order) \
|
||||
{isc_mutex_lock(&(obj)->m); (obj)->v = desired; isc_mutex_unlock(&(obj)->m); }
|
||||
#define atomic_fetch_add_explicit(obj, arg, order) \
|
||||
({ typeof((obj)->v) __v; isc_mutex_lock(&(obj)->m); __v= (obj)->v; (obj)->v += arg; isc_mutex_unlock(&(obj)->m); __v;} )
|
||||
#define atomic_fetch_sub_explicit(obj, arg, order) \
|
||||
({ typeof((obj)->v) __v; isc_mutex_lock(&(obj)->m); __v= (obj)->v; (obj)->v -= arg; isc_mutex_unlock(&(obj)->m); __v;} )
|
||||
#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) \
|
||||
({ bool __v; isc_mutex_lock(&(obj)->m); __v = ((obj)->v == *expected); *expected = (obj)->v; (obj)->v = __v ? desired : (obj)->v; isc_mutex_unlock(&(obj)->m); __v;} )
|
||||
#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) \
|
||||
({ bool __v; isc_mutex_lock(&(obj)->m); __v = ((obj)->v == *expected); *expected = (obj)->v; (obj)->v = __v ? desired : (obj)->v; isc_mutex_unlock(&(obj)->m); __v;} )
|
||||
|
||||
|
||||
|
||||
|
||||
#define atomic_load(obj) \
|
||||
atomic_load_explicit(obj, memory_order_seq_cst)
|
||||
#define atomic_store(obj, arg) \
|
||||
atomic_store_explicit(obj, arg, memory_order_seq_cst)
|
||||
#define atomic_fetch_add(obj, arg) \
|
||||
atomic_fetch_add_explicit(obj, arg, memory_order_seq_cst)
|
||||
#define atomic_fetch_sub(obj, arg) \
|
||||
atomic_fetch_sub_explicit(obj, arg, memory_order_seq_cst)
|
||||
#define atomic_compare_exchange_strong(obj, expected, desired) \
|
||||
atomic_compare_exchange_strong_explicit(obj, expected, desired, memory_order_seq_cst, memory_order_seq_cst)
|
||||
#define atomic_compare_exchange_weak(obj, expected, desired) \
|
||||
atomic_compare_exchange_weak_explicit(obj, expected, desired, memory_order_seq_cst, memory_order_seq_cst)
|
||||
@@ -45,13 +45,16 @@ struct isc_stats {
|
||||
static isc_result_t
|
||||
create_stats(isc_mem_t *mctx, int ncounters, isc_stats_t **statsp) {
|
||||
isc_stats_t *stats;
|
||||
int i;
|
||||
|
||||
REQUIRE(statsp != NULL && *statsp == NULL);
|
||||
|
||||
stats = isc_mem_get(mctx, sizeof(*stats));
|
||||
stats->counters = isc_mem_get(mctx, sizeof(isc_stat_t) * ncounters);
|
||||
isc_refcount_init(&stats->refs, 1);
|
||||
memset(stats->counters, 0, sizeof(isc_stat_t) * ncounters);
|
||||
for (i = 0; i < ncounters; i++) {
|
||||
atomic_init(&stats->counters[i], 0);
|
||||
}
|
||||
stats->mctx = NULL;
|
||||
isc_mem_attach(mctx, &stats->mctx);
|
||||
stats->ncounters = ncounters;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <isc/print.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/random.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/thread.h>
|
||||
#include <isc/time.h>
|
||||
@@ -99,9 +100,9 @@ struct isc__task {
|
||||
isc_task_t common;
|
||||
isc__taskmgr_t * manager;
|
||||
isc_mutex_t lock;
|
||||
isc_refcount_t references;
|
||||
/* Locked by task lock. */
|
||||
task_state_t state;
|
||||
unsigned int references;
|
||||
isc_eventlist_t events;
|
||||
isc_eventlist_t on_shutdown;
|
||||
unsigned int nevents;
|
||||
@@ -228,7 +229,7 @@ task_finished(isc__task_t *task) {
|
||||
REQUIRE(EMPTY(task->events));
|
||||
REQUIRE(task->nevents == 0);
|
||||
REQUIRE(EMPTY(task->on_shutdown));
|
||||
REQUIRE(task->references == 0);
|
||||
REQUIRE(isc_refcount_current(&task->references) == 0);
|
||||
REQUIRE(task->state == task_state_done);
|
||||
|
||||
XTRACE("task_finished");
|
||||
@@ -295,7 +296,7 @@ isc_task_create_bound(isc_taskmgr_t *manager0, unsigned int quantum,
|
||||
|
||||
isc_mutex_init(&task->lock);
|
||||
task->state = task_state_idle;
|
||||
task->references = 1;
|
||||
isc_refcount_init(&task->references, 1);
|
||||
INIT_LIST(task->events);
|
||||
INIT_LIST(task->on_shutdown);
|
||||
task->nevents = 0;
|
||||
@@ -345,9 +346,7 @@ isc_task_attach(isc_task_t *source0, isc_task_t **targetp) {
|
||||
|
||||
XTTRACE(source, "isc_task_attach");
|
||||
|
||||
LOCK(&source->lock);
|
||||
source->references++;
|
||||
UNLOCK(&source->lock);
|
||||
isc_refcount_increment(&source->references);
|
||||
|
||||
*targetp = (isc_task_t *)source;
|
||||
}
|
||||
@@ -420,12 +419,12 @@ task_detach(isc__task_t *task) {
|
||||
* Caller must be holding the task lock.
|
||||
*/
|
||||
|
||||
REQUIRE(task->references > 0);
|
||||
REQUIRE(isc_refcount_current(&task->references) > 0);
|
||||
|
||||
XTRACE("detach");
|
||||
|
||||
task->references--;
|
||||
if (task->references == 0 && task->state == task_state_idle) {
|
||||
if (isc_refcount_decrement(&task->references) == 1 &&
|
||||
task->state == task_state_idle) {
|
||||
INSIST(EMPTY(task->events));
|
||||
/*
|
||||
* There are no references to this task, and no
|
||||
@@ -1140,7 +1139,7 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) {
|
||||
dispatch_count++;
|
||||
}
|
||||
|
||||
if (task->references == 0 &&
|
||||
if (isc_refcount_current(&task->references) == 0 &&
|
||||
EMPTY(task->events) &&
|
||||
!TASK_SHUTTINGDOWN(task)) {
|
||||
bool was_idle;
|
||||
@@ -1177,7 +1176,7 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) {
|
||||
* right now.
|
||||
*/
|
||||
XTRACE("empty");
|
||||
if (task->references == 0 &&
|
||||
if (isc_refcount_current(&task->references) == 0 &&
|
||||
TASK_SHUTTINGDOWN(task)) {
|
||||
/*
|
||||
* The task is done.
|
||||
@@ -1244,7 +1243,7 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) {
|
||||
* we're stuck. Automatically drop privileges at that
|
||||
* point and continue with the regular ready queue.
|
||||
*/
|
||||
if (manager->mode != isc_taskmgrmode_normal &&
|
||||
if (atomic_load_relaxed(&manager->mode) != isc_taskmgrmode_normal &&
|
||||
atomic_load_explicit(&manager->tasks_running,
|
||||
memory_order_acquire) == 0)
|
||||
{
|
||||
@@ -1257,7 +1256,7 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) {
|
||||
* we'll end up in a deadlock over queue locks.
|
||||
*
|
||||
*/
|
||||
if (manager->mode != isc_taskmgrmode_normal &&
|
||||
if (atomic_load_relaxed(&manager->mode) != isc_taskmgrmode_normal &&
|
||||
atomic_load_explicit(&manager->tasks_running,
|
||||
memory_order_acquire) == 0)
|
||||
{
|
||||
@@ -1342,7 +1341,7 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
|
||||
RUNTIME_CHECK(manager != NULL);
|
||||
manager->common.impmagic = TASK_MANAGER_MAGIC;
|
||||
manager->common.magic = ISCAPI_TASKMGR_MAGIC;
|
||||
atomic_store(&manager->mode, isc_taskmgrmode_normal);
|
||||
atomic_init(&manager->mode, isc_taskmgrmode_normal);
|
||||
manager->mctx = NULL;
|
||||
isc_mutex_init(&manager->lock);
|
||||
isc_mutex_init(&manager->excl_lock);
|
||||
@@ -1357,18 +1356,18 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
|
||||
}
|
||||
manager->default_quantum = default_quantum;
|
||||
INIT_LIST(manager->tasks);
|
||||
atomic_store(&manager->tasks_count, 0);
|
||||
atomic_init(&manager->tasks_count, 0);
|
||||
manager->queues = isc_mem_get(mctx, workers * sizeof(isc__taskqueue_t));
|
||||
RUNTIME_CHECK(manager->queues != NULL);
|
||||
|
||||
manager->tasks_running = 0;
|
||||
manager->tasks_ready = 0;
|
||||
manager->curq = 0;
|
||||
manager->exiting = false;
|
||||
atomic_init(&manager->tasks_running, 0);
|
||||
atomic_init(&manager->tasks_ready, 0);
|
||||
atomic_init(&manager->curq, 0);
|
||||
atomic_init(&manager->exiting, false);
|
||||
manager->excl = NULL;
|
||||
manager->halted = 0;
|
||||
atomic_store_relaxed(&manager->exclusive_req, false);
|
||||
atomic_store_relaxed(&manager->pause_req, false);
|
||||
atomic_init(&manager->exclusive_req, false);
|
||||
atomic_init(&manager->pause_req, false);
|
||||
|
||||
isc_mem_attach(mctx, &manager->mctx);
|
||||
|
||||
@@ -1530,8 +1529,8 @@ void
|
||||
isc__taskmgr_resume(isc_taskmgr_t *manager0) {
|
||||
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
|
||||
LOCK(&manager->halt_lock);
|
||||
if (manager->pause_req) {
|
||||
manager->pause_req = false;
|
||||
if (atomic_load_relaxed(&manager->pause_req)) {
|
||||
atomic_store_relaxed(&manager->pause_req, false);
|
||||
while (manager->halted > 0) {
|
||||
BROADCAST(&manager->halt_cond);
|
||||
WAIT(&manager->halt_cond, &manager->halt_lock);
|
||||
@@ -1732,8 +1731,8 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, void *writer0) {
|
||||
|
||||
TRY0(xmlTextWriterStartElement(writer,
|
||||
ISC_XMLCHAR "references"));
|
||||
TRY0(xmlTextWriterWriteFormatString(writer, "%d",
|
||||
task->references));
|
||||
TRY0(xmlTextWriterWriteFormatString(writer, "%lu",
|
||||
isc_refcount_current(&task->references)));
|
||||
TRY0(xmlTextWriterEndElement(writer)); /* references */
|
||||
|
||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id"));
|
||||
@@ -1843,7 +1842,7 @@ isc_taskmgr_renderjson(isc_taskmgr_t *mgr0, void *tasks0) {
|
||||
json_object_object_add(taskobj, "name", obj);
|
||||
}
|
||||
|
||||
obj = json_object_new_int(task->references);
|
||||
obj = json_object_new_int(isc_refcount_current(&task->references));
|
||||
CHECKMEM(obj);
|
||||
json_object_object_add(taskobj, "references", obj);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <isc/once.h>
|
||||
#include <isc/platform.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/thread.h>
|
||||
#include <isc/time.h>
|
||||
@@ -61,8 +62,8 @@ struct isc__timer {
|
||||
isc_timer_t common;
|
||||
isc__timermgr_t * manager;
|
||||
isc_mutex_t lock;
|
||||
isc_refcount_t references;
|
||||
/*! Locked by timer lock. */
|
||||
unsigned int references;
|
||||
isc_time_t idle;
|
||||
/*! Locked by manager lock. */
|
||||
isc_timertype_t type;
|
||||
@@ -284,7 +285,7 @@ isc_timer_create(isc_timermgr_t *manager0, isc_timertype_t type,
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
||||
timer->manager = manager;
|
||||
timer->references = 1;
|
||||
isc_refcount_init(&timer->references, 1);
|
||||
|
||||
if (type == isc_timertype_once && !isc_interval_iszero(interval)) {
|
||||
result = isc_time_add(&now, interval, &timer->idle);
|
||||
@@ -479,10 +480,7 @@ isc_timer_attach(isc_timer_t *timer0, isc_timer_t **timerp) {
|
||||
|
||||
REQUIRE(VALID_TIMER(timer));
|
||||
REQUIRE(timerp != NULL && *timerp == NULL);
|
||||
|
||||
LOCK(&timer->lock);
|
||||
timer->references++;
|
||||
UNLOCK(&timer->lock);
|
||||
isc_refcount_increment(&timer->references);
|
||||
|
||||
*timerp = (isc_timer_t *)timer;
|
||||
}
|
||||
@@ -490,8 +488,6 @@ isc_timer_attach(isc_timer_t *timer0, isc_timer_t **timerp) {
|
||||
void
|
||||
isc_timer_detach(isc_timer_t **timerp) {
|
||||
isc__timer_t *timer;
|
||||
bool free_timer = false;
|
||||
|
||||
/*
|
||||
* Detach *timerp from its timer.
|
||||
*/
|
||||
@@ -500,15 +496,9 @@ isc_timer_detach(isc_timer_t **timerp) {
|
||||
timer = (isc__timer_t *)*timerp;
|
||||
REQUIRE(VALID_TIMER(timer));
|
||||
|
||||
LOCK(&timer->lock);
|
||||
REQUIRE(timer->references > 0);
|
||||
timer->references--;
|
||||
if (timer->references == 0)
|
||||
free_timer = true;
|
||||
UNLOCK(&timer->lock);
|
||||
|
||||
if (free_timer)
|
||||
if (isc_refcount_decrement(&timer->references) == 1) {
|
||||
destroy(timer);
|
||||
}
|
||||
|
||||
*timerp = NULL;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ struct ns_interface {
|
||||
unsigned int magic; /*%< Magic number. */
|
||||
ns_interfacemgr_t * mgr; /*%< Interface manager. */
|
||||
isc_mutex_t lock;
|
||||
int references; /*%< Locked */
|
||||
isc_refcount_t references;
|
||||
unsigned int generation; /*%< Generation number. */
|
||||
isc_sockaddr_t addr; /*%< Address and port. */
|
||||
unsigned int flags; /*%< Interface characteristics */
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
/*% nameserver interface manager structure */
|
||||
struct ns_interfacemgr {
|
||||
unsigned int magic; /*%< Magic number. */
|
||||
int references;
|
||||
isc_refcount_t references;
|
||||
isc_mutex_t lock;
|
||||
isc_mem_t * mctx; /*%< Memory context. */
|
||||
ns_server_t * sctx; /*%< Server context. */
|
||||
@@ -253,9 +253,9 @@ ns_interfacemgr_create(isc_mem_t *mctx,
|
||||
mgr->task = NULL;
|
||||
if (mgr->route != NULL)
|
||||
isc_task_attach(task, &mgr->task);
|
||||
mgr->references = (mgr->route != NULL) ? 2 : 1;
|
||||
isc_refcount_init(&mgr->references, (mgr->route != NULL) ? 2 : 1);
|
||||
#else
|
||||
mgr->references = 1;
|
||||
isc_refcount_init(&mgr->references, 1);
|
||||
#endif
|
||||
mgr->magic = IFMGR_MAGIC;
|
||||
*mgrp = mgr;
|
||||
@@ -332,27 +332,18 @@ ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr) {
|
||||
void
|
||||
ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target) {
|
||||
REQUIRE(NS_INTERFACEMGR_VALID(source));
|
||||
LOCK(&source->lock);
|
||||
INSIST(source->references > 0);
|
||||
source->references++;
|
||||
UNLOCK(&source->lock);
|
||||
INSIST(isc_refcount_increment(&source->references) > 0);
|
||||
*target = source;
|
||||
}
|
||||
|
||||
void
|
||||
ns_interfacemgr_detach(ns_interfacemgr_t **targetp) {
|
||||
isc_result_t need_destroy = false;
|
||||
ns_interfacemgr_t *target = *targetp;
|
||||
REQUIRE(target != NULL);
|
||||
REQUIRE(NS_INTERFACEMGR_VALID(target));
|
||||
LOCK(&target->lock);
|
||||
REQUIRE(target->references > 0);
|
||||
target->references--;
|
||||
if (target->references == 0)
|
||||
need_destroy = true;
|
||||
UNLOCK(&target->lock);
|
||||
if (need_destroy)
|
||||
if (isc_refcount_decrement(&target->references) == 1) {
|
||||
ns_interfacemgr_destroy(target);
|
||||
}
|
||||
*targetp = NULL;
|
||||
}
|
||||
|
||||
@@ -435,7 +426,7 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
|
||||
ns_interfacemgr_attach(mgr, &ifp->mgr);
|
||||
ISC_LIST_APPEND(mgr->interfaces, ifp, link);
|
||||
|
||||
ifp->references = 1;
|
||||
isc_refcount_init(&ifp->references, 1);
|
||||
ifp->magic = IFACE_MAGIC;
|
||||
*ifpret = ifp;
|
||||
|
||||
@@ -667,27 +658,18 @@ ns_interface_destroy(ns_interface_t *ifp) {
|
||||
void
|
||||
ns_interface_attach(ns_interface_t *source, ns_interface_t **target) {
|
||||
REQUIRE(NS_INTERFACE_VALID(source));
|
||||
LOCK(&source->lock);
|
||||
INSIST(source->references > 0);
|
||||
source->references++;
|
||||
UNLOCK(&source->lock);
|
||||
isc_refcount_increment(&source->references);
|
||||
*target = source;
|
||||
}
|
||||
|
||||
void
|
||||
ns_interface_detach(ns_interface_t **targetp) {
|
||||
isc_result_t need_destroy = false;
|
||||
ns_interface_t *target = *targetp;
|
||||
REQUIRE(target != NULL);
|
||||
REQUIRE(NS_INTERFACE_VALID(target));
|
||||
LOCK(&target->lock);
|
||||
REQUIRE(target->references > 0);
|
||||
target->references--;
|
||||
if (target->references == 0)
|
||||
need_destroy = true;
|
||||
UNLOCK(&target->lock);
|
||||
if (need_destroy)
|
||||
if (isc_refcount_decrement(&target->references) == 1) {
|
||||
ns_interface_destroy(target);
|
||||
}
|
||||
*targetp = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <isc/string.h>
|
||||
#include <isc/thread.h>
|
||||
#include <isc/util.h>
|
||||
#include <isc/once.h>
|
||||
|
||||
#include <dns/adb.h>
|
||||
#include <dns/badcache.h>
|
||||
@@ -5738,7 +5739,12 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
|
||||
}
|
||||
|
||||
if (result == ISC_R_SOFTQUOTA) {
|
||||
static atomic_uint_fast32_t last = 0;
|
||||
static atomic_uint_fast32_t last;
|
||||
static isc_once_t once = ISC_ONCE_INIT;
|
||||
void __ain() {
|
||||
atomic_init(&last, 0);
|
||||
}
|
||||
isc_once_do(&once, __ain);
|
||||
isc_stdtime_t now;
|
||||
isc_stdtime_get(&now);
|
||||
if (now != atomic_load_relaxed(&last)) {
|
||||
@@ -5755,7 +5761,12 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
|
||||
ns_client_killoldestquery(client);
|
||||
result = ISC_R_SUCCESS;
|
||||
} else if (result == ISC_R_QUOTA) {
|
||||
static atomic_uint_fast32_t last = 0;
|
||||
static atomic_uint_fast32_t last;
|
||||
static isc_once_t once = ISC_ONCE_INIT;
|
||||
void __ain() {
|
||||
atomic_init(&last, 0);
|
||||
}
|
||||
isc_once_do(&once, __ain);
|
||||
isc_stdtime_t now;
|
||||
isc_stdtime_get(&now);
|
||||
if (now != atomic_load_relaxed(&last)) {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <isc/magic.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/stats.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
@@ -22,14 +23,10 @@
|
||||
#define NS_STATS_VALID(x) ISC_MAGIC_VALID(x, NS_STATS_MAGIC)
|
||||
|
||||
struct ns_stats {
|
||||
/*% Unlocked */
|
||||
unsigned int magic;
|
||||
isc_mem_t *mctx;
|
||||
isc_mutex_t lock;
|
||||
isc_stats_t *counters;
|
||||
|
||||
/*% Locked by lock */
|
||||
unsigned int references;
|
||||
isc_refcount_t references;
|
||||
};
|
||||
|
||||
void
|
||||
@@ -37,9 +34,7 @@ ns_stats_attach(ns_stats_t *stats, ns_stats_t **statsp) {
|
||||
REQUIRE(NS_STATS_VALID(stats));
|
||||
REQUIRE(statsp != NULL && *statsp == NULL);
|
||||
|
||||
LOCK(&stats->lock);
|
||||
stats->references++;
|
||||
UNLOCK(&stats->lock);
|
||||
isc_refcount_increment(&stats->references);
|
||||
|
||||
*statsp = stats;
|
||||
}
|
||||
@@ -53,13 +48,8 @@ ns_stats_detach(ns_stats_t **statsp) {
|
||||
stats = *statsp;
|
||||
*statsp = NULL;
|
||||
|
||||
LOCK(&stats->lock);
|
||||
stats->references--;
|
||||
UNLOCK(&stats->lock);
|
||||
|
||||
if (stats->references == 0) {
|
||||
if (isc_refcount_decrement(&stats->references) == 1) {
|
||||
isc_stats_detach(&stats->counters);
|
||||
isc_mutex_destroy(&stats->lock);
|
||||
isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats));
|
||||
}
|
||||
}
|
||||
@@ -76,9 +66,7 @@ ns_stats_create(isc_mem_t *mctx, int ncounters, ns_stats_t **statsp) {
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
||||
stats->counters = NULL;
|
||||
stats->references = 1;
|
||||
|
||||
isc_mutex_init(&stats->lock);
|
||||
atomic_init(&stats->references, 1);
|
||||
|
||||
result = isc_stats_create(mctx, &stats->counters, ncounters);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
@@ -92,7 +80,6 @@ ns_stats_create(isc_mem_t *mctx, int ncounters, ns_stats_t **statsp) {
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
clean_mutex:
|
||||
isc_mutex_destroy(&stats->lock);
|
||||
isc_mem_put(mctx, stats, sizeof(*stats));
|
||||
|
||||
return (result);
|
||||
|
||||
Reference in New Issue
Block a user