diff --git a/src/common/ThreadStart.cpp b/src/common/ThreadStart.cpp index 2f531b5423..44a45d6130 100644 --- a/src/common/ThreadStart.cpp +++ b/src/common/ThreadStart.cpp @@ -210,7 +210,10 @@ void Thread::kill(Handle& thread) ThreadId Thread::getId() { #ifdef USE_LWP_AS_THREAD_ID - return syscall(SYS_gettid); + static __thread int tid = 0; + if (!tid) + tid = syscall(SYS_gettid); + return tid; #else return pthread_self(); #endif diff --git a/src/common/classes/RefMutex.h b/src/common/classes/RefMutex.h index 6c9c919954..1d50ae29bc 100644 --- a/src/common/classes/RefMutex.h +++ b/src/common/classes/RefMutex.h @@ -101,7 +101,7 @@ namespace Firebird } }; - template > + template class RefCounted = DefaultRefCounted > class EnsureUnlock { public: @@ -114,14 +114,14 @@ namespace Firebird #define FB_LOCKED_FROM NULL #endif { - RefCounted::addRef(m_mutex); + RefCounted::addRef(m_mutex); } ~EnsureUnlock() { while (m_locked) leave(); - RefCounted::release(m_mutex); + RefCounted::release(m_mutex); } void enter() @@ -155,7 +155,7 @@ namespace Firebird }; #undef FB_LOCKED_FROM - typedef EnsureUnlock > MutexEnsureUnlock; + typedef EnsureUnlock MutexEnsureUnlock; typedef EnsureUnlock RefMutexEnsureUnlock; } // namespace diff --git a/src/common/classes/XThreadMutex.h b/src/common/classes/XThreadMutex.h index 464b483d82..b3329c3d38 100644 --- a/src/common/classes/XThreadMutex.h +++ b/src/common/classes/XThreadMutex.h @@ -89,7 +89,7 @@ private: }; typedef RaiiLockGuard XThreadLockGuard; -typedef EnsureUnlock > XThreadEnsureUnlock; +typedef EnsureUnlock XThreadEnsureUnlock; } diff --git a/src/common/classes/locks.h b/src/common/classes/locks.h index 0a2b82b8be..7baae6abc0 100644 --- a/src/common/classes/locks.h +++ b/src/common/classes/locks.h @@ -320,7 +320,7 @@ typedef Mutex Spinlock; #endif //WIN_NT -// RAII holder +// RAII holders template class RaiiLockGuard { @@ -363,10 +363,12 @@ private: typedef RaiiLockGuard MutexLockGuard; -class MutexUnlockGuard + +template +class RaiiUnlockGuard { public: - explicit MutexUnlockGuard(Mutex& aLock, const char* aReason) + explicit RaiiUnlockGuard(M& aLock, const char* aReason) : lock(&aLock) #ifdef DEV_BUILD , saveReason(aReason) @@ -375,7 +377,7 @@ public: lock->leave(); } - ~MutexUnlockGuard() + ~RaiiUnlockGuard() { try { @@ -393,15 +395,17 @@ public: private: // Forbid copying - MutexUnlockGuard(const MutexUnlockGuard&); - MutexUnlockGuard& operator=(const MutexUnlockGuard&); + RaiiUnlockGuard(const RaiiUnlockGuard&); + RaiiUnlockGuard& operator=(const RaiiUnlockGuard&); - Mutex* lock; + M* lock; #ifdef DEV_BUILD const char* saveReason; #endif }; +typedef RaiiUnlockGuard MutexUnlockGuard; + class MutexCheckoutGuard { diff --git a/src/jrd/Attachment.cpp b/src/jrd/Attachment.cpp index 8a038cc6f9..d3f5530447 100644 --- a/src/jrd/Attachment.cpp +++ b/src/jrd/Attachment.cpp @@ -989,10 +989,10 @@ void Jrd::Attachment::SyncGuard::init(const char* f, bool if (jStable) { - jStable->getMutex()->enter(f); + jStable->getSync()->enter(f); if (!jStable->getHandle()) { - jStable->getMutex()->leave(); + jStable->getSync()->leave(); Arg::Gds(isc_att_shutdown).raise(); } } @@ -1004,13 +1004,13 @@ void StableAttachmentPart::manualLock(ULONG& flags, const ULONG whatLock) if (whatLock & ATT_async_manual_lock) { - asyncMutex.enter(FB_FUNCTION); + async.enter(FB_FUNCTION); flags |= ATT_async_manual_lock; } if (whatLock & ATT_manual_lock) { - mainMutex.enter(FB_FUNCTION); + mainSync.enter(FB_FUNCTION); flags |= ATT_manual_lock; } } @@ -1020,7 +1020,7 @@ void StableAttachmentPart::manualUnlock(ULONG& flags) if (flags & ATT_manual_lock) { flags &= ~ATT_manual_lock; - mainMutex.leave(); + mainSync.leave(); } manualAsyncUnlock(flags); } @@ -1030,7 +1030,7 @@ void StableAttachmentPart::manualAsyncUnlock(ULONG& flags) if (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 - MutexEnsureUnlock guard(*this->getMutex(), FB_FUNCTION); + EnsureUnlock guard(*this->getSync(), FB_FUNCTION); if (!guard.tryEnter()) return; diff --git a/src/jrd/Attachment.h b/src/jrd/Attachment.h index 507c3fb444..563940ffd6 100644 --- a/src/jrd/Attachment.h +++ b/src/jrd/Attachment.h @@ -203,6 +203,107 @@ private: class StableAttachmentPart : public Firebird::RefCounted, public Firebird::GlobalStorage { 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 waiters; + ThreadId threadId; + volatile FB_UINT64 totalLocksCounter; + int currentLocksCounter; + }; + + typedef Firebird::RaiiLockGuard SyncGuard; + explicit StableAttachmentPart(Attachment* handle) : att(handle), jAtt(NULL), shutError(0) { } @@ -226,13 +327,13 @@ public: shutError = 0; } - Firebird::Mutex* getMutex(bool useAsync = false, bool forceAsync = false) + Sync* getSync(bool useAsync = false, bool forceAsync = false) { if (useAsync && !forceAsync) { - fb_assert(!mainMutex.locked()); + fb_assert(!mainSync.locked()); } - return useAsync ? &asyncMutex : &mainMutex; + return useAsync ? &async : &mainSync; } Firebird::Mutex* getBlockingMutex() @@ -242,8 +343,8 @@ public: void cancel() { - fb_assert(asyncMutex.locked()); - fb_assert(mainMutex.locked()); + fb_assert(async.locked()); + fb_assert(mainSync.locked()); att = NULL; } @@ -279,13 +380,16 @@ private: JAttachment* jAtt; 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(). - Firebird::Mutex mainMutex, asyncMutex; + Sync mainSync, async; // This mutex guarantees attachment is not accessed by more than single external thread. Firebird::Mutex blockingMutex; }; +typedef Firebird::RaiiLockGuard AttSyncLockGuard; +typedef Firebird::RaiiUnlockGuard AttSyncUnlockGuard; + // // the attachment block; one is created for each attachment to a database // @@ -310,7 +414,7 @@ public: ~SyncGuard() { if (jStable) - jStable->getMutex()->leave(); + jStable->getSync()->leave(); } private: diff --git a/src/jrd/CryptoManager.cpp b/src/jrd/CryptoManager.cpp index 757f4d4677..8c5d0cd42a 100644 --- a/src/jrd/CryptoManager.cpp +++ b/src/jrd/CryptoManager.cpp @@ -266,6 +266,7 @@ namespace Jrd { sync(this), keyName(getPool()), pluginName(getPool()), + currentPage(0), keyProviders(getPool()), keyConsumers(getPool()), hash(getPool()), @@ -850,7 +851,7 @@ namespace Jrd { if (!LCK_lock(tdbb, threadLock, LCK_EX, LCK_NO_WAIT)) { // Cleanup lock manager error - fb_utils::init_status(tdbb->tdbb_status_vector); + tdbb->tdbb_status_vector->init(); return; } @@ -915,36 +916,13 @@ namespace Jrd { return; } - // Establish temp context - // Needed to take crypt thread lock - UserId user; - user.setUserName("Database Crypter"); - - Jrd::Attachment* const attachment = Jrd::Attachment::create(&dbb, nullptr); - RefPtr 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(); + // Establish temp context needed to take crypt thread lock + ThreadContextHolder tempDbb(&dbb, nullptr, &status_vector); // Take exclusive threadLock // If can't take that lock - nothing to do, cryptThread already runs somewhere if (!LCK_lock(tempDbb, threadLock, LCK_EX, LCK_NO_WAIT)) - { - Monitoring::cleanupAttachment(tempDbb); - attachment->releaseLocks(tempDbb); - LCK_fini(tempDbb, LCK_OWNER_attachment); return; - } try { @@ -971,7 +949,7 @@ namespace Jrd { dbb.dbb_database_name.c_str(), writer.getBufferLength(), writer.getBuffer())); check(&status_vector); - MutexLockGuard attGuard(*(jAtt->getStable()->getMutex()), FB_FUNCTION); + AttSyncLockGuard attGuard(*(jAtt->getStable()->getSync()), FB_FUNCTION); Attachment* att = jAtt->getHandle(); if (!att) Arg::Gds(isc_att_shutdown).raise(); @@ -1073,9 +1051,6 @@ namespace Jrd { // Release exclusive lock on StartCryptThread lckRelease = true; LCK_release(tempDbb, threadLock); - Monitoring::cleanupAttachment(tempDbb); - attachment->releaseLocks(tempDbb); - LCK_fini(tempDbb, LCK_OWNER_attachment); } catch (const Exception&) { @@ -1085,9 +1060,6 @@ namespace Jrd { { // Release exclusive lock on StartCryptThread LCK_release(tempDbb, threadLock); - Monitoring::cleanupAttachment(tempDbb); - attachment->releaseLocks(tempDbb); - LCK_fini(tempDbb, LCK_OWNER_attachment); } } catch (const Exception&) @@ -1322,9 +1294,16 @@ namespace Jrd { 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) @@ -1332,9 +1311,19 @@ namespace Jrd { 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 diff --git a/src/jrd/CryptoManager.h b/src/jrd/CryptoManager.h index adc637ff7f..dc1006a631 100644 --- a/src/jrd/CryptoManager.h +++ b/src/jrd/CryptoManager.h @@ -297,8 +297,8 @@ public: bool checkValidation(Firebird::IDbCryptPlugin* crypt); void setDbInfo(Firebird::IDbCryptPlugin* cp); - ULONG getCurrentPage() const; - UCHAR getCurrentState() const; + ULONG getCurrentPage(thread_db* tdbb) const; + UCHAR getCurrentState(thread_db* tdbb) const; const char* getKeyName() const; const char* getPluginName() const; diff --git a/src/jrd/Monitoring.cpp b/src/jrd/Monitoring.cpp index 9d1964fe99..38c51e271b 100644 --- a/src/jrd/Monitoring.cpp +++ b/src/jrd/Monitoring.cpp @@ -901,8 +901,8 @@ void Monitoring::putDatabase(thread_db* tdbb, SnapshotData::DumpRecord& record) // crypt thread status if (dbb->dbb_crypto_manager) { - record.storeInteger(f_mon_db_crypt_page, dbb->dbb_crypto_manager->getCurrentPage()); - record.storeInteger(f_mon_db_crypt_state, dbb->dbb_crypto_manager->getCurrentState()); + 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(tdbb)); } // database owner diff --git a/src/jrd/extds/ExtDS.cpp b/src/jrd/extds/ExtDS.cpp index e45b5f363a..5b31778f7f 100644 --- a/src/jrd/extds/ExtDS.cpp +++ b/src/jrd/extds/ExtDS.cpp @@ -2543,10 +2543,10 @@ void EngineCallbackGuard::init(thread_db* tdbb, Connection& conn, const char* fr { m_saveConnection = attachment->att_ext_connection; m_stable = attachment->getStable(); - m_stable->getMutex()->leave(); + m_stable->getSync()->leave(); - MutexLockGuard guardAsync(*m_stable->getMutex(true, true), FB_FUNCTION); - MutexLockGuard guardMain(*m_stable->getMutex(), FB_FUNCTION); + Jrd::AttSyncLockGuard guardAsync(*m_stable->getSync(true, true), FB_FUNCTION); + Jrd::AttSyncLockGuard guardMain(*m_stable->getSync(), FB_FUNCTION); if (m_stable->getHandle() == attachment) attachment->att_ext_connection = &conn; } @@ -2568,13 +2568,13 @@ EngineCallbackGuard::~EngineCallbackGuard() Jrd::Attachment* attachment = m_tdbb->getAttachment(); if (attachment && m_stable.hasData()) { - MutexLockGuard guardAsync(*m_stable->getMutex(true, true), FB_FUNCTION); - m_stable->getMutex()->enter(FB_FUNCTION); + Jrd::AttSyncLockGuard guardAsync(*m_stable->getSync(true, true), FB_FUNCTION); + m_stable->getSync()->enter(FB_FUNCTION); if (m_stable->getHandle() == attachment) attachment->att_ext_connection = m_saveConnection; else - m_stable->getMutex()->leave(); + m_stable->getSync()->leave(); } jrd_tra* transaction = m_tdbb->getTransaction(); diff --git a/src/jrd/inf.cpp b/src/jrd/inf.cpp index e8c6804a81..cff4e5637f 100644 --- a/src/jrd/inf.cpp +++ b/src/jrd/inf.cpp @@ -823,7 +823,7 @@ void INF_database_info(thread_db* tdbb, case fb_info_crypt_state: length = INF_convert(dbb->dbb_crypto_manager ? - dbb->dbb_crypto_manager->getCurrentState() : 0, buffer); + dbb->dbb_crypto_manager->getCurrentState(tdbb) : 0, buffer); break; case fb_info_crypt_key: diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 27fd8077d2..9c6ca18749 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -745,7 +745,7 @@ namespace try { if (!nolock) - sAtt->getMutex(async)->enter(from); + sAtt->getSync(async)->enter(from); Jrd::Attachment* attachment = sAtt->getHandle(); // Must be done after entering mutex @@ -776,7 +776,7 @@ namespace catch (const Firebird::Exception&) { if (!nolock) - sAtt->getMutex(async)->leave(); + sAtt->getSync(async)->leave(); throw; } } @@ -800,7 +800,7 @@ namespace } if (!nolock) - sAtt->getMutex(async)->leave(); + sAtt->getSync(async)->leave(); if (blocking) sAtt->getBlockingMutex()->leave(); @@ -3404,12 +3404,12 @@ void JAttachment::internalDropDatabase(CheckStatusWrapper* user_status) try { EngineContextHolder tdbb(user_status, this, FB_FUNCTION, AttachmentHolder::ATT_LOCK_ASYNC); - Jrd::Attachment* attachment = getHandle(); + Attachment* attachment = getHandle(); Database* const dbb = tdbb->getDatabase(); try { - MutexEnsureUnlock guard(*(getStable()->getMutex()), FB_FUNCTION); + EnsureUnlock guard(*(getStable()->getSync()), FB_FUNCTION); if (!guard.tryEnter()) { status_exception::raise(Arg::Gds(isc_attachment_in_use)); @@ -5031,8 +5031,8 @@ void SysStableAttachment::destroy(Attachment* attachment) } // Make Attachment::destroy() happy - MutexLockGuard async(*getMutex(true), FB_FUNCTION); - MutexLockGuard sync(*getMutex(), FB_FUNCTION); + AttSyncLockGuard async(*getSync(true), FB_FUNCTION); + AttSyncLockGuard sync(*getSync(), FB_FUNCTION); setInterface(NULL); Jrd::Attachment::destroy(attachment); @@ -8161,8 +8161,8 @@ static void purge_attachment(thread_db* tdbb, StableAttachmentPart* sAtt, unsign **************************************/ SET_TDBB(tdbb); - Mutex* const attMutex = sAtt->getMutex(); - fb_assert(attMutex->locked()); + StableAttachmentPart::Sync* const attSync = sAtt->getSync(); + fb_assert(attSync->locked()); Jrd::Attachment* attachment = sAtt->getHandle(); @@ -8177,10 +8177,10 @@ static void purge_attachment(thread_db* tdbb, StableAttachmentPart* sAtt, unsign attachment->att_use_count--; { // scope - MutexUnlockGuard cout(*attMutex, FB_FUNCTION); + AttSyncUnlockGuard cout(*attSync, FB_FUNCTION); // !!!!!!!!!!!!!!!!! - event? semaphore? condvar? (when ATT_purge_started / sAtt->getHandle() changes) - fb_assert(!attMutex->locked()); + fb_assert(!attSync->locked()); Thread::yield(); Thread::sleep(1); } @@ -8204,10 +8204,10 @@ static void purge_attachment(thread_db* tdbb, StableAttachmentPart* sAtt, unsign attachment->att_use_count--; { // scope - MutexUnlockGuard cout(*attMutex, FB_FUNCTION); + AttSyncUnlockGuard cout(*attSync, FB_FUNCTION); // !!!!!!!!!!!!!!!!! - event? semaphore? condvar? (when --att_use_count) - fb_assert(!attMutex->locked()); + fb_assert(!attSync->locked()); Thread::yield(); Thread::sleep(1); } @@ -8218,7 +8218,7 @@ static void purge_attachment(thread_db* tdbb, StableAttachmentPart* sAtt, unsign attachment->att_use_count++; } - fb_assert(attMutex->locked()); + fb_assert(attSync->locked()); if (!attachment) return; @@ -8340,13 +8340,13 @@ static void purge_attachment(thread_db* tdbb, StableAttachmentPart* sAtt, unsign attachment->att_trace_manager->event_detach(&conn, false); } - fb_assert(attMutex->locked()); - Mutex* asyncMutex = sAtt->getMutex(true, true); - MutexEnsureUnlock asyncGuard(*asyncMutex, FB_FUNCTION); + fb_assert(attSync->locked()); + StableAttachmentPart::Sync* attAsync = sAtt->getSync(true, true); + EnsureUnlock asyncGuard(*attAsync, FB_FUNCTION); { // scope - ensure correct order of taking both async and main mutexes - MutexUnlockGuard cout(*attMutex, FB_FUNCTION); - fb_assert(!attMutex->locked()); + AttSyncUnlockGuard cout(*attSync, FB_FUNCTION); + fb_assert(!attSync->locked()); asyncGuard.enter(); } @@ -8363,7 +8363,7 @@ static void purge_attachment(thread_db* tdbb, StableAttachmentPart* sAtt, unsign release_attachment(tdbb, attachment); asyncGuard.leave(); - MutexUnlockGuard cout(*attMutex, FB_FUNCTION); + AttSyncUnlockGuard cout(*attSync, FB_FUNCTION); MutexUnlockGuard coutBlocking(*sAtt->getBlockingMutex(), FB_FUNCTION); // Try to close database if there are no attachments @@ -8645,7 +8645,7 @@ namespace { StableAttachmentPart* const sAtt = *iter; - MutexLockGuard guard(*(sAtt->getMutex(true)), FB_FUNCTION); + AttSyncLockGuard guard(*(sAtt->getSync(true)), FB_FUNCTION); Attachment* attachment = sAtt->getHandle(); if (attachment) @@ -8660,7 +8660,7 @@ namespace StableAttachmentPart* const sAtt = *iter; MutexLockGuard guardBlocking(*(sAtt->getBlockingMutex()), FB_FUNCTION); - MutexLockGuard guard(*(sAtt->getMutex()), FB_FUNCTION); + AttSyncLockGuard guard(*(sAtt->getSync()), FB_FUNCTION); Attachment* attachment = sAtt->getHandle(); if (attachment) @@ -9079,9 +9079,18 @@ void thread_db::reschedule() 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); Thread::yield(); + + while (sync->hasContention() && (sync->getLockCounter() == cnt)) + Thread::sleep(1); } checkCancelState(); diff --git a/src/jrd/jrd.h b/src/jrd/jrd.h index 0a8feecfda..4fd59f561d 100644 --- a/src/jrd/jrd.h +++ b/src/jrd/jrd.h @@ -1089,7 +1089,7 @@ namespace Jrd { fb_assert(optional || m_ref.hasData()); if (m_ref.hasData()) - m_ref->getMutex()->leave(); + m_ref->getSync()->leave(); } EngineCheckout(Attachment* att, const char* from) @@ -1100,14 +1100,14 @@ namespace Jrd { if (att && att->att_use_count) { m_ref = att->getStable(); - m_ref->getMutex()->leave(); + m_ref->getSync()->leave(); } } ~EngineCheckout() { 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. // We cannot throw immediately, but we can reschedule ourselves. diff --git a/src/jrd/shut.cpp b/src/jrd/shut.cpp index 6ec0fb6dfa..6b06cd8dee 100644 --- a/src/jrd/shut.cpp +++ b/src/jrd/shut.cpp @@ -469,7 +469,6 @@ static bool notify_shutdown(thread_db* tdbb, SSHORT flag, SSHORT delay, Sync* gu * **************************************/ Database* const dbb = tdbb->getDatabase(); - StableAttachmentPart* const sAtt = tdbb->getAttachment()->getStable(); shutdown_data data; data.data_items.flag = flag; @@ -479,7 +478,7 @@ static bool notify_shutdown(thread_db* tdbb, SSHORT flag, SSHORT delay, Sync* gu { // scope // Checkout before calling AST function - MutexUnlockGuard uguard(*(sAtt->getMutex()), FB_FUNCTION); + EngineCheckout uguard(tdbb, FB_FUNCTION); // Notify local attachments SHUT_blocking_ast(tdbb, true);