void GlobalRWLock::unlockWrite(thread_db* tdbb, const bool release) { SET_TDBB(tdbb); Database* dbb = tdbb->getDatabase(); Database::CheckoutLockGuard counterGuard(dbb, counterMutex); COS_TRACE(("(%p)->unlockWrite readers(%d), blocking(%d), pendingWriters(%d), currentWriter(%d), lck_physical(%d)", this, readers, blocking, pendingWriters, currentWriter, cachedLock->lck_physical)); currentWriter = false; if (!lockCaching || release) LCK_release(tdbb, cachedLock); else if (blocking) LCK_downgrade(tdbb, cachedLock); blocking = false; if (cachedLock->lck_physical < LCK_read) invalidate(tdbb); writerFinished.notifyAll(); COS_TRACE(("(%p)->unlockWrite end readers(%d), blocking(%d), pendingWriters(%d), currentWriter(%d), lck_physical(%d)", this, readers, blocking, pendingWriters, currentWriter, cachedLock->lck_physical)); }
void GlobalRWLock::blockingAstHandler(thread_db* tdbb) { SET_TDBB(tdbb); COS_TRACE(("(%p)->blockingAst enter", this)); COS_TRACE(("(%p)->blockingAst readers(%d), blocking(%d), pendingWriters(%d), currentWriter(%d), lck_physical(%d)", this, readers, blocking, pendingWriters, currentWriter, cachedLock->lck_physical)); if (!pendingLock && !currentWriter && !readers) { COS_TRACE(("(%p)->Downgrade lock", this)); LCK_downgrade(tdbb, cachedLock); fb_assert(!blocking); if (cachedLock->lck_physical < LCK_read) invalidate(tdbb); } else if (!pendingLock && !currentWriter && readers && cachedLock->lck_physical > LCK_read) { COS_TRACE(("(%p)->Convert lock to SR ", this)); if (!LCK_convert(tdbb, cachedLock, LCK_read, LCK_NO_WAIT)) { COS_TRACE(("(%p)->Set blocking", this)); blocking = true; } } else { COS_TRACE(("(%p)->Set blocking", this)); blocking = true; } }
int Database::SharedCounter::blockingAst(void* ast_object) { ValueCache* const counter = static_cast<ValueCache*>(ast_object); fb_assert(counter && counter->lock); Database* const dbb = counter->lock->lck_dbb; try { Database::SyncGuard dsGuard(dbb, true); ThreadContextHolder tdbb; tdbb->setDatabase(dbb); // tdbb->setAttachment(counter->lock->lck_attachment); Jrd::ContextPoolHolder context(tdbb, dbb->dbb_permanent); LCK_downgrade(tdbb, counter->lock); } catch (const Firebird::Exception&) {} // no-op return 0; }