Compare commits
17 Commits
pspacek/hy
...
3054-exter
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6851e95ae | ||
|
|
893ad49799 | ||
|
|
df3f934e81 | ||
|
|
26769079fb | ||
|
|
3e180d7b9f | ||
|
|
5384028166 | ||
|
|
19a16de33c | ||
|
|
e287a9dd60 | ||
|
|
abb1ec7b76 | ||
|
|
29da36aaaa | ||
|
|
dca6f818af | ||
|
|
03a5957ddb | ||
|
|
02de040db1 | ||
|
|
533f507bb0 | ||
|
|
79c86d08ff | ||
|
|
bcf48747e0 | ||
|
|
31e9f6f0d3 |
@@ -984,6 +984,32 @@ unit:clang:asan:
|
||||
- job: clang:asan
|
||||
artifacts: true
|
||||
|
||||
# Jobs to track pthread init/destroy Debian 10 "buster" (amd64)
|
||||
|
||||
gcc:pthread-track:
|
||||
variables:
|
||||
CC: gcc
|
||||
CFLAGS: "${CFLAGS_COMMON} -DISC_TRACK_PTHREADS_OBJECTS"
|
||||
EXTRA_CONFIGURE: "--with-libidn2 --enable-pthread-rwlock --without-jemalloc"
|
||||
<<: *fedora_34_amd64_image
|
||||
<<: *build_job
|
||||
|
||||
system:gcc:pthread-track:
|
||||
variables:
|
||||
<<: *fedora_34_amd64_image
|
||||
<<: *system_test_job
|
||||
needs:
|
||||
- job: gcc:pthread-track
|
||||
artifacts: true
|
||||
|
||||
unit:gcc:pthread-track:
|
||||
variables:
|
||||
<<: *fedora_34_amd64_image
|
||||
<<: *unit_test_job
|
||||
needs:
|
||||
- job: gcc:pthread-track
|
||||
artifacts: true
|
||||
|
||||
# Jobs for TSAN builds on Debian 10 "buster" (amd64)
|
||||
|
||||
gcc:tsan:
|
||||
|
||||
@@ -1082,6 +1082,7 @@ main(int argc, char **argv) {
|
||||
fatal("isc_app_run() failed: %s", isc_result_totext(result));
|
||||
}
|
||||
|
||||
isc_app_finish();
|
||||
isc_task_detach(&rndc_task);
|
||||
isc_managers_destroy(&netmgr, &taskmgr, NULL);
|
||||
|
||||
|
||||
@@ -253,7 +253,7 @@ sub pid_file_exists {
|
||||
if (send_signal(0, $pid) == 0) {
|
||||
# XXX: on windows this is likely to result in a
|
||||
# false positive, so don't bother reporting the error.
|
||||
if (!defined($ENV{'CYGWIN'})) {
|
||||
if (!defined($ENV{'CYGWIN'}) || $ENV{'CYGWIN'} eq "") {
|
||||
print "I:$test:$server crashed on shutdown\n";
|
||||
$errors = 1;
|
||||
}
|
||||
|
||||
@@ -563,6 +563,16 @@ initialize_action(void) {
|
||||
isc_mutex_init(&insecure_prefix_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup_insecure_prefix_lock(void) ISC_DESTRUCTOR;
|
||||
|
||||
static void
|
||||
cleanup_insecure_prefix_lock(void) {
|
||||
RUNTIME_CHECK(isc_once_do(&insecure_prefix_once, initialize_action) ==
|
||||
ISC_R_SUCCESS);
|
||||
isc_mutex_destroy(&insecure_prefix_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called via isc_radix_process() to find IP table nodes that are
|
||||
* insecure.
|
||||
|
||||
@@ -1104,3 +1104,12 @@ dns_db_setgluecachestats(dns_db_t *db, isc_stats_t *stats) {
|
||||
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
|
||||
static void
|
||||
dns_db_destroyimplock(void) ISC_DESTRUCTOR;
|
||||
|
||||
static void
|
||||
dns_db_destroyimplock(void) {
|
||||
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
|
||||
isc_rwlock_destroy(&implock);
|
||||
}
|
||||
|
||||
@@ -532,3 +532,12 @@ dns_dlz_ssumatch(dns_dlzdb_t *dlzdatabase, const dns_name_t *signer,
|
||||
impl->driverarg, dlzdatabase->dbdata);
|
||||
return (r);
|
||||
}
|
||||
|
||||
static void
|
||||
dns_dlz_destroyimplock(void) ISC_DESTRUCTOR;
|
||||
|
||||
static void
|
||||
dns_dlz_destroyimplock(void) {
|
||||
RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS);
|
||||
isc_rwlock_destroy(&dlz_implock);
|
||||
}
|
||||
|
||||
@@ -504,6 +504,8 @@ destroy(dns_dtenv_t *env) {
|
||||
isc_stats_detach(&env->stats);
|
||||
}
|
||||
|
||||
isc_mutex_destroy(&env->reopen_lock);
|
||||
|
||||
isc_mem_putanddetach(&env->mctx, env, sizeof(*env));
|
||||
}
|
||||
|
||||
|
||||
@@ -34,12 +34,22 @@
|
||||
#define RRTYPE_WKS_ATTRIBUTES (0)
|
||||
|
||||
static isc_mutex_t wks_lock;
|
||||
static isc_once_t wks_once = ISC_ONCE_INIT;
|
||||
|
||||
static void
|
||||
init_lock(void) {
|
||||
isc_mutex_init(&wks_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup_wks_lock(void) ISC_DESTRUCTOR;
|
||||
|
||||
static void
|
||||
cleanup_wks_lock(void) {
|
||||
RUNTIME_CHECK(isc_once_do(&wks_once, init_lock) == ISC_R_SUCCESS);
|
||||
isc_mutex_destroy(&wks_lock);
|
||||
}
|
||||
|
||||
static bool
|
||||
mygetprotobyname(const char *name, long *proto) {
|
||||
struct protoent *pe;
|
||||
@@ -68,7 +78,6 @@ mygetservbyname(const char *name, const char *proto, long *port) {
|
||||
|
||||
static inline isc_result_t
|
||||
fromtext_in_wks(ARGS_FROMTEXT) {
|
||||
static isc_once_t once = ISC_ONCE_INIT;
|
||||
isc_token_t token;
|
||||
isc_region_t region;
|
||||
struct in_addr addr;
|
||||
@@ -92,7 +101,7 @@ fromtext_in_wks(ARGS_FROMTEXT) {
|
||||
UNUSED(rdclass);
|
||||
UNUSED(callbacks);
|
||||
|
||||
RUNTIME_CHECK(isc_once_do(&once, init_lock) == ISC_R_SUCCESS);
|
||||
RUNTIME_CHECK(isc_once_do(&wks_once, init_lock) == ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* IPv4 dotted quad.
|
||||
|
||||
@@ -102,6 +102,7 @@ cleanup_managers(void) {
|
||||
|
||||
if (app_running) {
|
||||
isc_app_finish();
|
||||
app_running = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +129,7 @@ dns_test_begin(FILE *logfile, bool start_managers) {
|
||||
|
||||
if (start_managers) {
|
||||
CHECK(isc_app_start());
|
||||
app_running = true;
|
||||
}
|
||||
if (debug_mem_record) {
|
||||
isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
/*! \file */
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <isc/condition.h>
|
||||
#include <isc/strerr.h>
|
||||
@@ -19,6 +20,66 @@
|
||||
#include <isc/time.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#ifdef ISC_TRACK_PTHREADS_OBJECTS
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
struct isc_condition_tracker {
|
||||
ISC_LINK(isc_condition_tracker_t) link;
|
||||
const char *file;
|
||||
int line;
|
||||
};
|
||||
|
||||
static pthread_mutex_t conditionslock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static ISC_LIST(isc_condition_tracker_t) conditions = { NULL, NULL };
|
||||
|
||||
void
|
||||
isc_condition_init_track(isc_condition_t *c, const char *file, int line) {
|
||||
isc__condition_init(&c->cond);
|
||||
|
||||
c->tracker = malloc(sizeof(*c->tracker));
|
||||
INSIST(c->tracker != NULL);
|
||||
c->tracker->file = file;
|
||||
c->tracker->line = line;
|
||||
|
||||
pthread_mutex_lock(&conditionslock);
|
||||
ISC_LIST_INITANDAPPEND(conditions, c->tracker, link);
|
||||
pthread_mutex_unlock(&conditionslock);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_condition_destroy_track(isc_condition_t *c) {
|
||||
INSIST(c->tracker != NULL);
|
||||
|
||||
pthread_mutex_lock(&conditionslock);
|
||||
ISC_LIST_UNLINK(conditions, c->tracker, link);
|
||||
pthread_mutex_unlock(&conditionslock);
|
||||
|
||||
free(c->tracker);
|
||||
c->tracker = NULL;
|
||||
|
||||
return (isc__condition_destroy(&c->cond));
|
||||
}
|
||||
|
||||
void
|
||||
isc_condition_check_track(void) {
|
||||
pthread_mutex_lock(&conditionslock);
|
||||
if (!ISC_LIST_EMPTY(conditions)) {
|
||||
isc_condition_tracker_t *t;
|
||||
fprintf(stderr,
|
||||
"isc_condition_init/isc_condition_destroy mismatch\n");
|
||||
for (t = ISC_LIST_HEAD(conditions); t != NULL;
|
||||
t = ISC_LIST_NEXT(t, link)) {
|
||||
fprintf(stderr, "condition %s:%d\n", t->file, t->line);
|
||||
}
|
||||
|
||||
abort();
|
||||
}
|
||||
pthread_mutex_unlock(&conditionslock);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
isc_result_t
|
||||
isc_condition_waituntil(isc_condition_t *c, isc_mutex_t *m, isc_time_t *t) {
|
||||
int presult;
|
||||
@@ -50,7 +111,22 @@ isc_condition_waituntil(isc_condition_t *c, isc_mutex_t *m, isc_time_t *t) {
|
||||
ts.tv_nsec = (long)isc_time_nanoseconds(t);
|
||||
|
||||
do {
|
||||
presult = pthread_cond_timedwait(c, m, &ts);
|
||||
pthread_cond_t *cond;
|
||||
pthread_mutex_t *mutex;
|
||||
|
||||
#ifdef ISC_TRACK_PTHREADS_OBJECTS
|
||||
cond = &c->cond;
|
||||
#else /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
cond = c;
|
||||
#endif /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
|
||||
#ifdef ISC_TRACK_PTHREADS_OBJECTS
|
||||
mutex = &m->mutex;
|
||||
#else /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
mutex = m;
|
||||
#endif /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
|
||||
presult = pthread_cond_timedwait(cond, mutex, &ts);
|
||||
if (presult == 0) {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -23,9 +23,45 @@
|
||||
#include <isc/string.h>
|
||||
#include <isc/types.h>
|
||||
|
||||
#ifdef ISC_TRACK_PTHREADS_OBJECTS
|
||||
|
||||
typedef struct isc_condition_tracker isc_condition_tracker_t;
|
||||
|
||||
typedef struct {
|
||||
pthread_cond_t cond;
|
||||
isc_condition_tracker_t *tracker;
|
||||
} isc_condition_t;
|
||||
|
||||
void
|
||||
isc_condition_init_track(isc_condition_t *c, const char *file, int line);
|
||||
|
||||
isc_result_t
|
||||
isc_condition_destroy_track(isc_condition_t *);
|
||||
|
||||
void
|
||||
isc_condition_check_track(void);
|
||||
|
||||
#define isc_condition_init(cond) \
|
||||
isc_condition_init_track(cond, __FILE__, __LINE__)
|
||||
#define isc_condition_wait(cp, mp) \
|
||||
isc__condition_wait(&(cp)->cond, &(mp)->mutex)
|
||||
#define isc_condition_signal(cp) isc__condition_signal(&(cp)->cond)
|
||||
#define isc_condition_broadcast(cp) isc__condition_broadcast(&(cp)->cond)
|
||||
#define isc_condition_destroy(cp) isc_condition_destroy_track(cp)
|
||||
|
||||
#else /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
|
||||
typedef pthread_cond_t isc_condition_t;
|
||||
|
||||
#define isc_condition_init(cond) \
|
||||
#define isc_condition_init(cond) isc__condition_init(cond)
|
||||
#define isc_condition_wait(cp, mp) isc__condition_wait(cp, mp)
|
||||
#define isc_condition_signal(cp) isc__condition_signal(cp)
|
||||
#define isc_condition_broadcast(cp) isc__condition_broadcast(cp)
|
||||
#define isc_condition_destroy(cp) isc__condition_destroy(cp)
|
||||
|
||||
#endif /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
|
||||
#define isc__condition_init(cond) \
|
||||
if (pthread_cond_init(cond, NULL) != 0) { \
|
||||
char isc_condition_strbuf[ISC_STRERRORSIZE]; \
|
||||
strerror_r(errno, isc_condition_strbuf, \
|
||||
@@ -35,17 +71,17 @@ typedef pthread_cond_t isc_condition_t;
|
||||
isc_condition_strbuf); \
|
||||
}
|
||||
|
||||
#define isc_condition_wait(cp, mp) \
|
||||
#define isc__condition_wait(cp, mp) \
|
||||
((pthread_cond_wait((cp), (mp)) == 0) ? ISC_R_SUCCESS \
|
||||
: ISC_R_UNEXPECTED)
|
||||
|
||||
#define isc_condition_signal(cp) \
|
||||
#define isc__condition_signal(cp) \
|
||||
((pthread_cond_signal((cp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
|
||||
|
||||
#define isc_condition_broadcast(cp) \
|
||||
#define isc__condition_broadcast(cp) \
|
||||
((pthread_cond_broadcast((cp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
|
||||
|
||||
#define isc_condition_destroy(cp) \
|
||||
#define isc__condition_destroy(cp) \
|
||||
((pthread_cond_destroy((cp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
@@ -21,22 +21,52 @@
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
#ifdef ISC_TRACK_PTHREADS_OBJECTS
|
||||
|
||||
typedef struct isc_mutex_tracker isc_mutex_tracker_t;
|
||||
|
||||
typedef struct {
|
||||
pthread_mutex_t mutex;
|
||||
isc_mutex_tracker_t *tracker;
|
||||
} isc_mutex_t;
|
||||
|
||||
void
|
||||
isc_mutex_init_track(isc_mutex_t *m, const char *file, int line);
|
||||
|
||||
void
|
||||
isc_mutex_destroy_track(isc_mutex_t *m);
|
||||
|
||||
void
|
||||
isc_mutex_check_track(void);
|
||||
|
||||
#define isc_mutex_init(mp) isc_mutex_init_track(mp, __FILE__, __LINE__)
|
||||
#define isc_mutex_lock(mp) isc__mutex_lock(&(mp)->mutex)
|
||||
#define isc_mutex_unlock(mp) isc__mutex_unlock(&(mp)->mutex)
|
||||
#define isc_mutex_trylock(mp) isc__mutex_trylock(&(mp)->mutex)
|
||||
#define isc_mutex_destroy(mp) isc_mutex_destroy_track(mp)
|
||||
|
||||
#else /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
|
||||
typedef pthread_mutex_t isc_mutex_t;
|
||||
|
||||
void
|
||||
isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line);
|
||||
|
||||
#define isc_mutex_init(mp) isc__mutex_init((mp), __FILE__, __LINE__)
|
||||
|
||||
#define isc_mutex_lock(mp) \
|
||||
((pthread_mutex_lock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
|
||||
|
||||
#define isc_mutex_unlock(mp) \
|
||||
((pthread_mutex_unlock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
|
||||
|
||||
#define isc_mutex_trylock(mp) \
|
||||
((pthread_mutex_trylock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_LOCKBUSY)
|
||||
isc_mutex_init_location(isc_mutex_t *mp, const char *file, unsigned int line);
|
||||
|
||||
#define isc_mutex_init(mp) isc_mutex_init_location((mp), __FILE__, __LINE__)
|
||||
#define isc_mutex_lock(mp) isc__mutex_lock(mp)
|
||||
#define isc_mutex_unlock(mp) isc__mutex_unlock(mp)
|
||||
#define isc_mutex_trylock(mp) isc__mutex_trylock(mp)
|
||||
#define isc_mutex_destroy(mp) RUNTIME_CHECK(pthread_mutex_destroy((mp)) == 0)
|
||||
|
||||
#endif /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
|
||||
#define isc__mutex_lock(mp) \
|
||||
((pthread_mutex_lock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
|
||||
|
||||
#define isc__mutex_unlock(mp) \
|
||||
((pthread_mutex_unlock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
|
||||
|
||||
#define isc__mutex_trylock(mp) \
|
||||
((pthread_mutex_trylock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_LOCKBUSY)
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
@@ -28,12 +28,22 @@ typedef enum {
|
||||
isc_rwlocktype_write
|
||||
} isc_rwlocktype_t;
|
||||
|
||||
#ifdef ISC_TRACK_PTHREADS_OBJECTS
|
||||
typedef struct isc_rwlock_tracker isc_rwlock_tracker_t;
|
||||
|
||||
void
|
||||
isc_rwlock_check_track(void);
|
||||
#endif
|
||||
|
||||
#if USE_PTHREAD_RWLOCK
|
||||
#include <pthread.h>
|
||||
|
||||
struct isc_rwlock {
|
||||
pthread_rwlock_t rwlock;
|
||||
atomic_bool downgrade;
|
||||
#ifdef ISC_TRACK_PTHREADS_OBJECTS
|
||||
isc_rwlock_tracker_t *tracker;
|
||||
#endif /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
};
|
||||
|
||||
#else /* USE_PTHREAD_RWLOCK */
|
||||
@@ -71,14 +81,19 @@ struct isc_rwlock {
|
||||
atomic_uint_fast32_t write_granted;
|
||||
|
||||
/* Unlocked. */
|
||||
unsigned int write_quota;
|
||||
unsigned int write_quota;
|
||||
#ifdef ISC_TRACK_PTHREADS_OBJECTS
|
||||
isc_rwlock_tracker_t *tracker;
|
||||
#endif /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
};
|
||||
|
||||
#endif /* USE_PTHREAD_RWLOCK */
|
||||
|
||||
#define isc_rwlock_init(rwl, read_quota, write_quota) \
|
||||
isc__rwlock_init(rwl, read_quota, write_quota, __FILE__, __LINE__)
|
||||
void
|
||||
isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
||||
unsigned int write_quota);
|
||||
isc__rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
||||
unsigned int write_quota, const char *file, int line);
|
||||
|
||||
isc_result_t
|
||||
isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
/*! \file */
|
||||
|
||||
#include <isc/bind9.h>
|
||||
#include <isc/condition.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/os.h>
|
||||
#include <isc/rwlock.h>
|
||||
#include <isc/tls.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
@@ -48,4 +50,9 @@ isc__shutdown(void) {
|
||||
isc__trampoline_shutdown();
|
||||
isc__tls_shutdown();
|
||||
isc__mem_shutdown();
|
||||
#ifdef ISC_TRACK_PTHREADS_OBJECTS
|
||||
isc_mutex_check_track();
|
||||
isc_rwlock_check_track();
|
||||
isc_condition_check_track();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -24,6 +24,62 @@
|
||||
#include <isc/string.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#ifdef ISC_TRACK_PTHREADS_OBJECTS
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
struct isc_mutex_tracker {
|
||||
ISC_LINK(isc_mutex_tracker_t) link;
|
||||
const char *file;
|
||||
int line;
|
||||
};
|
||||
|
||||
static pthread_mutex_t mutexeslock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static ISC_LIST(isc_mutex_tracker_t) mutexes = { NULL, NULL };
|
||||
|
||||
void
|
||||
isc_mutex_init_track(isc_mutex_t *m, const char *file, int line) {
|
||||
RUNTIME_CHECK(pthread_mutex_init(&m->mutex, NULL) == 0);
|
||||
|
||||
m->tracker = malloc(sizeof(*m->tracker));
|
||||
INSIST(m->tracker != NULL);
|
||||
m->tracker->file = file;
|
||||
m->tracker->line = line;
|
||||
|
||||
pthread_mutex_lock(&mutexeslock);
|
||||
ISC_LIST_INITANDAPPEND(mutexes, m->tracker, link);
|
||||
pthread_mutex_unlock(&mutexeslock);
|
||||
}
|
||||
|
||||
void
|
||||
isc_mutex_destroy_track(isc_mutex_t *m) {
|
||||
INSIST(m->tracker != NULL);
|
||||
pthread_mutex_lock(&mutexeslock);
|
||||
ISC_LIST_UNLINK(mutexes, m->tracker, link);
|
||||
pthread_mutex_unlock(&mutexeslock);
|
||||
free(m->tracker);
|
||||
m->tracker = NULL;
|
||||
RUNTIME_CHECK(pthread_mutex_destroy(&m->mutex) == 0);
|
||||
}
|
||||
|
||||
void
|
||||
isc_mutex_check_track(void) {
|
||||
pthread_mutex_lock(&mutexeslock);
|
||||
if (!ISC_LIST_EMPTY(mutexes)) {
|
||||
isc_mutex_tracker_t *t;
|
||||
fprintf(stderr, "isc_mutex_init/isc_mutext_destroy mismatch\n");
|
||||
for (t = ISC_LIST_HEAD(mutexes); t != NULL;
|
||||
t = ISC_LIST_NEXT(t, link)) {
|
||||
fprintf(stderr, "mutex %s:%d\n", t->file, t->line);
|
||||
}
|
||||
|
||||
abort();
|
||||
}
|
||||
pthread_mutex_unlock(&mutexeslock);
|
||||
}
|
||||
|
||||
#else /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
|
||||
#ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP
|
||||
static bool attr_initialized = false;
|
||||
static pthread_mutexattr_t attr;
|
||||
@@ -39,7 +95,7 @@ initialize_attr(void) {
|
||||
#endif /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */
|
||||
|
||||
void
|
||||
isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line) {
|
||||
isc_mutex_init_location(isc_mutex_t *mp, const char *file, unsigned int line) {
|
||||
int err;
|
||||
|
||||
#ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP
|
||||
@@ -58,3 +114,5 @@ isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line) {
|
||||
strbuf);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
|
||||
@@ -25,18 +25,62 @@
|
||||
#include <isc/rwlock.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#ifdef ISC_TRACK_PTHREADS_OBJECTS
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
struct isc_rwlock_tracker {
|
||||
ISC_LINK(isc_rwlock_tracker_t) link;
|
||||
const char *file;
|
||||
int line;
|
||||
};
|
||||
|
||||
static pthread_mutex_t rwlockslock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static ISC_LIST(isc_rwlock_tracker_t) rwlocks = { NULL, NULL };
|
||||
|
||||
void
|
||||
isc_rwlock_check_track(void) {
|
||||
pthread_mutex_lock(&rwlockslock);
|
||||
if (!ISC_LIST_EMPTY(rwlocks)) {
|
||||
isc_rwlock_tracker_t *t;
|
||||
fprintf(stderr,
|
||||
"isc_rwlock_init/isc_rwlock_destroy mismatch\n");
|
||||
for (t = ISC_LIST_HEAD(rwlocks); t != NULL;
|
||||
t = ISC_LIST_NEXT(t, link)) {
|
||||
fprintf(stderr, "rwlock %s:%d\n", t->file, t->line);
|
||||
}
|
||||
|
||||
abort();
|
||||
}
|
||||
pthread_mutex_unlock(&rwlockslock);
|
||||
}
|
||||
|
||||
#endif /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
|
||||
#if USE_PTHREAD_RWLOCK
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
void
|
||||
isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
||||
unsigned int write_quota) {
|
||||
isc__rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
||||
unsigned int write_quota, const char *file, int line) {
|
||||
UNUSED(read_quota);
|
||||
UNUSED(write_quota);
|
||||
REQUIRE(pthread_rwlock_init(&rwl->rwlock, NULL) == 0);
|
||||
atomic_init(&rwl->downgrade, false);
|
||||
#ifdef ISC_TRACK_PTHREADS_OBJECTS
|
||||
rwl->tracker = malloc(sizeof(*rwl->tracker));
|
||||
INSIST(rwl->tracker != NULL);
|
||||
rwl->tracker->file = file;
|
||||
rwl->tracker->line = line;
|
||||
pthread_mutex_lock(&rwlockslock);
|
||||
ISC_LIST_INITANDAPPEND(rwlocks, rwl->tracker, link);
|
||||
pthread_mutex_unlock(&rwlockslock);
|
||||
#else
|
||||
UNUSED(file);
|
||||
UNUSED(line);
|
||||
#endif /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
@@ -123,6 +167,15 @@ isc_rwlock_downgrade(isc_rwlock_t *rwl) {
|
||||
|
||||
void
|
||||
isc_rwlock_destroy(isc_rwlock_t *rwl) {
|
||||
#ifdef ISC_TRACK_PTHREADS_OBJECTS
|
||||
INSIST(rwl->tracker != NULL);
|
||||
pthread_mutex_lock(&rwlockslock);
|
||||
ISC_LIST_UNLINK(rwlocks, rwl->tracker, link);
|
||||
pthread_mutex_unlock(&rwlockslock);
|
||||
free(rwl->tracker);
|
||||
rwl->tracker = NULL;
|
||||
#endif /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
|
||||
pthread_rwlock_destroy(&rwl->rwlock);
|
||||
}
|
||||
|
||||
@@ -191,8 +244,8 @@ print_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||
#endif /* ISC_RWLOCK_TRACE */
|
||||
|
||||
void
|
||||
isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
||||
unsigned int write_quota) {
|
||||
isc__rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
||||
unsigned int write_quota, const char *file, int line) {
|
||||
REQUIRE(rwl != NULL);
|
||||
|
||||
/*
|
||||
@@ -221,6 +274,19 @@ isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
||||
isc_condition_init(&rwl->readable);
|
||||
isc_condition_init(&rwl->writeable);
|
||||
|
||||
#ifdef ISC_TRACK_PTHREADS_OBJECTS
|
||||
rwl->tracker = malloc(sizeof(*rwl->tracker));
|
||||
INSIST(rwl->tracker != NULL);
|
||||
rwl->tracker->file = file;
|
||||
rwl->tracker->line = line;
|
||||
pthread_mutex_lock(&rwlockslock);
|
||||
ISC_LIST_INITANDAPPEND(rwlocks, rwl->tracker, link);
|
||||
pthread_mutex_unlock(&rwlockslock);
|
||||
#else
|
||||
UNUSED(file);
|
||||
UNUSED(line);
|
||||
#endif /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
|
||||
rwl->magic = RWLOCK_MAGIC;
|
||||
}
|
||||
|
||||
@@ -233,6 +299,15 @@ isc_rwlock_destroy(isc_rwlock_t *rwl) {
|
||||
atomic_load_acquire(&rwl->cnt_and_flag) == 0 &&
|
||||
rwl->readers_waiting == 0);
|
||||
|
||||
#ifdef ISC_TRACK_PTHREADS_OBJECTS
|
||||
INSIST(rwl->tracker != NULL);
|
||||
pthread_mutex_lock(&rwlockslock);
|
||||
ISC_LIST_UNLINK(rwlocks, rwl->tracker, link);
|
||||
pthread_mutex_unlock(&rwlockslock);
|
||||
free(rwl->tracker);
|
||||
rwl->tracker = NULL;
|
||||
#endif /* ISC_TRACK_PTHREADS_OBJECTS */
|
||||
|
||||
rwl->magic = 0;
|
||||
(void)isc_condition_destroy(&rwl->readable);
|
||||
(void)isc_condition_destroy(&rwl->writeable);
|
||||
|
||||
@@ -379,6 +379,8 @@ nm_teardown(void **state __attribute__((unused))) {
|
||||
isc_refcount_destroy(&active_ssends);
|
||||
isc_refcount_destroy(&active_sreads);
|
||||
|
||||
isc_quota_destroy(&listener_quota);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -104,6 +104,7 @@ _teardown(void **state) {
|
||||
UNUSED(state);
|
||||
|
||||
isc_test_end();
|
||||
isc_mutex_destroy(&lock);
|
||||
isc_condition_destroy(&cv);
|
||||
|
||||
return (0);
|
||||
@@ -919,8 +920,6 @@ post_shutdown(void **state) {
|
||||
atomic_init(&done, false);
|
||||
event_type = 4;
|
||||
|
||||
isc_condition_init(&cv);
|
||||
|
||||
LOCK(&lock);
|
||||
|
||||
task = NULL;
|
||||
@@ -1059,6 +1058,7 @@ test_purge(int sender, int type, int tag, int exp_purged) {
|
||||
atomic_init(&done, false);
|
||||
eventcnt = 0;
|
||||
|
||||
isc_condition_destroy(&cv);
|
||||
isc_condition_init(&cv);
|
||||
|
||||
result = isc_task_create(taskmgr, 0, &task);
|
||||
@@ -1354,8 +1354,6 @@ try_purgeevent(bool purgeable) {
|
||||
atomic_init(&done, false);
|
||||
eventcnt = 0;
|
||||
|
||||
isc_condition_init(&cv);
|
||||
|
||||
result = isc_task_create(taskmgr, 0, &task);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
|
||||
@@ -146,6 +146,7 @@ setup_test(isc_timertype_t timertype, isc_time_t *expires,
|
||||
|
||||
isc_task_detach(&task);
|
||||
isc_mutex_destroy(&mx);
|
||||
isc_mutex_destroy(&lasttime_mx);
|
||||
(void)isc_condition_destroy(&cv);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user