2
0
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:
Ondřej Surý
2018-11-22 11:42:12 +01:00
parent 64fbffbbaa
commit 4501f646ee
2 changed files with 27 additions and 3 deletions

View File

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