mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 14:03:07 +01:00
Backported fix for #6947: Query to mon$ tables does not return data when the encryption/decryption thread is running
This commit is contained in:
parent
d9d3c6cf65
commit
77118ed5fb
@ -210,7 +210,10 @@ void Thread::kill(Handle& thread)
|
|||||||
ThreadId Thread::getId()
|
ThreadId Thread::getId()
|
||||||
{
|
{
|
||||||
#ifdef USE_LWP_AS_THREAD_ID
|
#ifdef USE_LWP_AS_THREAD_ID
|
||||||
return syscall(SYS_gettid);
|
static __thread int tid = 0;
|
||||||
|
if (!tid)
|
||||||
|
tid = syscall(SYS_gettid);
|
||||||
|
return tid;
|
||||||
#else
|
#else
|
||||||
return pthread_self();
|
return pthread_self();
|
||||||
#endif
|
#endif
|
||||||
|
@ -101,7 +101,7 @@ namespace Firebird
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Mtx, typename RefCounted = DefaultRefCounted<Mtx> >
|
template <typename Mtx, template <typename T> class RefCounted = DefaultRefCounted >
|
||||||
class EnsureUnlock
|
class EnsureUnlock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -114,14 +114,14 @@ namespace Firebird
|
|||||||
#define FB_LOCKED_FROM NULL
|
#define FB_LOCKED_FROM NULL
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
RefCounted::addRef(m_mutex);
|
RefCounted<Mtx>::addRef(m_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
~EnsureUnlock()
|
~EnsureUnlock()
|
||||||
{
|
{
|
||||||
while (m_locked)
|
while (m_locked)
|
||||||
leave();
|
leave();
|
||||||
RefCounted::release(m_mutex);
|
RefCounted<Mtx>::release(m_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void enter()
|
void enter()
|
||||||
@ -155,7 +155,7 @@ namespace Firebird
|
|||||||
};
|
};
|
||||||
#undef FB_LOCKED_FROM
|
#undef FB_LOCKED_FROM
|
||||||
|
|
||||||
typedef EnsureUnlock<Mutex, NotRefCounted<Mutex> > MutexEnsureUnlock;
|
typedef EnsureUnlock<Mutex, NotRefCounted> MutexEnsureUnlock;
|
||||||
typedef EnsureUnlock<RefMutex> RefMutexEnsureUnlock;
|
typedef EnsureUnlock<RefMutex> RefMutexEnsureUnlock;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -89,7 +89,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef RaiiLockGuard<XThreadMutex> XThreadLockGuard;
|
typedef RaiiLockGuard<XThreadMutex> XThreadLockGuard;
|
||||||
typedef EnsureUnlock<XThreadMutex, NotRefCounted<XThreadMutex> > XThreadEnsureUnlock;
|
typedef EnsureUnlock<XThreadMutex, NotRefCounted> XThreadEnsureUnlock;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +320,7 @@ typedef Mutex Spinlock;
|
|||||||
#endif //WIN_NT
|
#endif //WIN_NT
|
||||||
|
|
||||||
|
|
||||||
// RAII holder
|
// RAII holders
|
||||||
template <typename M>
|
template <typename M>
|
||||||
class RaiiLockGuard
|
class RaiiLockGuard
|
||||||
{
|
{
|
||||||
@ -363,10 +363,12 @@ private:
|
|||||||
|
|
||||||
typedef RaiiLockGuard<Mutex> MutexLockGuard;
|
typedef RaiiLockGuard<Mutex> MutexLockGuard;
|
||||||
|
|
||||||
class MutexUnlockGuard
|
|
||||||
|
template <typename M>
|
||||||
|
class RaiiUnlockGuard
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit MutexUnlockGuard(Mutex& aLock, const char* aReason)
|
explicit RaiiUnlockGuard(M& aLock, const char* aReason)
|
||||||
: lock(&aLock)
|
: lock(&aLock)
|
||||||
#ifdef DEV_BUILD
|
#ifdef DEV_BUILD
|
||||||
, saveReason(aReason)
|
, saveReason(aReason)
|
||||||
@ -375,7 +377,7 @@ public:
|
|||||||
lock->leave();
|
lock->leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
~MutexUnlockGuard()
|
~RaiiUnlockGuard()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -393,15 +395,17 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Forbid copying
|
// Forbid copying
|
||||||
MutexUnlockGuard(const MutexUnlockGuard&);
|
RaiiUnlockGuard(const RaiiUnlockGuard&);
|
||||||
MutexUnlockGuard& operator=(const MutexUnlockGuard&);
|
RaiiUnlockGuard& operator=(const RaiiUnlockGuard&);
|
||||||
|
|
||||||
Mutex* lock;
|
M* lock;
|
||||||
#ifdef DEV_BUILD
|
#ifdef DEV_BUILD
|
||||||
const char* saveReason;
|
const char* saveReason;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef RaiiUnlockGuard<Mutex> MutexUnlockGuard;
|
||||||
|
|
||||||
|
|
||||||
class MutexCheckoutGuard
|
class MutexCheckoutGuard
|
||||||
{
|
{
|
||||||
|
@ -989,10 +989,10 @@ void Jrd::Attachment::SyncGuard::init(const char* f, bool
|
|||||||
|
|
||||||
if (jStable)
|
if (jStable)
|
||||||
{
|
{
|
||||||
jStable->getMutex()->enter(f);
|
jStable->getSync()->enter(f);
|
||||||
if (!jStable->getHandle())
|
if (!jStable->getHandle())
|
||||||
{
|
{
|
||||||
jStable->getMutex()->leave();
|
jStable->getSync()->leave();
|
||||||
Arg::Gds(isc_att_shutdown).raise();
|
Arg::Gds(isc_att_shutdown).raise();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1004,13 +1004,13 @@ void StableAttachmentPart::manualLock(ULONG& flags, const ULONG whatLock)
|
|||||||
|
|
||||||
if (whatLock & ATT_async_manual_lock)
|
if (whatLock & ATT_async_manual_lock)
|
||||||
{
|
{
|
||||||
asyncMutex.enter(FB_FUNCTION);
|
async.enter(FB_FUNCTION);
|
||||||
flags |= ATT_async_manual_lock;
|
flags |= ATT_async_manual_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (whatLock & ATT_manual_lock)
|
if (whatLock & ATT_manual_lock)
|
||||||
{
|
{
|
||||||
mainMutex.enter(FB_FUNCTION);
|
mainSync.enter(FB_FUNCTION);
|
||||||
flags |= ATT_manual_lock;
|
flags |= ATT_manual_lock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1020,7 +1020,7 @@ void StableAttachmentPart::manualUnlock(ULONG& flags)
|
|||||||
if (flags & ATT_manual_lock)
|
if (flags & ATT_manual_lock)
|
||||||
{
|
{
|
||||||
flags &= ~ATT_manual_lock;
|
flags &= ~ATT_manual_lock;
|
||||||
mainMutex.leave();
|
mainSync.leave();
|
||||||
}
|
}
|
||||||
manualAsyncUnlock(flags);
|
manualAsyncUnlock(flags);
|
||||||
}
|
}
|
||||||
@ -1030,7 +1030,7 @@ void StableAttachmentPart::manualAsyncUnlock(ULONG& flags)
|
|||||||
if (flags & ATT_async_manual_lock)
|
if (flags & ATT_async_manual_lock)
|
||||||
{
|
{
|
||||||
flags &= ~ATT_async_manual_lock;
|
flags &= ~ATT_async_manual_lock;
|
||||||
asyncMutex.leave();
|
async.leave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1038,7 +1038,7 @@ void StableAttachmentPart::onIdleTimer(TimerImpl*)
|
|||||||
{
|
{
|
||||||
// Ensure attachment is still alive and still idle
|
// Ensure attachment is still alive and still idle
|
||||||
|
|
||||||
MutexEnsureUnlock guard(*this->getMutex(), FB_FUNCTION);
|
EnsureUnlock<Sync, NotRefCounted> guard(*this->getSync(), FB_FUNCTION);
|
||||||
if (!guard.tryEnter())
|
if (!guard.tryEnter())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -203,6 +203,107 @@ private:
|
|||||||
class StableAttachmentPart : public Firebird::RefCounted, public Firebird::GlobalStorage
|
class StableAttachmentPart : public Firebird::RefCounted, public Firebird::GlobalStorage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
class Sync
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Sync()
|
||||||
|
: waiters(0), threadId(0), totalLocksCounter(0), currentLocksCounter(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void enter(const char* aReason)
|
||||||
|
{
|
||||||
|
ThreadId curTid = getThreadId();
|
||||||
|
|
||||||
|
if (threadId == curTid)
|
||||||
|
{
|
||||||
|
currentLocksCounter++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (threadId || !syncMutex.tryEnter(aReason))
|
||||||
|
{
|
||||||
|
// we have contention with another thread
|
||||||
|
waiters.fetch_add(1, std::memory_order_relaxed);
|
||||||
|
syncMutex.enter(aReason);
|
||||||
|
waiters.fetch_sub(1, std::memory_order_relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
threadId = curTid;
|
||||||
|
totalLocksCounter++;
|
||||||
|
fb_assert(currentLocksCounter == 0);
|
||||||
|
currentLocksCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tryEnter(const char* aReason)
|
||||||
|
{
|
||||||
|
ThreadId curTid = getThreadId();
|
||||||
|
|
||||||
|
if (threadId == curTid)
|
||||||
|
{
|
||||||
|
currentLocksCounter++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (threadId || !syncMutex.tryEnter(aReason))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
threadId = curTid;
|
||||||
|
totalLocksCounter++;
|
||||||
|
fb_assert(currentLocksCounter == 0);
|
||||||
|
currentLocksCounter++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void leave()
|
||||||
|
{
|
||||||
|
fb_assert(currentLocksCounter > 0);
|
||||||
|
|
||||||
|
if (--currentLocksCounter == 0)
|
||||||
|
{
|
||||||
|
threadId = 0;
|
||||||
|
syncMutex.leave();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasContention() const
|
||||||
|
{
|
||||||
|
return (waiters.load(std::memory_order_relaxed) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
FB_UINT64 getLockCounter() const
|
||||||
|
{
|
||||||
|
return totalLocksCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEV_BUILD
|
||||||
|
bool locked() const
|
||||||
|
{
|
||||||
|
return threadId == getThreadId();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
~Sync()
|
||||||
|
{
|
||||||
|
if (threadId == getThreadId())
|
||||||
|
{
|
||||||
|
syncMutex.leave();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// copying is prohibited
|
||||||
|
Sync(const Sync&);
|
||||||
|
Sync& operator=(const Sync&);
|
||||||
|
|
||||||
|
Firebird::Mutex syncMutex;
|
||||||
|
std::atomic<int> waiters;
|
||||||
|
ThreadId threadId;
|
||||||
|
volatile FB_UINT64 totalLocksCounter;
|
||||||
|
int currentLocksCounter;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Firebird::RaiiLockGuard<StableAttachmentPart> SyncGuard;
|
||||||
|
|
||||||
explicit StableAttachmentPart(Attachment* handle)
|
explicit StableAttachmentPart(Attachment* handle)
|
||||||
: att(handle), jAtt(NULL), shutError(0)
|
: att(handle), jAtt(NULL), shutError(0)
|
||||||
{ }
|
{ }
|
||||||
@ -226,13 +327,13 @@ public:
|
|||||||
shutError = 0;
|
shutError = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Firebird::Mutex* getMutex(bool useAsync = false, bool forceAsync = false)
|
Sync* getSync(bool useAsync = false, bool forceAsync = false)
|
||||||
{
|
{
|
||||||
if (useAsync && !forceAsync)
|
if (useAsync && !forceAsync)
|
||||||
{
|
{
|
||||||
fb_assert(!mainMutex.locked());
|
fb_assert(!mainSync.locked());
|
||||||
}
|
}
|
||||||
return useAsync ? &asyncMutex : &mainMutex;
|
return useAsync ? &async : &mainSync;
|
||||||
}
|
}
|
||||||
|
|
||||||
Firebird::Mutex* getBlockingMutex()
|
Firebird::Mutex* getBlockingMutex()
|
||||||
@ -242,8 +343,8 @@ public:
|
|||||||
|
|
||||||
void cancel()
|
void cancel()
|
||||||
{
|
{
|
||||||
fb_assert(asyncMutex.locked());
|
fb_assert(async.locked());
|
||||||
fb_assert(mainMutex.locked());
|
fb_assert(mainSync.locked());
|
||||||
att = NULL;
|
att = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,13 +380,16 @@ private:
|
|||||||
JAttachment* jAtt;
|
JAttachment* jAtt;
|
||||||
ISC_STATUS shutError;
|
ISC_STATUS shutError;
|
||||||
|
|
||||||
// These mutexes guarantee attachment existence. After releasing both of them with possibly
|
// These syncs guarantee attachment existence. After releasing both of them with possibly
|
||||||
// zero att_use_count one should check does attachment still exists calling getHandle().
|
// zero att_use_count one should check does attachment still exists calling getHandle().
|
||||||
Firebird::Mutex mainMutex, asyncMutex;
|
Sync mainSync, async;
|
||||||
// This mutex guarantees attachment is not accessed by more than single external thread.
|
// This mutex guarantees attachment is not accessed by more than single external thread.
|
||||||
Firebird::Mutex blockingMutex;
|
Firebird::Mutex blockingMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef Firebird::RaiiLockGuard<StableAttachmentPart::Sync> AttSyncLockGuard;
|
||||||
|
typedef Firebird::RaiiUnlockGuard<StableAttachmentPart::Sync> AttSyncUnlockGuard;
|
||||||
|
|
||||||
//
|
//
|
||||||
// the attachment block; one is created for each attachment to a database
|
// the attachment block; one is created for each attachment to a database
|
||||||
//
|
//
|
||||||
@ -310,7 +414,7 @@ public:
|
|||||||
~SyncGuard()
|
~SyncGuard()
|
||||||
{
|
{
|
||||||
if (jStable)
|
if (jStable)
|
||||||
jStable->getMutex()->leave();
|
jStable->getSync()->leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -266,6 +266,7 @@ namespace Jrd {
|
|||||||
sync(this),
|
sync(this),
|
||||||
keyName(getPool()),
|
keyName(getPool()),
|
||||||
pluginName(getPool()),
|
pluginName(getPool()),
|
||||||
|
currentPage(0),
|
||||||
keyProviders(getPool()),
|
keyProviders(getPool()),
|
||||||
keyConsumers(getPool()),
|
keyConsumers(getPool()),
|
||||||
hash(getPool()),
|
hash(getPool()),
|
||||||
@ -850,7 +851,7 @@ namespace Jrd {
|
|||||||
if (!LCK_lock(tdbb, threadLock, LCK_EX, LCK_NO_WAIT))
|
if (!LCK_lock(tdbb, threadLock, LCK_EX, LCK_NO_WAIT))
|
||||||
{
|
{
|
||||||
// Cleanup lock manager error
|
// Cleanup lock manager error
|
||||||
fb_utils::init_status(tdbb->tdbb_status_vector);
|
tdbb->tdbb_status_vector->init();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -915,36 +916,13 @@ namespace Jrd {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establish temp context
|
// Establish temp context needed to take crypt thread lock
|
||||||
// Needed to take crypt thread lock
|
ThreadContextHolder tempDbb(&dbb, nullptr, &status_vector);
|
||||||
UserId user;
|
|
||||||
user.setUserName("Database Crypter");
|
|
||||||
|
|
||||||
Jrd::Attachment* const attachment = Jrd::Attachment::create(&dbb, nullptr);
|
|
||||||
RefPtr<SysStableAttachment> sAtt(FB_NEW SysStableAttachment(attachment));
|
|
||||||
attachment->setStable(sAtt);
|
|
||||||
attachment->att_filename = dbb.dbb_filename;
|
|
||||||
attachment->att_user = &user;
|
|
||||||
|
|
||||||
BackgroundContextHolder tempDbb(&dbb, attachment, &status_vector, FB_FUNCTION);
|
|
||||||
|
|
||||||
LCK_init(tempDbb, LCK_OWNER_attachment);
|
|
||||||
PAG_header(tempDbb, true);
|
|
||||||
PAG_attachment_id(tempDbb);
|
|
||||||
|
|
||||||
Monitoring::publishAttachment(tempDbb);
|
|
||||||
|
|
||||||
sAtt->initDone();
|
|
||||||
|
|
||||||
// Take exclusive threadLock
|
// Take exclusive threadLock
|
||||||
// If can't take that lock - nothing to do, cryptThread already runs somewhere
|
// If can't take that lock - nothing to do, cryptThread already runs somewhere
|
||||||
if (!LCK_lock(tempDbb, threadLock, LCK_EX, LCK_NO_WAIT))
|
if (!LCK_lock(tempDbb, threadLock, LCK_EX, LCK_NO_WAIT))
|
||||||
{
|
|
||||||
Monitoring::cleanupAttachment(tempDbb);
|
|
||||||
attachment->releaseLocks(tempDbb);
|
|
||||||
LCK_fini(tempDbb, LCK_OWNER_attachment);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -971,7 +949,7 @@ namespace Jrd {
|
|||||||
dbb.dbb_database_name.c_str(), writer.getBufferLength(), writer.getBuffer()));
|
dbb.dbb_database_name.c_str(), writer.getBufferLength(), writer.getBuffer()));
|
||||||
check(&status_vector);
|
check(&status_vector);
|
||||||
|
|
||||||
MutexLockGuard attGuard(*(jAtt->getStable()->getMutex()), FB_FUNCTION);
|
AttSyncLockGuard attGuard(*(jAtt->getStable()->getSync()), FB_FUNCTION);
|
||||||
Attachment* att = jAtt->getHandle();
|
Attachment* att = jAtt->getHandle();
|
||||||
if (!att)
|
if (!att)
|
||||||
Arg::Gds(isc_att_shutdown).raise();
|
Arg::Gds(isc_att_shutdown).raise();
|
||||||
@ -1073,9 +1051,6 @@ namespace Jrd {
|
|||||||
// Release exclusive lock on StartCryptThread
|
// Release exclusive lock on StartCryptThread
|
||||||
lckRelease = true;
|
lckRelease = true;
|
||||||
LCK_release(tempDbb, threadLock);
|
LCK_release(tempDbb, threadLock);
|
||||||
Monitoring::cleanupAttachment(tempDbb);
|
|
||||||
attachment->releaseLocks(tempDbb);
|
|
||||||
LCK_fini(tempDbb, LCK_OWNER_attachment);
|
|
||||||
}
|
}
|
||||||
catch (const Exception&)
|
catch (const Exception&)
|
||||||
{
|
{
|
||||||
@ -1085,9 +1060,6 @@ namespace Jrd {
|
|||||||
{
|
{
|
||||||
// Release exclusive lock on StartCryptThread
|
// Release exclusive lock on StartCryptThread
|
||||||
LCK_release(tempDbb, threadLock);
|
LCK_release(tempDbb, threadLock);
|
||||||
Monitoring::cleanupAttachment(tempDbb);
|
|
||||||
attachment->releaseLocks(tempDbb);
|
|
||||||
LCK_fini(tempDbb, LCK_OWNER_attachment);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const Exception&)
|
catch (const Exception&)
|
||||||
@ -1322,9 +1294,16 @@ namespace Jrd {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG CryptoManager::getCurrentPage() const
|
ULONG CryptoManager::getCurrentPage(thread_db* tdbb) const
|
||||||
{
|
{
|
||||||
return process ? currentPage : 0;
|
if (!process)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (currentPage)
|
||||||
|
return currentPage;
|
||||||
|
|
||||||
|
CchHdr hdr(tdbb, LCK_read);
|
||||||
|
return hdr->hdr_crypt_page;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG CryptoManager::getLastPage(thread_db* tdbb)
|
ULONG CryptoManager::getLastPage(thread_db* tdbb)
|
||||||
@ -1332,9 +1311,19 @@ namespace Jrd {
|
|||||||
return PAG_last_page(tdbb) + 1;
|
return PAG_last_page(tdbb) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
UCHAR CryptoManager::getCurrentState() const
|
UCHAR CryptoManager::getCurrentState(thread_db* tdbb) const
|
||||||
{
|
{
|
||||||
return (crypt ? fb_info_crypt_encrypted : 0) | (process ? fb_info_crypt_process : 0);
|
bool p = process;
|
||||||
|
bool c = crypt;
|
||||||
|
if (!currentPage)
|
||||||
|
{
|
||||||
|
CchHdr hdr(tdbb, LCK_read);
|
||||||
|
|
||||||
|
p = hdr->hdr_flags & Ods::hdr_crypt_process;
|
||||||
|
c = hdr->hdr_flags & Ods::hdr_encrypted;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (c ? fb_info_crypt_encrypted : 0) | (p ? fb_info_crypt_process : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* CryptoManager::getKeyName() const
|
const char* CryptoManager::getKeyName() const
|
||||||
|
@ -297,8 +297,8 @@ public:
|
|||||||
bool checkValidation(Firebird::IDbCryptPlugin* crypt);
|
bool checkValidation(Firebird::IDbCryptPlugin* crypt);
|
||||||
void setDbInfo(Firebird::IDbCryptPlugin* cp);
|
void setDbInfo(Firebird::IDbCryptPlugin* cp);
|
||||||
|
|
||||||
ULONG getCurrentPage() const;
|
ULONG getCurrentPage(thread_db* tdbb) const;
|
||||||
UCHAR getCurrentState() const;
|
UCHAR getCurrentState(thread_db* tdbb) const;
|
||||||
const char* getKeyName() const;
|
const char* getKeyName() const;
|
||||||
const char* getPluginName() const;
|
const char* getPluginName() const;
|
||||||
|
|
||||||
|
@ -901,8 +901,8 @@ void Monitoring::putDatabase(thread_db* tdbb, SnapshotData::DumpRecord& record)
|
|||||||
// crypt thread status
|
// crypt thread status
|
||||||
if (dbb->dbb_crypto_manager)
|
if (dbb->dbb_crypto_manager)
|
||||||
{
|
{
|
||||||
record.storeInteger(f_mon_db_crypt_page, dbb->dbb_crypto_manager->getCurrentPage());
|
record.storeInteger(f_mon_db_crypt_page, dbb->dbb_crypto_manager->getCurrentPage(tdbb));
|
||||||
record.storeInteger(f_mon_db_crypt_state, dbb->dbb_crypto_manager->getCurrentState());
|
record.storeInteger(f_mon_db_crypt_state, dbb->dbb_crypto_manager->getCurrentState(tdbb));
|
||||||
}
|
}
|
||||||
|
|
||||||
// database owner
|
// database owner
|
||||||
|
@ -2543,10 +2543,10 @@ void EngineCallbackGuard::init(thread_db* tdbb, Connection& conn, const char* fr
|
|||||||
{
|
{
|
||||||
m_saveConnection = attachment->att_ext_connection;
|
m_saveConnection = attachment->att_ext_connection;
|
||||||
m_stable = attachment->getStable();
|
m_stable = attachment->getStable();
|
||||||
m_stable->getMutex()->leave();
|
m_stable->getSync()->leave();
|
||||||
|
|
||||||
MutexLockGuard guardAsync(*m_stable->getMutex(true, true), FB_FUNCTION);
|
Jrd::AttSyncLockGuard guardAsync(*m_stable->getSync(true, true), FB_FUNCTION);
|
||||||
MutexLockGuard guardMain(*m_stable->getMutex(), FB_FUNCTION);
|
Jrd::AttSyncLockGuard guardMain(*m_stable->getSync(), FB_FUNCTION);
|
||||||
if (m_stable->getHandle() == attachment)
|
if (m_stable->getHandle() == attachment)
|
||||||
attachment->att_ext_connection = &conn;
|
attachment->att_ext_connection = &conn;
|
||||||
}
|
}
|
||||||
@ -2568,13 +2568,13 @@ EngineCallbackGuard::~EngineCallbackGuard()
|
|||||||
Jrd::Attachment* attachment = m_tdbb->getAttachment();
|
Jrd::Attachment* attachment = m_tdbb->getAttachment();
|
||||||
if (attachment && m_stable.hasData())
|
if (attachment && m_stable.hasData())
|
||||||
{
|
{
|
||||||
MutexLockGuard guardAsync(*m_stable->getMutex(true, true), FB_FUNCTION);
|
Jrd::AttSyncLockGuard guardAsync(*m_stable->getSync(true, true), FB_FUNCTION);
|
||||||
m_stable->getMutex()->enter(FB_FUNCTION);
|
m_stable->getSync()->enter(FB_FUNCTION);
|
||||||
|
|
||||||
if (m_stable->getHandle() == attachment)
|
if (m_stable->getHandle() == attachment)
|
||||||
attachment->att_ext_connection = m_saveConnection;
|
attachment->att_ext_connection = m_saveConnection;
|
||||||
else
|
else
|
||||||
m_stable->getMutex()->leave();
|
m_stable->getSync()->leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
jrd_tra* transaction = m_tdbb->getTransaction();
|
jrd_tra* transaction = m_tdbb->getTransaction();
|
||||||
|
@ -823,7 +823,7 @@ void INF_database_info(thread_db* tdbb,
|
|||||||
|
|
||||||
case fb_info_crypt_state:
|
case fb_info_crypt_state:
|
||||||
length = INF_convert(dbb->dbb_crypto_manager ?
|
length = INF_convert(dbb->dbb_crypto_manager ?
|
||||||
dbb->dbb_crypto_manager->getCurrentState() : 0, buffer);
|
dbb->dbb_crypto_manager->getCurrentState(tdbb) : 0, buffer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case fb_info_crypt_key:
|
case fb_info_crypt_key:
|
||||||
|
@ -745,7 +745,7 @@ namespace
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!nolock)
|
if (!nolock)
|
||||||
sAtt->getMutex(async)->enter(from);
|
sAtt->getSync(async)->enter(from);
|
||||||
|
|
||||||
Jrd::Attachment* attachment = sAtt->getHandle(); // Must be done after entering mutex
|
Jrd::Attachment* attachment = sAtt->getHandle(); // Must be done after entering mutex
|
||||||
|
|
||||||
@ -776,7 +776,7 @@ namespace
|
|||||||
catch (const Firebird::Exception&)
|
catch (const Firebird::Exception&)
|
||||||
{
|
{
|
||||||
if (!nolock)
|
if (!nolock)
|
||||||
sAtt->getMutex(async)->leave();
|
sAtt->getSync(async)->leave();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -800,7 +800,7 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!nolock)
|
if (!nolock)
|
||||||
sAtt->getMutex(async)->leave();
|
sAtt->getSync(async)->leave();
|
||||||
|
|
||||||
if (blocking)
|
if (blocking)
|
||||||
sAtt->getBlockingMutex()->leave();
|
sAtt->getBlockingMutex()->leave();
|
||||||
@ -3404,12 +3404,12 @@ void JAttachment::internalDropDatabase(CheckStatusWrapper* user_status)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
EngineContextHolder tdbb(user_status, this, FB_FUNCTION, AttachmentHolder::ATT_LOCK_ASYNC);
|
EngineContextHolder tdbb(user_status, this, FB_FUNCTION, AttachmentHolder::ATT_LOCK_ASYNC);
|
||||||
Jrd::Attachment* attachment = getHandle();
|
Attachment* attachment = getHandle();
|
||||||
Database* const dbb = tdbb->getDatabase();
|
Database* const dbb = tdbb->getDatabase();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MutexEnsureUnlock guard(*(getStable()->getMutex()), FB_FUNCTION);
|
EnsureUnlock<StableAttachmentPart::Sync, NotRefCounted> guard(*(getStable()->getSync()), FB_FUNCTION);
|
||||||
if (!guard.tryEnter())
|
if (!guard.tryEnter())
|
||||||
{
|
{
|
||||||
status_exception::raise(Arg::Gds(isc_attachment_in_use));
|
status_exception::raise(Arg::Gds(isc_attachment_in_use));
|
||||||
@ -5031,8 +5031,8 @@ void SysStableAttachment::destroy(Attachment* attachment)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make Attachment::destroy() happy
|
// Make Attachment::destroy() happy
|
||||||
MutexLockGuard async(*getMutex(true), FB_FUNCTION);
|
AttSyncLockGuard async(*getSync(true), FB_FUNCTION);
|
||||||
MutexLockGuard sync(*getMutex(), FB_FUNCTION);
|
AttSyncLockGuard sync(*getSync(), FB_FUNCTION);
|
||||||
|
|
||||||
setInterface(NULL);
|
setInterface(NULL);
|
||||||
Jrd::Attachment::destroy(attachment);
|
Jrd::Attachment::destroy(attachment);
|
||||||
@ -8161,8 +8161,8 @@ static void purge_attachment(thread_db* tdbb, StableAttachmentPart* sAtt, unsign
|
|||||||
**************************************/
|
**************************************/
|
||||||
SET_TDBB(tdbb);
|
SET_TDBB(tdbb);
|
||||||
|
|
||||||
Mutex* const attMutex = sAtt->getMutex();
|
StableAttachmentPart::Sync* const attSync = sAtt->getSync();
|
||||||
fb_assert(attMutex->locked());
|
fb_assert(attSync->locked());
|
||||||
|
|
||||||
Jrd::Attachment* attachment = sAtt->getHandle();
|
Jrd::Attachment* attachment = sAtt->getHandle();
|
||||||
|
|
||||||
@ -8177,10 +8177,10 @@ static void purge_attachment(thread_db* tdbb, StableAttachmentPart* sAtt, unsign
|
|||||||
attachment->att_use_count--;
|
attachment->att_use_count--;
|
||||||
|
|
||||||
{ // scope
|
{ // scope
|
||||||
MutexUnlockGuard cout(*attMutex, FB_FUNCTION);
|
AttSyncUnlockGuard cout(*attSync, FB_FUNCTION);
|
||||||
// !!!!!!!!!!!!!!!!! - event? semaphore? condvar? (when ATT_purge_started / sAtt->getHandle() changes)
|
// !!!!!!!!!!!!!!!!! - event? semaphore? condvar? (when ATT_purge_started / sAtt->getHandle() changes)
|
||||||
|
|
||||||
fb_assert(!attMutex->locked());
|
fb_assert(!attSync->locked());
|
||||||
Thread::yield();
|
Thread::yield();
|
||||||
Thread::sleep(1);
|
Thread::sleep(1);
|
||||||
}
|
}
|
||||||
@ -8204,10 +8204,10 @@ static void purge_attachment(thread_db* tdbb, StableAttachmentPart* sAtt, unsign
|
|||||||
attachment->att_use_count--;
|
attachment->att_use_count--;
|
||||||
|
|
||||||
{ // scope
|
{ // scope
|
||||||
MutexUnlockGuard cout(*attMutex, FB_FUNCTION);
|
AttSyncUnlockGuard cout(*attSync, FB_FUNCTION);
|
||||||
// !!!!!!!!!!!!!!!!! - event? semaphore? condvar? (when --att_use_count)
|
// !!!!!!!!!!!!!!!!! - event? semaphore? condvar? (when --att_use_count)
|
||||||
|
|
||||||
fb_assert(!attMutex->locked());
|
fb_assert(!attSync->locked());
|
||||||
Thread::yield();
|
Thread::yield();
|
||||||
Thread::sleep(1);
|
Thread::sleep(1);
|
||||||
}
|
}
|
||||||
@ -8218,7 +8218,7 @@ static void purge_attachment(thread_db* tdbb, StableAttachmentPart* sAtt, unsign
|
|||||||
attachment->att_use_count++;
|
attachment->att_use_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
fb_assert(attMutex->locked());
|
fb_assert(attSync->locked());
|
||||||
|
|
||||||
if (!attachment)
|
if (!attachment)
|
||||||
return;
|
return;
|
||||||
@ -8340,13 +8340,13 @@ static void purge_attachment(thread_db* tdbb, StableAttachmentPart* sAtt, unsign
|
|||||||
attachment->att_trace_manager->event_detach(&conn, false);
|
attachment->att_trace_manager->event_detach(&conn, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fb_assert(attMutex->locked());
|
fb_assert(attSync->locked());
|
||||||
Mutex* asyncMutex = sAtt->getMutex(true, true);
|
StableAttachmentPart::Sync* attAsync = sAtt->getSync(true, true);
|
||||||
MutexEnsureUnlock asyncGuard(*asyncMutex, FB_FUNCTION);
|
EnsureUnlock<StableAttachmentPart::Sync, NotRefCounted> asyncGuard(*attAsync, FB_FUNCTION);
|
||||||
|
|
||||||
{ // scope - ensure correct order of taking both async and main mutexes
|
{ // scope - ensure correct order of taking both async and main mutexes
|
||||||
MutexUnlockGuard cout(*attMutex, FB_FUNCTION);
|
AttSyncUnlockGuard cout(*attSync, FB_FUNCTION);
|
||||||
fb_assert(!attMutex->locked());
|
fb_assert(!attSync->locked());
|
||||||
asyncGuard.enter();
|
asyncGuard.enter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8363,7 +8363,7 @@ static void purge_attachment(thread_db* tdbb, StableAttachmentPart* sAtt, unsign
|
|||||||
release_attachment(tdbb, attachment);
|
release_attachment(tdbb, attachment);
|
||||||
|
|
||||||
asyncGuard.leave();
|
asyncGuard.leave();
|
||||||
MutexUnlockGuard cout(*attMutex, FB_FUNCTION);
|
AttSyncUnlockGuard cout(*attSync, FB_FUNCTION);
|
||||||
MutexUnlockGuard coutBlocking(*sAtt->getBlockingMutex(), FB_FUNCTION);
|
MutexUnlockGuard coutBlocking(*sAtt->getBlockingMutex(), FB_FUNCTION);
|
||||||
|
|
||||||
// Try to close database if there are no attachments
|
// Try to close database if there are no attachments
|
||||||
@ -8645,7 +8645,7 @@ namespace
|
|||||||
{
|
{
|
||||||
StableAttachmentPart* const sAtt = *iter;
|
StableAttachmentPart* const sAtt = *iter;
|
||||||
|
|
||||||
MutexLockGuard guard(*(sAtt->getMutex(true)), FB_FUNCTION);
|
AttSyncLockGuard guard(*(sAtt->getSync(true)), FB_FUNCTION);
|
||||||
Attachment* attachment = sAtt->getHandle();
|
Attachment* attachment = sAtt->getHandle();
|
||||||
|
|
||||||
if (attachment)
|
if (attachment)
|
||||||
@ -8660,7 +8660,7 @@ namespace
|
|||||||
StableAttachmentPart* const sAtt = *iter;
|
StableAttachmentPart* const sAtt = *iter;
|
||||||
|
|
||||||
MutexLockGuard guardBlocking(*(sAtt->getBlockingMutex()), FB_FUNCTION);
|
MutexLockGuard guardBlocking(*(sAtt->getBlockingMutex()), FB_FUNCTION);
|
||||||
MutexLockGuard guard(*(sAtt->getMutex()), FB_FUNCTION);
|
AttSyncLockGuard guard(*(sAtt->getSync()), FB_FUNCTION);
|
||||||
Attachment* attachment = sAtt->getHandle();
|
Attachment* attachment = sAtt->getHandle();
|
||||||
|
|
||||||
if (attachment)
|
if (attachment)
|
||||||
@ -9079,9 +9079,18 @@ void thread_db::reschedule()
|
|||||||
|
|
||||||
checkCancelState();
|
checkCancelState();
|
||||||
|
|
||||||
{ // checkout scope
|
StableAttachmentPart::Sync* sync = this->getAttachment()->getStable()->getSync();
|
||||||
|
Database* dbb = this->getDatabase();
|
||||||
|
|
||||||
|
if (sync->hasContention())
|
||||||
|
{
|
||||||
|
FB_UINT64 cnt = sync->getLockCounter();
|
||||||
|
|
||||||
EngineCheckout cout(this, FB_FUNCTION);
|
EngineCheckout cout(this, FB_FUNCTION);
|
||||||
Thread::yield();
|
Thread::yield();
|
||||||
|
|
||||||
|
while (sync->hasContention() && (sync->getLockCounter() == cnt))
|
||||||
|
Thread::sleep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkCancelState();
|
checkCancelState();
|
||||||
|
@ -1089,7 +1089,7 @@ namespace Jrd {
|
|||||||
fb_assert(optional || m_ref.hasData());
|
fb_assert(optional || m_ref.hasData());
|
||||||
|
|
||||||
if (m_ref.hasData())
|
if (m_ref.hasData())
|
||||||
m_ref->getMutex()->leave();
|
m_ref->getSync()->leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
EngineCheckout(Attachment* att, const char* from)
|
EngineCheckout(Attachment* att, const char* from)
|
||||||
@ -1100,14 +1100,14 @@ namespace Jrd {
|
|||||||
if (att && att->att_use_count)
|
if (att && att->att_use_count)
|
||||||
{
|
{
|
||||||
m_ref = att->getStable();
|
m_ref = att->getStable();
|
||||||
m_ref->getMutex()->leave();
|
m_ref->getSync()->leave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~EngineCheckout()
|
~EngineCheckout()
|
||||||
{
|
{
|
||||||
if (m_ref.hasData())
|
if (m_ref.hasData())
|
||||||
m_ref->getMutex()->enter(m_from);
|
m_ref->getSync()->enter(m_from);
|
||||||
|
|
||||||
// If we were signalled to cancel/shutdown, react as soon as possible.
|
// If we were signalled to cancel/shutdown, react as soon as possible.
|
||||||
// We cannot throw immediately, but we can reschedule ourselves.
|
// We cannot throw immediately, but we can reschedule ourselves.
|
||||||
|
@ -469,7 +469,6 @@ static bool notify_shutdown(thread_db* tdbb, SSHORT flag, SSHORT delay, Sync* gu
|
|||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
Database* const dbb = tdbb->getDatabase();
|
Database* const dbb = tdbb->getDatabase();
|
||||||
StableAttachmentPart* const sAtt = tdbb->getAttachment()->getStable();
|
|
||||||
|
|
||||||
shutdown_data data;
|
shutdown_data data;
|
||||||
data.data_items.flag = flag;
|
data.data_items.flag = flag;
|
||||||
@ -479,7 +478,7 @@ static bool notify_shutdown(thread_db* tdbb, SSHORT flag, SSHORT delay, Sync* gu
|
|||||||
|
|
||||||
{ // scope
|
{ // scope
|
||||||
// Checkout before calling AST function
|
// Checkout before calling AST function
|
||||||
MutexUnlockGuard uguard(*(sAtt->getMutex()), FB_FUNCTION);
|
EngineCheckout uguard(tdbb, FB_FUNCTION);
|
||||||
|
|
||||||
// Notify local attachments
|
// Notify local attachments
|
||||||
SHUT_blocking_ast(tdbb, true);
|
SHUT_blocking_ast(tdbb, true);
|
||||||
|
Loading…
Reference in New Issue
Block a user