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;
	}
}
Exemple #3
0
	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;
	}