diff --git a/src/dsql/StmtNodes.cpp b/src/dsql/StmtNodes.cpp index ca35ec992f..77c66f69bf 100644 --- a/src/dsql/StmtNodes.cpp +++ b/src/dsql/StmtNodes.cpp @@ -8965,11 +8965,11 @@ void SetTransactionNode::genTableLock(DsqlCompilerScratch* dsqlScratch, //-------------------- -void SessionResetNode::execute(thread_db* tdbb, DsqlRequest* request, jrd_tra** traHandle) const +void SessionResetNode::execute(thread_db* tdbb, DsqlRequest* request, jrd_tra**) const { SET_TDBB(tdbb); - Attachment* const attachment = tdbb->getAttachment(); - attachment->resetSession(tdbb, traHandle); + const auto attachment = tdbb->getAttachment(); + attachment->scheduleResetSession(); } diff --git a/src/jrd/Attachment.cpp b/src/jrd/Attachment.cpp index 66b146b535..6616b4e154 100644 --- a/src/jrd/Attachment.cpp +++ b/src/jrd/Attachment.cpp @@ -505,6 +505,11 @@ static void runDBTriggers(thread_db* tdbb, TriggerAction action) } } +void Jrd::Attachment::scheduleResetSession() +{ + att_flags |= ATT_reset_scheduled; +} + void Jrd::Attachment::resetSession(thread_db* tdbb, jrd_tra** traHandle) { jrd_tra* oldTran = traHandle ? *traHandle : nullptr; @@ -578,6 +583,8 @@ void Jrd::Attachment::resetSession(thread_db* tdbb, jrd_tra** traHandle) // reset GTT's releaseGTTs(tdbb); + att_flags &= ~ATT_reset_scheduled; + // Run ON CONNECT trigger after reset if (!(att_flags & ATT_no_db_triggers)) runDBTriggers(tdbb, TRIGGER_CONNECT); diff --git a/src/jrd/Attachment.h b/src/jrd/Attachment.h index a8c507f2b2..7a3b2c8c63 100644 --- a/src/jrd/Attachment.h +++ b/src/jrd/Attachment.h @@ -167,7 +167,8 @@ const ULONG ATT_monitor_init = 0x100000L; // Attachment is registered in monito const ULONG ATT_repl_reset = 0x200000L; // Replication set has been reset const ULONG ATT_replicating = 0x400000L; // Replication is active const ULONG ATT_resetting = 0x800000L; // Session reset is in progress -const ULONG ATT_worker = 0x1000000L; // Worker attachment, managed by the engine +const ULONG ATT_reset_scheduled = 0x1000000L; // Session reset scheduled +const ULONG ATT_worker = 0x2000000L; // Worker attachment, managed by the engine const ULONG ATT_NO_CLEANUP = (ATT_no_cleanup | ATT_notify_gc); @@ -726,6 +727,7 @@ public: const Firebird::ByteChunk& chunk); void releaseGTTs(thread_db* tdbb); + void scheduleResetSession(); void resetSession(thread_db* tdbb, jrd_tra** traHandle); void signalCancel(); diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 60e37d157a..bd4d981662 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -855,6 +855,18 @@ EngineContextHolder::EngineContextHolder(CheckStatusWrapper* status, I* interfac validateHandle(*this, interfacePtr->getHandle()); } +EngineContextHolder::~EngineContextHolder() +{ + thread_db* const tdbb = *this; + const auto attachment = tdbb->getAttachment(); + + if (attachment && attachment->att_use_count == 1 && (attachment->att_flags & ATT_reset_scheduled)) + { + auto transaction = tdbb->getTransaction(); + attachment->resetSession(tdbb, &transaction); + } +} + // Used in ProfilerManager.cpp template EngineContextHolder::EngineContextHolder( CheckStatusWrapper* status, JAttachment* interfacePtr, const char* from, unsigned lockFlags); diff --git a/src/jrd/jrd.h b/src/jrd/jrd.h index 29b756b353..0a5e17ce70 100644 --- a/src/jrd/jrd.h +++ b/src/jrd/jrd.h @@ -1069,6 +1069,7 @@ namespace Jrd { template EngineContextHolder(Firebird::CheckStatusWrapper* status, I* interfacePtr, const char* from, unsigned lockFlags = 0); + ~EngineContextHolder(); }; class AstLockHolder : public Firebird::ReadLockGuard