Compare commits
7 Commits
nicki/pyte
...
ondrej/isc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4eae3fb9cd | ||
|
|
3e12d19329 | ||
|
|
67bbfd3ec8 | ||
|
|
d3b1a73325 | ||
|
|
606e19c286 | ||
|
|
eeed92e0b9 | ||
|
|
6ffcd13bf1 |
46
lib/dns/db.c
46
lib/dns/db.c
@@ -62,24 +62,9 @@ unsigned int dns_pps = 0U;
|
||||
|
||||
static ISC_LIST(dns_dbimplementation_t) implementations;
|
||||
static isc_rwlock_t implock;
|
||||
static isc_once_t once = ISC_ONCE_INIT;
|
||||
|
||||
static dns_dbimplementation_t rbtimp;
|
||||
|
||||
static void
|
||||
initialize(void) {
|
||||
isc_rwlock_init(&implock, 0, 0);
|
||||
|
||||
rbtimp.name = "rbt";
|
||||
rbtimp.create = dns_rbtdb_create;
|
||||
rbtimp.mctx = NULL;
|
||||
rbtimp.driverarg = NULL;
|
||||
ISC_LINK_INIT(&rbtimp, link);
|
||||
|
||||
ISC_LIST_INIT(implementations);
|
||||
ISC_LIST_APPEND(implementations, &rbtimp, link);
|
||||
}
|
||||
|
||||
static inline dns_dbimplementation_t *
|
||||
impfind(const char *name) {
|
||||
dns_dbimplementation_t *imp;
|
||||
@@ -104,8 +89,6 @@ dns_db_create(isc_mem_t *mctx, const char *db_type, const dns_name_t *origin,
|
||||
char *argv[], dns_db_t **dbp) {
|
||||
dns_dbimplementation_t *impinfo;
|
||||
|
||||
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Create a new database using implementation 'db_type'.
|
||||
*/
|
||||
@@ -839,8 +822,6 @@ dns_db_register(const char *name, dns_dbcreatefunc_t create, void *driverarg,
|
||||
REQUIRE(name != NULL);
|
||||
REQUIRE(dbimp != NULL && *dbimp == NULL);
|
||||
|
||||
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
|
||||
|
||||
RWLOCK(&implock, isc_rwlocktype_write);
|
||||
imp = impfind(name);
|
||||
if (imp != NULL) {
|
||||
@@ -869,8 +850,6 @@ dns_db_unregister(dns_dbimplementation_t **dbimp) {
|
||||
|
||||
REQUIRE(dbimp != NULL && *dbimp != NULL);
|
||||
|
||||
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
|
||||
|
||||
imp = *dbimp;
|
||||
*dbimp = NULL;
|
||||
RWLOCK(&implock, isc_rwlocktype_write);
|
||||
@@ -1104,3 +1083,28 @@ dns_db_setgluecachestats(dns_db_t *db, isc_stats_t *stats) {
|
||||
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
|
||||
void
|
||||
initialize(void) ISC_CONSTRUCTOR;
|
||||
|
||||
void
|
||||
initialize(void) {
|
||||
isc_rwlock_init(&implock, 0, 0);
|
||||
|
||||
rbtimp.name = "rbt";
|
||||
rbtimp.create = dns_rbtdb_create;
|
||||
rbtimp.mctx = NULL;
|
||||
rbtimp.driverarg = NULL;
|
||||
ISC_LINK_INIT(&rbtimp, link);
|
||||
|
||||
ISC_LIST_INIT(implementations);
|
||||
ISC_LIST_APPEND(implementations, &rbtimp, link);
|
||||
}
|
||||
|
||||
void
|
||||
dns__db_shutdown(void) ISC_DESTRUCTOR;
|
||||
|
||||
void
|
||||
dns__db_shutdown(void) {
|
||||
isc_rwlock_destroy(&implock);
|
||||
}
|
||||
|
||||
@@ -75,13 +75,6 @@
|
||||
|
||||
static ISC_LIST(dns_dlzimplementation_t) dlz_implementations;
|
||||
static isc_rwlock_t dlz_implock;
|
||||
static isc_once_t once = ISC_ONCE_INIT;
|
||||
|
||||
static void
|
||||
dlz_initialize(void) {
|
||||
isc_rwlock_init(&dlz_implock, 0, 0);
|
||||
ISC_LIST_INIT(dlz_implementations);
|
||||
}
|
||||
|
||||
/*%
|
||||
* Searches the dlz_implementations list for a driver matching name.
|
||||
@@ -158,12 +151,6 @@ dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername,
|
||||
isc_result_t result;
|
||||
dns_dlzdb_t *db = NULL;
|
||||
|
||||
/*
|
||||
* initialize the dlz_implementations list, this is guaranteed
|
||||
* to only really happen once.
|
||||
*/
|
||||
RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Performs checks to make sure data is as we expect it to be.
|
||||
*/
|
||||
@@ -289,12 +276,6 @@ dns_dlzregister(const char *drivername, const dns_dlzmethods_t *methods,
|
||||
REQUIRE(mctx != NULL);
|
||||
REQUIRE(dlzimp != NULL && *dlzimp == NULL);
|
||||
|
||||
/*
|
||||
* initialize the dlz_implementations list, this is guaranteed
|
||||
* to only really happen once.
|
||||
*/
|
||||
RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS);
|
||||
|
||||
/* lock the dlz_implementations list so we can modify it. */
|
||||
RWLOCK(&dlz_implock, isc_rwlocktype_write);
|
||||
|
||||
@@ -374,12 +355,6 @@ dns_dlzunregister(dns_dlzimplementation_t **dlzimp) {
|
||||
*/
|
||||
REQUIRE(dlzimp != NULL && *dlzimp != NULL);
|
||||
|
||||
/*
|
||||
* initialize the dlz_implementations list, this is guaranteed
|
||||
* to only really happen once.
|
||||
*/
|
||||
RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS);
|
||||
|
||||
dlz_imp = *dlzimp;
|
||||
|
||||
/* lock the dlz_implementations list so we can modify it. */
|
||||
@@ -532,3 +507,20 @@ dns_dlz_ssumatch(dns_dlzdb_t *dlzdatabase, const dns_name_t *signer,
|
||||
impl->driverarg, dlzdatabase->dbdata);
|
||||
return (r);
|
||||
}
|
||||
|
||||
void
|
||||
dns__dlz_initialize(void) ISC_CONSTRUCTOR;
|
||||
|
||||
void
|
||||
dns__dlz_initialize(void) {
|
||||
isc_rwlock_init(&dlz_implock, 0, 0);
|
||||
ISC_LIST_INIT(dlz_implementations);
|
||||
}
|
||||
|
||||
void
|
||||
dns__dlz_destroy(void) ISC_DESTRUCTOR;
|
||||
|
||||
void
|
||||
dns__dlz_destroy(void) {
|
||||
isc_rwlock_destroy(&dlz_implock);
|
||||
}
|
||||
|
||||
@@ -21,21 +21,8 @@
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
/*!
|
||||
* Supply mutex attributes that enable deadlock detection
|
||||
* (helpful when debugging). This is system dependent and
|
||||
* currently only supported on NetBSD.
|
||||
*/
|
||||
#if ISC_MUTEX_DEBUG && defined(__NetBSD__) && defined(PTHREAD_MUTEX_ERRORCHECK)
|
||||
extern pthread_mutexattr_t isc__mutex_attrs;
|
||||
#define ISC__MUTEX_ATTRS &isc__mutex_attrs
|
||||
#else /* if ISC_MUTEX_DEBUG && defined(__NetBSD__) && \
|
||||
* defined(PTHREAD_MUTEX_ERRORCHECK) */
|
||||
#define ISC__MUTEX_ATTRS NULL
|
||||
#endif /* if ISC_MUTEX_DEBUG && defined(__NetBSD__) && \
|
||||
* defined(PTHREAD_MUTEX_ERRORCHECK) */
|
||||
|
||||
/* XXX We could do fancier error handling... */
|
||||
/* DROPME */
|
||||
#define ISC_MUTEX_DEBUG 1
|
||||
|
||||
/*!
|
||||
* Define ISC_MUTEX_PROFILE to turn on profiling of mutexes by line. When
|
||||
@@ -47,79 +34,79 @@ extern pthread_mutexattr_t isc__mutex_attrs;
|
||||
#define ISC_MUTEX_PROFILE 0
|
||||
#endif /* ifndef ISC_MUTEX_PROFILE */
|
||||
|
||||
#if ISC_MUTEX_PROFILE
|
||||
#if defined(ISC_MUTEX_DEBUG)
|
||||
|
||||
typedef pthread_mutex_t isc_mutex_t;
|
||||
|
||||
#define isc_mutex_init(mp) \
|
||||
isc_mutex_init_debug((mp), __func__, __FILE__, __LINE__)
|
||||
#define isc_mutex_destroy(mp) \
|
||||
isc_mutex_destroy_debug((mp), __func__, __FILE__, __LINE__)
|
||||
void
|
||||
isc_mutex_init_debug(isc_mutex_t *mp, const char *func, const char *file,
|
||||
unsigned int line);
|
||||
|
||||
void
|
||||
isc_mutex_destroy_debug(isc_mutex_t *mp, const char *func, const char *file,
|
||||
unsigned int line);
|
||||
|
||||
#elif ISC_MUTEX_PROFILE
|
||||
|
||||
typedef struct isc_mutexstats isc_mutexstats_t;
|
||||
|
||||
typedef struct {
|
||||
pthread_mutex_t mutex; /*%< The actual mutex. */
|
||||
isc_mutexstats_t *stats; /*%< Mutex statistics. */
|
||||
} isc_mutex_t;
|
||||
#else /* if ISC_MUTEX_PROFILE */
|
||||
typedef pthread_mutex_t isc_mutex_t;
|
||||
#endif /* if ISC_MUTEX_PROFILE */
|
||||
|
||||
#if ISC_MUTEX_PROFILE
|
||||
#define isc_mutex_init(mp) isc_mutex_init_profile((mp), __FILE__, __LINE__)
|
||||
#else /* if ISC_MUTEX_PROFILE */
|
||||
#if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)
|
||||
#define isc_mutex_init(mp) isc_mutex_init_errcheck((mp))
|
||||
#else /* if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK) */
|
||||
#define isc_mutex_init(mp) isc__mutex_init((mp), __FILE__, __LINE__)
|
||||
void
|
||||
isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line);
|
||||
#endif /* if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK) */
|
||||
#endif /* if ISC_MUTEX_PROFILE */
|
||||
|
||||
#if ISC_MUTEX_PROFILE
|
||||
#define isc_mutex_lock(mp) isc_mutex_lock_profile((mp), __FILE__, __LINE__)
|
||||
#else /* if ISC_MUTEX_PROFILE */
|
||||
#define isc_mutex_lock(mp) \
|
||||
((pthread_mutex_lock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
|
||||
#endif /* if ISC_MUTEX_PROFILE */
|
||||
|
||||
#if ISC_MUTEX_PROFILE
|
||||
#define isc_mutex_unlock(mp) isc_mutex_unlock_profile((mp), __FILE__, __LINE__)
|
||||
#else /* if ISC_MUTEX_PROFILE */
|
||||
#define isc_mutex_unlock(mp) \
|
||||
((pthread_mutex_unlock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
|
||||
#endif /* if ISC_MUTEX_PROFILE */
|
||||
|
||||
#if ISC_MUTEX_PROFILE
|
||||
#define isc_mutex_trylock(mp) \
|
||||
((pthread_mutex_trylock((&(mp)->mutex)) == 0) ? ISC_R_SUCCESS \
|
||||
: ISC_R_LOCKBUSY)
|
||||
#else /* if ISC_MUTEX_PROFILE */
|
||||
#define isc_mutex_trylock(mp) \
|
||||
((pthread_mutex_trylock((mp)) == 0) ? ISC_R_SUCCESS : ISC_R_LOCKBUSY)
|
||||
#endif /* if ISC_MUTEX_PROFILE */
|
||||
|
||||
#if ISC_MUTEX_PROFILE
|
||||
#define isc_mutex_destroy(mp) \
|
||||
RUNTIME_CHECK(pthread_mutex_destroy((&(mp)->mutex)) == 0)
|
||||
#else /* if ISC_MUTEX_PROFILE */
|
||||
#define isc_mutex_destroy(mp) RUNTIME_CHECK(pthread_mutex_destroy((mp)) == 0)
|
||||
#endif /* if ISC_MUTEX_PROFILE */
|
||||
|
||||
#if ISC_MUTEX_PROFILE
|
||||
#define isc_mutex_stats(fp) isc_mutex_statsprofile(fp);
|
||||
#else /* if ISC_MUTEX_PROFILE */
|
||||
#define isc_mutex_stats(fp)
|
||||
#endif /* if ISC_MUTEX_PROFILE */
|
||||
|
||||
#if ISC_MUTEX_PROFILE
|
||||
|
||||
void
|
||||
isc_mutex_init_profile(isc_mutex_t *mp, const char *_file, int _line);
|
||||
|
||||
#else
|
||||
|
||||
typedef pthread_mutex_t isc_mutex_t;
|
||||
|
||||
#define isc_mutex_init(mp) isc__mutex_init((mp), __FILE__, __LINE__)
|
||||
void
|
||||
isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line);
|
||||
#define isc_mutex_destroy(mp) RUNTIME_CHECK(pthread_mutex_destroy((mp)) == 0)
|
||||
|
||||
#endif
|
||||
|
||||
#if ISC_MUTEX_PROFILE
|
||||
|
||||
#define isc_mutex_lock(mp) isc_mutex_lock_profile((mp), __FILE__, __LINE__)
|
||||
isc_result_t
|
||||
isc_mutex_lock_profile(isc_mutex_t *mp, const char *_file, int _line);
|
||||
|
||||
#define isc_mutex_unlock(mp) isc_mutex_unlock_profile((mp), __FILE__, __LINE__)
|
||||
isc_result_t
|
||||
isc_mutex_unlock_profile(isc_mutex_t *mp, const char *_file, int _line);
|
||||
|
||||
#define isc_mutex_trylock(mp) \
|
||||
((pthread_mutex_trylock((&(mp)->mutex)) == 0) ? ISC_R_SUCCESS \
|
||||
: ISC_R_LOCKBUSY)
|
||||
|
||||
#define isc_mutex_stats(fp) isc_mutex_statsprofile(fp);
|
||||
void
|
||||
isc_mutex_statsprofile(FILE *fp);
|
||||
#endif /* ISC_MUTEX_PROFILE */
|
||||
|
||||
void
|
||||
isc_mutex_init_errcheck(isc_mutex_t *mp);
|
||||
#else
|
||||
|
||||
#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)
|
||||
|
||||
#define isc_mutex_stats(fp)
|
||||
|
||||
#endif
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
@@ -76,9 +76,14 @@ struct isc_rwlock {
|
||||
|
||||
#endif /* USE_PTHREAD_RWLOCK */
|
||||
|
||||
#define isc_rwlock_init(rwl, read_quota, write_quota) \
|
||||
isc__rwlock_init(rwl, read_quota, write_quota, __func__, __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 *func, const char *file,
|
||||
unsigned int line);
|
||||
|
||||
isc_result_t
|
||||
isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
|
||||
@@ -95,7 +100,10 @@ isc_rwlock_tryupgrade(isc_rwlock_t *rwl);
|
||||
void
|
||||
isc_rwlock_downgrade(isc_rwlock_t *rwl);
|
||||
|
||||
#define isc_rwlock_destroy(rwl) \
|
||||
isc__rwlock_destroy(rwl, __func__, __FILE__, __LINE__)
|
||||
void
|
||||
isc_rwlock_destroy(isc_rwlock_t *rwl);
|
||||
isc__rwlock_destroy(isc_rwlock_t *rwl, const char *func, const char *file,
|
||||
unsigned int line);
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
106
lib/isc/lib.c
106
lib/isc/lib.c
@@ -11,6 +11,11 @@
|
||||
|
||||
/*! \file */
|
||||
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
#include <isc/bind9.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/os.h>
|
||||
@@ -19,6 +24,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "mem_p.h"
|
||||
#include "mutex_p.h"
|
||||
#include "tls_p.h"
|
||||
#include "trampoline_p.h"
|
||||
|
||||
@@ -30,6 +36,100 @@
|
||||
*** Functions
|
||||
***/
|
||||
|
||||
static isc_mem_t *uv_mem = NULL;
|
||||
static isc_mem_t *openssl_mem = NULL;
|
||||
|
||||
static void *
|
||||
uv_malloc(size_t size) {
|
||||
return (isc_mem_allocate(uv_mem, size));
|
||||
}
|
||||
|
||||
static void *
|
||||
uv_realloc(void *ptr, size_t size) {
|
||||
return (isc_mem_reallocate(uv_mem, ptr, size));
|
||||
}
|
||||
|
||||
static void *
|
||||
uv_calloc(size_t count, size_t size) {
|
||||
/* FIXME: Check for overflow */
|
||||
void *ptr = isc_mem_allocate(uv_mem, count * size);
|
||||
memset(ptr, 0, count * size);
|
||||
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
uv_free(void *ptr) {
|
||||
if (ptr == 0) {
|
||||
return;
|
||||
}
|
||||
isc_mem_free(uv_mem, ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
isc__uv_initialize(void) {
|
||||
isc_mem_create(&uv_mem);
|
||||
|
||||
RUNTIME_CHECK(uv_replace_allocator(uv_malloc, uv_realloc, uv_calloc,
|
||||
uv_free) == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
isc__uv_shutdown(void) {
|
||||
uv_library_shutdown();
|
||||
isc_mem_destroy(&uv_mem);
|
||||
}
|
||||
|
||||
static void *
|
||||
openssl_malloc(size_t size, const char *file, int line) {
|
||||
#if ISC_MEM_TRACKLINES
|
||||
return (isc__mem_allocate(openssl_mem, size, file, line));
|
||||
#else
|
||||
UNUSED(file);
|
||||
UNUSED(line);
|
||||
|
||||
return (isc_mem_allocate(openssl_mem, size));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void *
|
||||
openssl_realloc(void *ptr, size_t size, const char *file, int line) {
|
||||
#if ISC_MEM_TRACKLINES
|
||||
return (isc__mem_reallocate(openssl_mem, ptr, size, file, line));
|
||||
#else
|
||||
UNUSED(file);
|
||||
UNUSED(line);
|
||||
return (isc_mem_reallocate(openssl_mem, ptr, size));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
openssl_free(void *ptr, const char *file, int line) {
|
||||
if (ptr == 0) {
|
||||
return;
|
||||
}
|
||||
#if ISC_MEM_TRACKLINES
|
||||
isc__mem_free(openssl_mem, ptr, file, line);
|
||||
#else
|
||||
UNUSED(file);
|
||||
UNUSED(line);
|
||||
isc_mem_free(openssl_mem, ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
isc__openssl_initialize(void) {
|
||||
isc_mem_create(&openssl_mem);
|
||||
|
||||
RUNTIME_CHECK(CRYPTO_set_mem_functions(openssl_malloc, openssl_realloc,
|
||||
openssl_free) == 1);
|
||||
}
|
||||
|
||||
static void
|
||||
isc__openssl_shutdown(void) {
|
||||
isc_mem_destroy(&openssl_mem);
|
||||
}
|
||||
|
||||
void
|
||||
isc__initialize(void) ISC_CONSTRUCTOR;
|
||||
void
|
||||
@@ -37,7 +137,10 @@ isc__shutdown(void) ISC_DESTRUCTOR;
|
||||
|
||||
void
|
||||
isc__initialize(void) {
|
||||
isc__mutex_initialize();
|
||||
isc__mem_initialize();
|
||||
isc__uv_initialize();
|
||||
isc__openssl_initialize();
|
||||
isc__tls_initialize();
|
||||
isc__trampoline_initialize();
|
||||
(void)isc_os_ncpus();
|
||||
@@ -47,5 +150,8 @@ void
|
||||
isc__shutdown(void) {
|
||||
isc__trampoline_shutdown();
|
||||
isc__tls_shutdown();
|
||||
isc__openssl_shutdown();
|
||||
isc__uv_shutdown();
|
||||
isc__mem_shutdown();
|
||||
isc__mutex_shutdown();
|
||||
}
|
||||
|
||||
145
lib/isc/mutex.c
145
lib/isc/mutex.c
@@ -17,6 +17,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <isc/atomic.h>
|
||||
#include <isc/mutex.h>
|
||||
#include <isc/once.h>
|
||||
#include <isc/print.h>
|
||||
@@ -24,7 +25,75 @@
|
||||
#include <isc/string.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#if ISC_MUTEX_PROFILE
|
||||
#include "mutex_p.h"
|
||||
|
||||
static pthread_mutexattr_t attr;
|
||||
static isc_once_t init_once = ISC_ONCE_INIT;
|
||||
static isc_once_t shut_once = ISC_ONCE_INIT;
|
||||
|
||||
static atomic_uint_fast32_t mutex_active = ATOMIC_VAR_INIT(0);
|
||||
|
||||
static void
|
||||
mutex_initialize(void) {
|
||||
RUNTIME_CHECK(pthread_mutexattr_init(&attr) == 0);
|
||||
#if defined(ISC_MUTEX_DEBUG) && defined(PTHREAD_MUTEX_ERRORCHECK)
|
||||
RUNTIME_CHECK(pthread_mutexattr_settype(&attr,
|
||||
PTHREAD_MUTEX_ERRORCHECK) == 0);
|
||||
#elif defined(HAVE_PTHREAD_MUTEX_ADAPTIVE_NP)
|
||||
RUNTIME_CHECK(pthread_mutexattr_settype(
|
||||
&attr, PTHREAD_MUTEX_ADAPTIVE_NP) == 0);
|
||||
#endif /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */
|
||||
}
|
||||
|
||||
void
|
||||
isc__mutex_initialize(void) {
|
||||
RUNTIME_CHECK(isc_once_do(&init_once, mutex_initialize) ==
|
||||
ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
mutex_shutdown(void) {
|
||||
REQUIRE(atomic_load_acquire(&mutex_active) == 0);
|
||||
}
|
||||
|
||||
void
|
||||
isc__mutex_shutdown(void) {
|
||||
RUNTIME_CHECK(isc_once_do(&shut_once, mutex_shutdown) == ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
#if ISC_MUTEX_DEBUG
|
||||
|
||||
void
|
||||
isc_mutex_init_debug(isc_mutex_t *mp, const char *func, const char *file,
|
||||
unsigned int line) {
|
||||
int err;
|
||||
|
||||
err = pthread_mutex_init(mp, &attr);
|
||||
if (err != 0) {
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
strerror_r(err, strbuf, sizeof(strbuf));
|
||||
isc_error_fatal(file, line, "pthread_mutex_init failed: %s",
|
||||
strbuf);
|
||||
}
|
||||
|
||||
fprintf(stderr, "mutex:init %p func %s file %s line %u\n", mp, func,
|
||||
file, line);
|
||||
|
||||
atomic_fetch_add_relaxed(&mutex_active, 1);
|
||||
}
|
||||
|
||||
void
|
||||
isc_mutex_destroy_debug(isc_mutex_t *mp, const char *func, const char *file,
|
||||
unsigned int line) {
|
||||
atomic_fetch_sub_release(&mutex_active, 1);
|
||||
|
||||
fprintf(stderr, "mutex:destroy %p func %s file %s line %u\n", mp, func,
|
||||
file, line);
|
||||
|
||||
pthread_mutex_destroy(mp);
|
||||
}
|
||||
|
||||
#elif ISC_MUTEX_PROFILE
|
||||
|
||||
/*@{*/
|
||||
/*% Operations on timevals; adapted from FreeBSD's sys/time.h */
|
||||
@@ -83,7 +152,7 @@ void
|
||||
isc_mutex_init_profile(isc_mutex_t *mp, const char *file, int line) {
|
||||
int i, err;
|
||||
|
||||
err = pthread_mutex_init(&mp->mutex, NULL);
|
||||
err = pthread_mutex_init(&mp->mutex, &attr);
|
||||
if (err != 0) {
|
||||
strerror_r(err, strbuf, sizeof(strbuf));
|
||||
isc_error_fatal(file, line, "pthread_mutex_init failed: %s",
|
||||
@@ -216,79 +285,13 @@ isc_mutex_statsprofile(FILE *fp) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ISC_MUTEX_PROFILE */
|
||||
|
||||
#if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)
|
||||
|
||||
static bool errcheck_initialized = false;
|
||||
static pthread_mutexattr_t errcheck;
|
||||
static isc_once_t once_errcheck = ISC_ONCE_INIT;
|
||||
|
||||
static void
|
||||
initialize_errcheck(void) {
|
||||
RUNTIME_CHECK(pthread_mutexattr_init(&errcheck) == 0);
|
||||
RUNTIME_CHECK(pthread_mutexattr_settype(&errcheck,
|
||||
PTHREAD_MUTEX_ERRORCHECK) == 0);
|
||||
errcheck_initialized = true;
|
||||
}
|
||||
|
||||
void
|
||||
isc_mutex_init_errcheck(isc_mutex_t *mp) {
|
||||
isc_result_t result;
|
||||
int err;
|
||||
|
||||
result = isc_once_do(&once_errcheck, initialize_errcheck);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
err = pthread_mutex_init(mp, &errcheck);
|
||||
if (err != 0) {
|
||||
strerror_r(err, strbuf, sizeof(strbuf));
|
||||
isc_error_fatal(file, line, "pthread_mutex_init failed: %s",
|
||||
strbuf);
|
||||
}
|
||||
}
|
||||
#endif /* if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK) */
|
||||
|
||||
#if ISC_MUTEX_DEBUG && defined(__NetBSD__) && defined(PTHREAD_MUTEX_ERRORCHECK)
|
||||
pthread_mutexattr_t isc__mutex_attrs = {
|
||||
PTHREAD_MUTEX_ERRORCHECK, /* m_type */
|
||||
0 /* m_flags, which appears to be unused. */
|
||||
};
|
||||
#endif /* if ISC_MUTEX_DEBUG && defined(__NetBSD__) && \
|
||||
* defined(PTHREAD_MUTEX_ERRORCHECK) */
|
||||
|
||||
#if !(ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)) && \
|
||||
!ISC_MUTEX_PROFILE
|
||||
|
||||
#ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP
|
||||
static bool attr_initialized = false;
|
||||
static pthread_mutexattr_t attr;
|
||||
static isc_once_t once_attr = ISC_ONCE_INIT;
|
||||
#endif /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */
|
||||
|
||||
#ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP
|
||||
static void
|
||||
initialize_attr(void) {
|
||||
RUNTIME_CHECK(pthread_mutexattr_init(&attr) == 0);
|
||||
RUNTIME_CHECK(pthread_mutexattr_settype(
|
||||
&attr, PTHREAD_MUTEX_ADAPTIVE_NP) == 0);
|
||||
attr_initialized = true;
|
||||
}
|
||||
#endif /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */
|
||||
#else
|
||||
|
||||
void
|
||||
isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line) {
|
||||
int err;
|
||||
|
||||
#ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
result = isc_once_do(&once_attr, initialize_attr);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
err = pthread_mutex_init(mp, &attr);
|
||||
#else /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */
|
||||
err = pthread_mutex_init(mp, ISC__MUTEX_ATTRS);
|
||||
#endif /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */
|
||||
if (err != 0) {
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
strerror_r(err, strbuf, sizeof(strbuf));
|
||||
@@ -296,5 +299,5 @@ isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line) {
|
||||
strbuf);
|
||||
}
|
||||
}
|
||||
#endif /* if !(ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)) && \
|
||||
* !ISC_MUTEX_PROFILE */
|
||||
|
||||
#endif
|
||||
|
||||
24
lib/isc/mutex_p.h
Normal file
24
lib/isc/mutex_p.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <isc/mem.h>
|
||||
|
||||
/*! \file */
|
||||
|
||||
void
|
||||
isc__mutex_initialize(void);
|
||||
|
||||
void
|
||||
isc__mutex_shutdown(void);
|
||||
@@ -379,6 +379,7 @@ nm_destroy(isc_nm_t **mgr0) {
|
||||
isc_mem_put(mgr->mctx, ievent, sizeof(*ievent));
|
||||
}
|
||||
isc_condition_destroy(&worker->cond_prio);
|
||||
isc_mutex_destroy(&worker->lock);
|
||||
|
||||
r = uv_loop_close(&worker->loop);
|
||||
INSIST(r == 0);
|
||||
|
||||
@@ -191,8 +191,9 @@ 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 *func, const char *file,
|
||||
unsigned int line) {
|
||||
REQUIRE(rwl != NULL);
|
||||
|
||||
/*
|
||||
@@ -221,13 +222,20 @@ isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
||||
isc_condition_init(&rwl->readable);
|
||||
isc_condition_init(&rwl->writeable);
|
||||
|
||||
fprintf(stderr, "rwlock:init %p func %s file %s line %u\n", rwl, func,
|
||||
file, line);
|
||||
|
||||
rwl->magic = RWLOCK_MAGIC;
|
||||
}
|
||||
|
||||
void
|
||||
isc_rwlock_destroy(isc_rwlock_t *rwl) {
|
||||
isc__rwlock_destroy(isc_rwlock_t *rwl, const char *func, const char *file,
|
||||
unsigned int line) {
|
||||
REQUIRE(VALID_RWLOCK(rwl));
|
||||
|
||||
fprintf(stderr, "rwlock:destroy %p func %s file %s line %u\n", rwl,
|
||||
func, file, line);
|
||||
|
||||
REQUIRE(atomic_load_acquire(&rwl->write_requests) ==
|
||||
atomic_load_acquire(&rwl->write_completions) &&
|
||||
atomic_load_acquire(&rwl->cnt_and_flag) == 0 &&
|
||||
|
||||
21
util/mutexleak.pl
Normal file
21
util/mutexleak.pl
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# 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 https://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
# Massage the output from ISC_MEM_DEBUG to extract mem_get() calls
|
||||
# with no corresponding mem_put().
|
||||
|
||||
while (<>) {
|
||||
$gets{$1} = $_ if (/mutex:init (?:0x)?([0-9a-f]+) func/);
|
||||
delete $gets{$1} if /mutex:destroy (?:0x)?([0-9a-f]+) func/;
|
||||
}
|
||||
print join('', values %gets);
|
||||
|
||||
exit(0);
|
||||
21
util/rwlockleak.pl
Normal file
21
util/rwlockleak.pl
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# 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 https://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
# Massage the output from ISC_MEM_DEBUG to extract mem_get() calls
|
||||
# with no corresponding mem_put().
|
||||
|
||||
while (<>) {
|
||||
$gets{$1} = $_ if (/rwlock:init (?:0x)?([0-9a-f]+) func/);
|
||||
delete $gets{$1} if /rwlock:destroy (?:0x)?([0-9a-f]+) func/;
|
||||
}
|
||||
print join('', values %gets);
|
||||
|
||||
exit(0);
|
||||
Reference in New Issue
Block a user