2
0
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:
Mark Andrews
2003-04-17 01:56:35 +00:00
parent 444d2ad833
commit 163547c0c0
4 changed files with 82 additions and 9 deletions

View File

@@ -1,3 +1,5 @@
1461. [bug] Remove deadlock from rbtdb code. [RT #5999]
1460. [bug] inet_pton() failed to reject certian malformed
IPv6 literals.

View File

@@ -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

View File

@@ -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);

View File

@@ -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));