mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Merge branch 'wpk-pthread-rwlock-optional' into 'master'
configure option to use pthread_rwlock instead of internal implementation See merge request isc-projects/bind9!1397
This commit is contained in:
commit
6c6d93b29d
5 changed files with 156 additions and 6 deletions
|
|
@ -309,6 +309,9 @@
|
|||
/* Have PTHREAD_PRIO_INHERIT. */
|
||||
#undef HAVE_PTHREAD_PRIO_INHERIT
|
||||
|
||||
/* Define to 1 if you have the `pthread_rwlock_rdlock' function. */
|
||||
#undef HAVE_PTHREAD_RWLOCK_RDLOCK
|
||||
|
||||
/* Define to 1 if you have the `pthread_setaffinity_np' function. */
|
||||
#undef HAVE_PTHREAD_SETAFFINITY_NP
|
||||
|
||||
|
|
@ -553,6 +556,9 @@
|
|||
/* define if PKCS11 is used for Public-Key Cryptography */
|
||||
#undef USE_PKCS11
|
||||
|
||||
/* Define if you want to use pthread rwlock implementation */
|
||||
#undef USE_PTHREAD_RWLOCK
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
|
|
|
|||
33
configure
vendored
33
configure
vendored
|
|
@ -900,6 +900,7 @@ enable_devpoll
|
|||
with_geoip
|
||||
with_locktype
|
||||
with_libtool
|
||||
enable_pthread_rwlock
|
||||
with_openssl
|
||||
enable_fips_mode
|
||||
with_cc_alg
|
||||
|
|
@ -1599,6 +1600,8 @@ Optional Features:
|
|||
--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]
|
||||
--enable-pthread-rwlock use pthread rwlock instead of internal rwlock
|
||||
implementation (EXPERIMENTAL)
|
||||
--enable-fips-mode enable FIPS mode in OpenSSL library [default=no]
|
||||
--enable-native-pkcs11 use native PKCS11 for public-key crypto [default=no]
|
||||
--enable-backtrace log stack backtrace on abort [default=yes]
|
||||
|
|
@ -15616,10 +15619,34 @@ esac
|
|||
|
||||
|
||||
#
|
||||
# If PIC is disabled, shared libraries must also be
|
||||
# Do we want to use pthread rwlock? (useful for ThreadSanitizer)
|
||||
#
|
||||
if test "$pic_mode" = "no"; then :
|
||||
enable_shared="no"
|
||||
# Check whether --enable-pthread_rwlock was given.
|
||||
if test "${enable_pthread_rwlock+set}" = set; then :
|
||||
enableval=$enable_pthread_rwlock;
|
||||
else
|
||||
enable_pthread_rwlock=no
|
||||
fi
|
||||
|
||||
|
||||
if test "$enable_pthread_rwlock" = "yes"; then :
|
||||
for ac_func in pthread_rwlock_rdlock
|
||||
do :
|
||||
ac_fn_c_check_func "$LINENO" "pthread_rwlock_rdlock" "ac_cv_func_pthread_rwlock_rdlock"
|
||||
if test "x$ac_cv_func_pthread_rwlock_rdlock" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_PTHREAD_RWLOCK_RDLOCK 1
|
||||
_ACEOF
|
||||
|
||||
else
|
||||
as_fn_error $? "pthread_rwlock_rdlock requested but not found" "$LINENO" 5
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
$as_echo "#define USE_PTHREAD_RWLOCK 1" >>confdefs.h
|
||||
|
||||
|
||||
fi
|
||||
|
||||
CRYPTO=OpenSSL
|
||||
|
|
|
|||
14
configure.ac
14
configure.ac
|
|
@ -734,10 +734,18 @@ esac
|
|||
AC_SUBST(INSTALL_LIBRARY)
|
||||
|
||||
#
|
||||
# If PIC is disabled, shared libraries must also be
|
||||
# Do we want to use pthread rwlock? (useful for ThreadSanitizer)
|
||||
#
|
||||
AS_IF([test "$pic_mode" = "no"],
|
||||
[enable_shared="no"])
|
||||
AC_ARG_ENABLE([pthread_rwlock],
|
||||
[AS_HELP_STRING([--enable-pthread-rwlock],
|
||||
[use pthread rwlock instead of internal rwlock implementation (EXPERIMENTAL)])],
|
||||
[], [enable_pthread_rwlock=no])
|
||||
|
||||
AS_IF([test "$enable_pthread_rwlock" = "yes"],
|
||||
[AC_CHECK_FUNCS([pthread_rwlock_rdlock], [],
|
||||
[AC_MSG_ERROR([pthread_rwlock_rdlock requested but not found])])
|
||||
AC_DEFINE([USE_PTHREAD_RWLOCK],[1],[Define if you want to use pthread rwlock implementation])
|
||||
])
|
||||
|
||||
CRYPTO=OpenSSL
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#define ISC_RWLOCK_H 1
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <pthread.h>
|
||||
|
||||
/*! \file isc/rwlock.h */
|
||||
|
||||
|
|
@ -31,6 +32,15 @@ typedef enum {
|
|||
isc_rwlocktype_write
|
||||
} isc_rwlocktype_t;
|
||||
|
||||
#if USE_PTHREAD_RWLOCK
|
||||
|
||||
struct isc_rwlock {
|
||||
pthread_rwlock_t rwlock;
|
||||
atomic_bool downgrade;
|
||||
};
|
||||
|
||||
#else /* USE_PTHREAD_RWLOCK */
|
||||
|
||||
struct isc_rwlock {
|
||||
/* Unlocked. */
|
||||
unsigned int magic;
|
||||
|
|
@ -68,6 +78,8 @@ struct isc_rwlock {
|
|||
|
||||
};
|
||||
|
||||
#endif /* USE_PTHREAD_RWLOCK */
|
||||
|
||||
isc_result_t
|
||||
isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
||||
unsigned int write_quota);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,101 @@
|
|||
#include <isc/rwlock.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#if USE_PTHREAD_RWLOCK
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
isc_result_t
|
||||
isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
||||
unsigned int write_quota)
|
||||
{
|
||||
UNUSED(read_quota);
|
||||
UNUSED(write_quota);
|
||||
REQUIRE(pthread_rwlock_init(&rwl->rwlock, NULL) == 0);
|
||||
atomic_init(&rwl->downgrade, false);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||
switch (type) {
|
||||
case isc_rwlocktype_read:
|
||||
REQUIRE(pthread_rwlock_rdlock(&rwl->rwlock) == 0);
|
||||
break;
|
||||
case isc_rwlocktype_write:
|
||||
while (true) {
|
||||
REQUIRE(pthread_rwlock_wrlock(&rwl->rwlock) == 0);
|
||||
/* Unlock if in middle of downgrade operation */
|
||||
if (atomic_load_release(&rwl->downgrade)) {
|
||||
REQUIRE(pthread_rwlock_unlock(&rwl->rwlock)
|
||||
== 0);
|
||||
while (atomic_load(&rwl->downgrade));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
INSIST(0);
|
||||
ISC_UNREACHABLE();
|
||||
}
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||
int ret = 0;
|
||||
switch (type) {
|
||||
case isc_rwlocktype_read:
|
||||
ret = pthread_rwlock_tryrdlock(&rwl->rwlock);
|
||||
break;
|
||||
case isc_rwlocktype_write:
|
||||
ret = pthread_rwlock_trywrlock(&rwl->rwlock);
|
||||
if ((ret == 0) && atomic_load(&rwl->downgrade)) {
|
||||
isc_rwlock_unlock(rwl, type);
|
||||
return (ISC_R_LOCKBUSY);
|
||||
}
|
||||
break;
|
||||
default: INSIST(0);
|
||||
}
|
||||
|
||||
switch (ret) {
|
||||
case 0: return (ISC_R_SUCCESS);
|
||||
case EBUSY: return (ISC_R_LOCKBUSY);
|
||||
case EAGAIN: return (ISC_R_LOCKBUSY);
|
||||
default: INSIST(0); ISC_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
isc_result_t
|
||||
isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||
UNUSED(type);
|
||||
REQUIRE(pthread_rwlock_unlock(&rwl->rwlock) == 0);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
|
||||
return (ISC_R_LOCKBUSY);
|
||||
}
|
||||
|
||||
void
|
||||
isc_rwlock_downgrade(isc_rwlock_t *rwl) {
|
||||
atomic_store_acquire(&rwl->downgrade, true);
|
||||
isc_rwlock_unlock(rwl, isc_rwlocktype_write);
|
||||
isc_rwlock_lock(rwl, isc_rwlocktype_read);
|
||||
atomic_store_acquire(&rwl->downgrade, false);
|
||||
}
|
||||
|
||||
void
|
||||
isc_rwlock_destroy(isc_rwlock_t *rwl) {
|
||||
pthread_rwlock_destroy(&rwl->rwlock);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define RWLOCK_MAGIC ISC_MAGIC('R', 'W', 'L', 'k')
|
||||
#define VALID_RWLOCK(rwl) ISC_MAGIC_VALID(rwl, RWLOCK_MAGIC)
|
||||
|
||||
|
|
@ -549,3 +644,5 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
#endif /* USE_PTHREAD_RWLOCK */
|
||||
|
|
|
|||
Loading…
Reference in a new issue