Initialize pthread_mutexattrs just once (#38547)

This commit is contained in:
Mukund Sivaraman 2015-02-26 14:43:45 +05:30
parent db93c0def5
commit 07dd40e8ee
4 changed files with 73 additions and 47 deletions

View file

@ -1,3 +1,6 @@
4071. [cleanup] Initialize pthread mutex attrs just once, instead of
doing it per mutex creation. [RT #38547]
4070. [bug] Fix a segfault in nslookup in a query such as
"nslookup isc.org AMS.SNS-PB.ISC.ORG -all".
[RT #38548]

View file

@ -189,8 +189,7 @@ dns_test_end(void) {
* Create a view.
*/
isc_result_t
dns_test_makeview(const char *name, dns_view_t **viewp)
{
dns_test_makeview(const char *name, dns_view_t **viewp) {
isc_result_t result;
dns_view_t *view = NULL;

View file

@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: mutex.h,v 1.6 2007/06/19 23:47:18 tbox Exp $ */
#ifndef ISC_MUTEX_H
#define ISC_MUTEX_H 1

View file

@ -29,29 +29,30 @@
#include <isc/mutex.h>
#include <isc/util.h>
#include <isc/strerror.h>
#include <isc/once.h>
#if ISC_MUTEX_PROFILE
/*@{*/
/*% Operations on timevals; adapted from FreeBSD's sys/time.h */
#define timevalclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
#define timevaladd(vvp, uvp) \
do { \
(vvp)->tv_sec += (uvp)->tv_sec; \
(vvp)->tv_usec += (uvp)->tv_usec; \
if ((vvp)->tv_usec >= 1000000) { \
(vvp)->tv_sec++; \
(vvp)->tv_usec -= 1000000; \
} \
#define timevaladd(vvp, uvp) \
do { \
(vvp)->tv_sec += (uvp)->tv_sec; \
(vvp)->tv_usec += (uvp)->tv_usec; \
if ((vvp)->tv_usec >= 1000000) { \
(vvp)->tv_sec++; \
(vvp)->tv_usec -= 1000000; \
} \
} while (0)
#define timevalsub(vvp, uvp) \
do { \
(vvp)->tv_sec -= (uvp)->tv_sec; \
(vvp)->tv_usec -= (uvp)->tv_usec; \
if ((vvp)->tv_usec < 0) { \
(vvp)->tv_sec--; \
(vvp)->tv_usec += 1000000; \
} \
#define timevalsub(vvp, uvp) \
do { \
(vvp)->tv_sec -= (uvp)->tv_sec; \
(vvp)->tv_usec -= (uvp)->tv_usec; \
if ((vvp)->tv_usec < 0) { \
(vvp)->tv_sec--; \
(vvp)->tv_usec += 1000000; \
} \
} while (0)
/*@}*/
@ -68,7 +69,7 @@ typedef struct {
struct isc_mutexstats {
const char * file; /*%< File mutex was created in. */
int line; /*%< Line mutex was created on. */
int line; /*%< Line mutex was created on. */
unsigned count;
struct timeval lock_t;
struct timeval locked_total;
@ -225,24 +226,35 @@ isc_mutex_statsprofile(FILE *fp) {
#endif /* ISC_MUTEX_PROFILE */
#if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)
isc_result_t
isc_mutex_init_errcheck(isc_mutex_t *mp)
{
pthread_mutexattr_t attr;
int err, errd;
if (pthread_mutexattr_init(&attr) != 0)
return (ISC_R_UNEXPECTED);
static isc_boolean_t errcheck_initialized = ISC_FALSE;
static pthread_mutexattr_t errcheck;
static isc_once_t once_errcheck = ISC_ONCE_INIT;
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0) {
errd = pthread_mutexattr_destroy(&attr);
RUNTIME_CHECK(errd == 0);
return (ISC_R_UNEXPECTED);
static void
destroy_errcheck(void) {
if (errcheck_initialized) {
RUNTIME_CHECK(pthread_mutexattr_destroy(&errcheck) == 0);
}
}
err = pthread_mutex_init(mp, &attr) != 0)
errd = pthread_mutexattr_destroy(&attr);
RUNTIME_CHECK(errd == 0);
static void
initialize_errcheck(void) {
RUNTIME_CHECK(pthread_mutexattr_init(&errcheck) == 0);
RUNTIME_CHECK(pthread_mutexattr_settype
(&errcheck, PTHREAD_MUTEX_ERRORCHECK) == 0);
errcheck_initialized = ISC_TRUE;
}
isc_result_t
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 == ENOMEM)
return (ISC_R_NOMEMORY);
return ((err == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED);
@ -257,25 +269,39 @@ pthread_mutexattr_t isc__mutex_attrs = {
#endif
#if !(ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)) && !ISC_MUTEX_PROFILE
static isc_boolean_t attr_initialized = ISC_FALSE;
static pthread_mutexattr_t attr;
static isc_once_t once_attr = ISC_ONCE_INIT;
static void
destroy_attr(void) {
if (attr_initialized) {
RUNTIME_CHECK(pthread_mutexattr_destroy(&attr) == 0);
}
}
#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 = ISC_TRUE;
}
#endif /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */
isc_result_t
isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line) {
char strbuf[ISC_STRERRORSIZE];
isc_result_t result = ISC_R_SUCCESS;
int err;
#ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP
pthread_mutexattr_t attr;
int errd;
if (pthread_mutexattr_init(&attr) != 0)
return (ISC_R_UNEXPECTED);
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP) != 0) {
errd = pthread_mutexattr_destroy(&attr);
RUNTIME_CHECK(errd == 0);
return (ISC_R_UNEXPECTED);
}
#ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP
result = isc_once_do(&once_attr, initialize_attr);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
err = pthread_mutex_init(mp, &attr);
errd = pthread_mutexattr_destroy(&attr);
RUNTIME_CHECK(errd == 0);
#else /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */
err = pthread_mutex_init(mp, ISC__MUTEX_ATTRS);
#endif /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */