mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 22:15:20 +00:00
1461. [bug] Remove deadlock from rbtdb code. [RT #5999]
This commit is contained in:
2
CHANGES
2
CHANGES
@@ -1,3 +1,5 @@
|
||||
1461. [bug] Remove deadlock from rbtdb code. [RT #5999]
|
||||
|
||||
1460. [bug] inet_pton() failed to reject certian malformed
|
||||
IPv6 literals.
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rbtdb.c,v 1.186 2003/02/27 00:19:03 marka Exp $ */
|
||||
/* $Id: rbtdb.c,v 1.187 2003/04/17 01:56:34 marka Exp $ */
|
||||
|
||||
/*
|
||||
* Principal Author: Bob Halley
|
||||
@@ -815,10 +815,10 @@ no_references(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
||||
* we only do a trylock.
|
||||
*/
|
||||
if (lock == isc_rwlocktype_read)
|
||||
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
|
||||
|
||||
result = isc_rwlock_trylock(&rbtdb->tree_lock,
|
||||
isc_rwlocktype_write);
|
||||
result = isc_rwlock_tryupgrade(&rbtdb->tree_lock);
|
||||
else
|
||||
result = isc_rwlock_trylock(&rbtdb->tree_lock,
|
||||
isc_rwlocktype_write);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS ||
|
||||
result == ISC_R_LOCKBUSY);
|
||||
|
||||
@@ -849,12 +849,13 @@ no_references(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
||||
/*
|
||||
* Relock a read lock, or unlock the write lock if no lock was held.
|
||||
*/
|
||||
if (lock != isc_rwlocktype_write)
|
||||
if (lock == isc_rwlocktype_none)
|
||||
if (write_locked)
|
||||
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
|
||||
|
||||
if (lock == isc_rwlocktype_read)
|
||||
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
|
||||
if (write_locked)
|
||||
isc_rwlock_downgrade(&rbtdb->tree_lock);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rwlock.h,v 1.18 2001/03/08 00:55:15 tale Exp $ */
|
||||
/* $Id: rwlock.h,v 1.19 2003/04/17 01:56:35 marka Exp $ */
|
||||
|
||||
#ifndef ISC_RWLOCK_H
|
||||
#define ISC_RWLOCK_H 1
|
||||
@@ -80,6 +80,12 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
|
||||
isc_result_t
|
||||
isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
|
||||
|
||||
isc_result_t
|
||||
isc_rwlock_tryupgrade(isc_rwlock_t *rwl);
|
||||
|
||||
void
|
||||
isc_rwlock_downgrade(isc_rwlock_t *rwl);
|
||||
|
||||
void
|
||||
isc_rwlock_destroy(isc_rwlock_t *rwl);
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rwlock.c,v 1.33 2001/04/17 14:36:45 tale Exp $ */
|
||||
/* $Id: rwlock.c,v 1.34 2003/04/17 01:56:34 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -205,6 +205,44 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||
return (doit(rwl, type, ISC_TRUE));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
REQUIRE(VALID_RWLOCK(rwl));
|
||||
LOCK(&rwl->lock);
|
||||
REQUIRE(rwl->type == isc_rwlocktype_read);
|
||||
REQUIRE(rwl->active != 0);
|
||||
|
||||
/* If we are the only reader then succeed. */
|
||||
if (rwl->active == 1)
|
||||
rwl->type = isc_rwlocktype_write;
|
||||
else
|
||||
result = ISC_R_LOCKBUSY;
|
||||
|
||||
UNLOCK(&rwl->lock);
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
isc_rwlock_downgrade(isc_rwlock_t *rwl) {
|
||||
|
||||
REQUIRE(VALID_RWLOCK(rwl));
|
||||
LOCK(&rwl->lock);
|
||||
REQUIRE(rwl->type == isc_rwlocktype_write);
|
||||
REQUIRE(rwl->active == 1);
|
||||
|
||||
rwl->type = isc_rwlocktype_read;
|
||||
/*
|
||||
* Wake up waiting readers if there are no waiting writers.
|
||||
*/
|
||||
if ((rwl->writers_waiting == 0 || rwl->granted < rwl->read_quota) &&
|
||||
rwl->readers_waiting > 0)
|
||||
BROADCAST(&rwl->readable);
|
||||
|
||||
UNLOCK(&rwl->lock);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||
|
||||
@@ -318,6 +356,32 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||
return (isc_rwlock_lock(rwl, type));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
REQUIRE(VALID_RWLOCK(rwl));
|
||||
REQUIRE(rwl->type == isc_rwlocktype_read);
|
||||
REQUIRE(rwl->active != 0);
|
||||
|
||||
/* If we are the only reader then succeed. */
|
||||
if (rwl->active == 1)
|
||||
rwl->type = isc_rwlocktype_write;
|
||||
else
|
||||
result = ISC_R_LOCKBUSY;
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
isc_rwlock_downgrade(isc_rwlock_t *rwl) {
|
||||
|
||||
REQUIRE(VALID_RWLOCK(rwl));
|
||||
REQUIRE(rwl->type == isc_rwlocktype_write);
|
||||
REQUIRE(rwl->active == 1);
|
||||
|
||||
rwl->type = isc_rwlocktype_read;
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||
REQUIRE(VALID_RWLOCK(rwl));
|
||||
|
Reference in New Issue
Block a user