diff --git a/lib/isc/rwlock.c b/lib/isc/rwlock.c index 3b3b342627..5b3ce61f60 100644 --- a/lib/isc/rwlock.c +++ b/lib/isc/rwlock.c @@ -1,4 +1,6 @@ +#include + #include #include #include @@ -15,21 +17,23 @@ #define WAIT(cvp, lp) \ INSIST(isc_condition_wait((cvp), (lp)) == ISC_R_SUCCESS); -#include +#define RWLOCK_MAGIC 0x52574C6BU /* RWLk. */ +#define VALID_RWLOCK(rwl) ((rwl) != NULL && \ + (rwl)->magic == RWLOCK_MAGIC) +#ifdef ISC_RWLOCK_TRACE static void print_lock(char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) { printf("%s(%s): ", operation, (type == isc_rwlocktype_read ? "read" : "write")); - printf("%s, %u active", + printf("%s, %u active, %u granted", (rwl->type == isc_rwlocktype_read ? "reading" : "writing"), - rwl->active); - if (rwl->type == isc_rwlocktype_read) - printf(", %u granted", rwl->granted); + rwl->active, rwl->granted); printf(", %u rwaiting, %u wwaiting\n", rwl->readers_waiting, rwl->writers_waiting); } +#endif isc_result_t isc_rwlock_init(isc_rwlock_t *rwl, @@ -40,6 +44,12 @@ isc_rwlock_init(isc_rwlock_t *rwl, REQUIRE(rwl != NULL); + /* + * In case there's trouble initializing, we zero magic now. If all + * goes well, we'll set it to RWLOCK_MAGIC. + */ + rwl->magic = 0; + rwl->type = isc_rwlocktype_read; rwl->active = 0; rwl->granted = 0; @@ -73,6 +83,8 @@ isc_rwlock_init(isc_rwlock_t *rwl, return (ISC_R_UNEXPECTED); } + rwl->magic = RWLOCK_MAGIC; + return (ISC_R_SUCCESS); } @@ -81,9 +93,11 @@ isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { isc_boolean_t skip = ISC_FALSE; isc_boolean_t done = ISC_FALSE; + REQUIRE(VALID_RWLOCK(rwl)); + LOCK(&rwl->lock); -#ifdef DEBUG +#ifdef ISC_RWLOCK_TRACE print_lock("prelock", rwl, type); #endif @@ -124,7 +138,7 @@ isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { } } -#ifdef DEBUG +#ifdef ISC_RWLOCK_TRACE print_lock("postlock", rwl, type); #endif @@ -135,10 +149,12 @@ isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { isc_result_t isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { + + REQUIRE(VALID_RWLOCK(rwl)); LOCK(&rwl->lock); REQUIRE(rwl->type == type); -#ifdef DEBUG +#ifdef ISC_RWLOCK_TRACE print_lock("preunlock", rwl, type); #endif @@ -166,6 +182,8 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { } else if (rwl->writers_waiting > 0) { rwl->granted = 0; SIGNAL(&rwl->writeable); + } else { + rwl->granted = 0; } } } else { @@ -178,7 +196,7 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { } } -#ifdef DEBUG +#ifdef ISC_RWLOCK_TRACE print_lock("postunlock", rwl, type); #endif @@ -189,11 +207,15 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { void isc_rwlock_destroy(isc_rwlock_t *rwl) { + + REQUIRE(VALID_RWLOCK(rwl)); LOCK(&rwl->lock); REQUIRE(rwl->active == 0 && rwl->readers_waiting == 0 && rwl->writers_waiting == 0); UNLOCK(&rwl->lock); + + rwl->magic = 0; (void)isc_condition_destroy(&rwl->readable); (void)isc_condition_destroy(&rwl->writeable); (void)isc_mutex_destroy(&rwl->lock);