mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-02 15:45:25 +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
|
1460. [bug] inet_pton() failed to reject certian malformed
|
||||||
IPv6 literals.
|
IPv6 literals.
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* 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
|
* Principal Author: Bob Halley
|
||||||
@@ -815,10 +815,10 @@ no_references(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
|||||||
* we only do a trylock.
|
* we only do a trylock.
|
||||||
*/
|
*/
|
||||||
if (lock == isc_rwlocktype_read)
|
if (lock == isc_rwlocktype_read)
|
||||||
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
|
result = isc_rwlock_tryupgrade(&rbtdb->tree_lock);
|
||||||
|
else
|
||||||
result = isc_rwlock_trylock(&rbtdb->tree_lock,
|
result = isc_rwlock_trylock(&rbtdb->tree_lock,
|
||||||
isc_rwlocktype_write);
|
isc_rwlocktype_write);
|
||||||
RUNTIME_CHECK(result == ISC_R_SUCCESS ||
|
RUNTIME_CHECK(result == ISC_R_SUCCESS ||
|
||||||
result == ISC_R_LOCKBUSY);
|
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.
|
* 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)
|
if (write_locked)
|
||||||
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
|
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
|
||||||
|
|
||||||
if (lock == isc_rwlocktype_read)
|
if (lock == isc_rwlocktype_read)
|
||||||
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
|
if (write_locked)
|
||||||
|
isc_rwlock_downgrade(&rbtdb->tree_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* 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
|
#ifndef ISC_RWLOCK_H
|
||||||
#define ISC_RWLOCK_H 1
|
#define ISC_RWLOCK_H 1
|
||||||
@@ -80,6 +80,12 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
|
|||||||
isc_result_t
|
isc_result_t
|
||||||
isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
|
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
|
void
|
||||||
isc_rwlock_destroy(isc_rwlock_t *rwl);
|
isc_rwlock_destroy(isc_rwlock_t *rwl);
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* 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>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -205,6 +205,44 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
return (doit(rwl, type, ISC_TRUE));
|
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_result_t
|
||||||
isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
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));
|
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_result_t
|
||||||
isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||||
REQUIRE(VALID_RWLOCK(rwl));
|
REQUIRE(VALID_RWLOCK(rwl));
|
||||||
|
Reference in New Issue
Block a user