mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
Implement isc_rwlock_downgrade using pthreads and single atomic_bool
This commit is contained in:
@@ -39,15 +39,32 @@ isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
||||
UNUSED(read_quota);
|
||||
UNUSED(write_quota);
|
||||
REQUIRE(pthread_rwlock_init(&rwl->rwlock, NULL) == 0);
|
||||
atomic_init(&rwl->downgrade, false);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||
switch (type) {
|
||||
case isc_rwlocktype_read: REQUIRE(pthread_rwlock_rdlock(&rwl->rwlock) == 0); break;
|
||||
case isc_rwlocktype_write: REQUIRE(pthread_rwlock_wrlock(&rwl->rwlock) == 0); break;
|
||||
default: INSIST(0);
|
||||
case isc_rwlocktype_read:
|
||||
REQUIRE(pthread_rwlock_rdlock(&rwl->rwlock) == 0);
|
||||
break;
|
||||
case isc_rwlocktype_write:
|
||||
while (true) {
|
||||
REQUIRE(pthread_rwlock_wrlock(&rwl->rwlock) == 0);
|
||||
/* Unlock if in middle of downgrade operation */
|
||||
if (atomic_load_release(&rwl->downgrade)) {
|
||||
REQUIRE(pthread_rwlock_unlock(&rwl->rwlock)
|
||||
== 0);
|
||||
while (atomic_load(&rwl->downgrade));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
INSIST(0);
|
||||
ISC_UNREACHABLE();
|
||||
}
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
@@ -61,6 +78,10 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||
break;
|
||||
case isc_rwlocktype_write:
|
||||
ret = pthread_rwlock_trywrlock(&rwl->rwlock);
|
||||
if ((ret == 0) && atomic_load(&rwl->downgrade)) {
|
||||
isc_rwlock_unlock(rwl, type);
|
||||
return (ISC_R_LOCKBUSY);
|
||||
}
|
||||
break;
|
||||
default: INSIST(0);
|
||||
}
|
||||
@@ -88,8 +109,10 @@ isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
|
||||
|
||||
void
|
||||
isc_rwlock_downgrade(isc_rwlock_t *rwl) {
|
||||
atomic_store_acquire(&rwl->downgrade, true);
|
||||
isc_rwlock_unlock(rwl, isc_rwlocktype_write);
|
||||
isc_rwlock_lock(rwl, isc_rwlocktype_read);
|
||||
atomic_store_acquire(&rwl->downgrade, false);
|
||||
}
|
||||
|
||||
void
|
||||
|
Reference in New Issue
Block a user