]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
1492. [cleanup] Preserve rwlock quota context when upgrading /
authorMark Andrews <marka@isc.org>
Mon, 21 Jul 2003 01:14:18 +0000 (01:14 +0000)
committerMark Andrews <marka@isc.org>
Mon, 21 Jul 2003 01:14:18 +0000 (01:14 +0000)
                        downgrading. [RT #5599]

CHANGES
lib/isc/include/isc/rwlock.h
lib/isc/rwlock.c

diff --git a/CHANGES b/CHANGES
index 8e49dce8e5978b97ff9eec976ee8064d343b0f8a..77314c1c6b845ead1b2f78e803a2971e5a72903f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+1492.  [cleanup]       Preserve rwlock quota context when upgrading /
+                       downgrading. [RT #5599]
+
 1491.  [bug]           dns_master_dump*() would produce extraneous $ORIGIN
                        lines. [RT #6206]
 
index d84d4db2102e4fa1387ed7917f9d1cf21def612d..252bcc370790253499be8bb56ce7675e5e933141 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rwlock.h,v 1.19 2003/04/17 01:56:35 marka Exp $ */
+/* $Id: rwlock.h,v 1.20 2003/07/21 01:14:18 marka Exp $ */
 
 #ifndef ISC_RWLOCK_H
 #define ISC_RWLOCK_H 1
@@ -57,6 +57,7 @@ struct isc_rwlock {
        unsigned int            writers_waiting;
        unsigned int            read_quota;
        unsigned int            write_quota;
+       isc_rwlocktype_t        original;
 };
 #else /* ISC_PLATFORM_USETHREADS */
 struct isc_rwlock {
index 25172dcdd3692ce06639a31018e4d963ca856069..73c4ae6a7239aea2a13d28e92216d5619748e490 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rwlock.c,v 1.34 2003/04/17 01:56:34 marka Exp $ */
+/* $Id: rwlock.c,v 1.35 2003/07/21 01:14:18 marka Exp $ */
 
 #include <config.h>
 
@@ -82,6 +82,7 @@ isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
        rwl->magic = 0;
 
        rwl->type = isc_rwlocktype_read;
+       rwl->original = isc_rwlocktype_none;
        rwl->active = 0;
        rwl->granted = 0;
        rwl->readers_waiting = 0;
@@ -215,9 +216,11 @@ isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
        REQUIRE(rwl->active != 0);
 
        /* If we are the only reader then succeed. */
-       if (rwl->active == 1)
+       if (rwl->active == 1) {
+               rwl->original = (rwl->original == isc_rwlocktype_none) ?
+                               isc_rwlocktype_read : isc_rwlocktype_none;
                rwl->type = isc_rwlocktype_write;
-       else
+       else
                result = ISC_R_LOCKBUSY;
 
        UNLOCK(&rwl->lock);
@@ -233,10 +236,14 @@ isc_rwlock_downgrade(isc_rwlock_t *rwl) {
        REQUIRE(rwl->active == 1);
 
        rwl->type = isc_rwlocktype_read;
+       rwl->original = (rwl->original == isc_rwlocktype_none) ?
+                       isc_rwlocktype_write : isc_rwlocktype_none;
        /*
-        * Wake up waiting readers if there are no waiting writers.
+        * Resume processing any read request that were blocked when
+        * we upgraded.
         */
-       if ((rwl->writers_waiting == 0 || rwl->granted < rwl->read_quota) &&
+       if (rwl->original == isc_rwlocktype_none &&
+           (rwl->writers_waiting == 0 || rwl->granted < rwl->read_quota) &&
            rwl->readers_waiting > 0)
                BROADCAST(&rwl->readable);
 
@@ -260,6 +267,10 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
        INSIST(rwl->active > 0);
        rwl->active--;
        if (rwl->active == 0) {
+               if (rwl->original != isc_rwlocktype_none) {
+                       rwl->type = rwl->original;
+                       rwl->original = isc_rwlocktype_none;
+               }
                if (rwl->type == isc_rwlocktype_read) {
                        rwl->granted = 0;
                        if (rwl->writers_waiting > 0) {
@@ -287,6 +298,7 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
                        }
                }
        }
+       INSIST(rwl->original == isc_rwlock_none);
 
 #ifdef ISC_RWLOCK_TRACE
        print_lock(isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,