8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-02 10:00:38 +01:00

Move EngineContextHolder (and AttachmentHolder) to jrd.h.

This commit is contained in:
Adriano dos Santos Fernandes 2022-05-31 22:38:16 -03:00
parent b3654c48e8
commit a0ade0c8f9
2 changed files with 123 additions and 112 deletions

View File

@ -710,118 +710,6 @@ namespace
validateHandle(tdbb, applier->getAttachment());
}
class AttachmentHolder
{
public:
static const unsigned ATT_LOCK_ASYNC = 1;
static const unsigned ATT_DONT_LOCK = 2;
static const unsigned ATT_NO_SHUTDOWN_CHECK = 4;
static const unsigned ATT_NON_BLOCKING = 8;
AttachmentHolder(thread_db* tdbb, StableAttachmentPart* sa, unsigned lockFlags, const char* from)
: sAtt(sa),
async(lockFlags & ATT_LOCK_ASYNC),
nolock(lockFlags & ATT_DONT_LOCK),
blocking(!(lockFlags & ATT_NON_BLOCKING))
{
if (!sa)
Arg::Gds(isc_att_shutdown).raise();
if (blocking)
sAtt->getBlockingMutex()->enter(from);
try
{
if (!nolock)
sAtt->getSync(async)->enter(from);
Jrd::Attachment* attachment = sAtt->getHandle(); // Must be done after entering mutex
try
{
if (!attachment || (engineShutdown && !(lockFlags & ATT_NO_SHUTDOWN_CHECK)))
{
// This shutdown check is an optimization, threads can still enter engine
// with the flag set cause shutdownMutex mutex is not locked here.
// That's not a danger cause check of att_use_count
// in shutdown code makes it anyway safe.
Arg::Gds err(isc_att_shutdown);
if (sAtt->getShutError())
err << Arg::Gds(sAtt->getShutError());
err.raise();
}
tdbb->setAttachment(attachment);
tdbb->setDatabase(attachment->att_database);
if (!async)
{
attachment->att_use_count++;
attachment->setupIdleTimer(true);
}
}
catch (const Firebird::Exception&)
{
if (!nolock)
sAtt->getSync(async)->leave();
throw;
}
}
catch (const Firebird::Exception&)
{
if (blocking)
sAtt->getBlockingMutex()->leave();
throw;
}
}
~AttachmentHolder()
{
Jrd::Attachment* attachment = sAtt->getHandle();
if (attachment && !async)
{
attachment->att_use_count--;
if (!attachment->att_use_count)
attachment->setupIdleTimer(false);
}
if (!nolock)
sAtt->getSync(async)->leave();
if (blocking)
sAtt->getBlockingMutex()->leave();
}
private:
RefPtr<StableAttachmentPart> sAtt;
bool async; // async mutex should be locked instead normal
bool nolock; // if locked manually, no need to take lock recursively
bool blocking; // holder instance is blocking other instances
private:
// copying is prohibited
AttachmentHolder(const AttachmentHolder&);
AttachmentHolder& operator =(const AttachmentHolder&);
};
class EngineContextHolder : public ThreadContextHolder, private AttachmentHolder,
private DatabaseContextHolder
{
public:
template <typename I>
EngineContextHolder(CheckStatusWrapper* status, I* interfacePtr, const char* from,
unsigned lockFlags = 0)
: ThreadContextHolder(status),
AttachmentHolder(*this, interfacePtr->getAttachment(), lockFlags, from),
DatabaseContextHolder(operator thread_db*())
{
validateHandle(*this, interfacePtr->getHandle());
}
};
void validateAccess(thread_db* tdbb, Jrd::Attachment* attachment, SystemPrivilege sp)
{
if (!attachment->locksmith(tdbb, sp))
@ -865,6 +753,98 @@ namespace
} // anonymous
AttachmentHolder::AttachmentHolder(thread_db* tdbb, StableAttachmentPart* sa, unsigned lockFlags, const char* from)
: sAtt(sa),
async(lockFlags & ATT_LOCK_ASYNC),
nolock(lockFlags & ATT_DONT_LOCK),
blocking(!(lockFlags & ATT_NON_BLOCKING))
{
if (!sa)
Arg::Gds(isc_att_shutdown).raise();
if (blocking)
sAtt->getBlockingMutex()->enter(from);
try
{
if (!nolock)
sAtt->getSync(async)->enter(from);
Jrd::Attachment* attachment = sAtt->getHandle(); // Must be done after entering mutex
try
{
if (!attachment || (engineShutdown && !(lockFlags & ATT_NO_SHUTDOWN_CHECK)))
{
// This shutdown check is an optimization, threads can still enter engine
// with the flag set cause shutdownMutex mutex is not locked here.
// That's not a danger cause check of att_use_count
// in shutdown code makes it anyway safe.
Arg::Gds err(isc_att_shutdown);
if (sAtt->getShutError())
err << Arg::Gds(sAtt->getShutError());
err.raise();
}
tdbb->setAttachment(attachment);
tdbb->setDatabase(attachment->att_database);
if (!async)
{
attachment->att_use_count++;
attachment->setupIdleTimer(true);
}
}
catch (const Firebird::Exception&)
{
if (!nolock)
sAtt->getSync(async)->leave();
throw;
}
}
catch (const Firebird::Exception&)
{
if (blocking)
sAtt->getBlockingMutex()->leave();
throw;
}
}
AttachmentHolder::~AttachmentHolder()
{
Jrd::Attachment* attachment = sAtt->getHandle();
if (attachment && !async)
{
attachment->att_use_count--;
if (!attachment->att_use_count)
attachment->setupIdleTimer(false);
}
if (!nolock)
sAtt->getSync(async)->leave();
if (blocking)
sAtt->getBlockingMutex()->leave();
}
template <typename I>
EngineContextHolder::EngineContextHolder(CheckStatusWrapper* status, I* interfacePtr, const char* from,
unsigned lockFlags)
: ThreadContextHolder(status),
AttachmentHolder(*this, interfacePtr->getAttachment(), lockFlags, from),
DatabaseContextHolder(operator thread_db*())
{
validateHandle(*this, interfacePtr->getHandle());
}
// Used in ProfilerManager.cpp
template EngineContextHolder::EngineContextHolder(
CheckStatusWrapper* status, JAttachment* interfacePtr, const char* from, unsigned lockFlags);
#ifdef WIN_NT
#include <windows.h>
// these should stop a most annoying warning

View File

@ -1029,6 +1029,37 @@ namespace Jrd {
BackgroundContextHolder& operator=(const BackgroundContextHolder&);
};
class AttachmentHolder
{
public:
static const unsigned ATT_LOCK_ASYNC = 1;
static const unsigned ATT_DONT_LOCK = 2;
static const unsigned ATT_NO_SHUTDOWN_CHECK = 4;
static const unsigned ATT_NON_BLOCKING = 8;
AttachmentHolder(thread_db* tdbb, StableAttachmentPart* sa, unsigned lockFlags, const char* from);
~AttachmentHolder();
private:
Firebird::RefPtr<StableAttachmentPart> sAtt;
bool async; // async mutex should be locked instead normal
bool nolock; // if locked manually, no need to take lock recursively
bool blocking; // holder instance is blocking other instances
private:
// copying is prohibited
AttachmentHolder(const AttachmentHolder&);
AttachmentHolder& operator =(const AttachmentHolder&);
};
class EngineContextHolder final : public ThreadContextHolder, private AttachmentHolder, private DatabaseContextHolder
{
public:
template <typename I>
EngineContextHolder(Firebird::CheckStatusWrapper* status, I* interfacePtr, const char* from,
unsigned lockFlags = 0);
};
class AstLockHolder : public Firebird::ReadLockGuard
{
public: