diff --git a/src/jrd/Database.cpp b/src/jrd/Database.cpp index 67d908fca3..c99129d08c 100644 --- a/src/jrd/Database.cpp +++ b/src/jrd/Database.cpp @@ -156,13 +156,18 @@ namespace Jrd lock->lck_object = counter; LCK_lock(tdbb, lock, LCK_PW, LCK_WAIT); + counter->isProtected = true; counter->curVal = 1; counter->maxVal = 0; } if (counter->curVal > counter->maxVal) { - LCK_convert(tdbb, counter->lock, LCK_PW, LCK_WAIT); + if (!counter->isProtected) + { + LCK_convert(tdbb, counter->lock, LCK_PW, LCK_WAIT); + counter->isProtected = true; + } counter->curVal = LCK_read_data(tdbb, counter->lock); @@ -192,6 +197,7 @@ namespace Jrd SyncLockGuard guard(&dbb->dbb_sh_counter_sync, SYNC_EXCLUSIVE, "Database::blockingAstSharedCounter"); LCK_downgrade(tdbb, counter->lock); + counter->isProtected = false; } catch (const Exception&) {} // no-op diff --git a/src/jrd/Database.h b/src/jrd/Database.h index 8858933d50..263bf7cf18 100644 --- a/src/jrd/Database.h +++ b/src/jrd/Database.h @@ -236,9 +236,10 @@ public: struct ValueCache { - Lock* lock; // lock which holds shared counter value - SLONG curVal; // current value of shared counter lock - SLONG maxVal; // maximum cached value of shared counter lock + Lock* lock; // lock which holds shared counter value + bool isProtected; // flag indicating that we own the lock in the PW mode + SLONG curVal; // current value of shared counter lock + SLONG maxVal; // maximum cached value of shared counter lock }; public: