diff --git a/src/jrd/Attachment.h b/src/jrd/Attachment.h index 3777c2b38b..a5a511974f 100644 --- a/src/jrd/Attachment.h +++ b/src/jrd/Attachment.h @@ -521,6 +521,16 @@ public: } } + bool isEmpty() const + { + return m_attachments.isEmpty(); + } + + bool hasData() const + { + return m_attachments.hasData(); + } + void add(StableAttachmentPart* jAtt) { if (jAtt) diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 4316260647..362f300f39 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -7350,9 +7350,9 @@ namespace StableAttachmentPart* const sAtt = *iter; MutexLockGuard guard(*(sAtt->getMutex(true)), FB_FUNCTION); - Attachment* attachment = sAtt->getHandle(); + Attachment* const attachment = sAtt->getHandle(); - if (attachment) + if (attachment && !(attachment->att_flags & ATT_shutdown)) attachment->signalShutdown(); } } @@ -7402,7 +7402,7 @@ namespace MutexLockGuard guard(shutdownMutex, FB_FUNCTION); if (engineShutdown) { - // Shutdown was done, all attachmnets are gone + // Shutdown was done, all attachments are gone return 0; } @@ -8024,16 +8024,15 @@ void JRD_shutdown_attachment(Attachment* attachment) try { - fb_assert(attachment->att_flags & ATT_shutdown); - MemoryPool& pool = *getDefaultMemoryPool(); - AttachmentsRefHolder* queue = FB_NEW_POOL(pool) AttachmentsRefHolder(pool); + AutoPtr queue(FB_NEW_POOL(pool) AttachmentsRefHolder(pool)); - fb_assert(attachment->getStable()); - attachment->getStable()->addRef(); queue->add(attachment->getStable()); - Thread::start(attachmentShutdownThread, queue, THREAD_high); + if (!(attachment->att_flags & ATT_shutdown)) + attachment->signalShutdown(); + + Thread::start(attachmentShutdownThread, queue.release(), THREAD_high); } catch (const Exception&) {} // no-op @@ -8059,26 +8058,38 @@ void JRD_shutdown_attachments(Database* dbb) MemoryPool& pool = *getDefaultMemoryPool(); AutoPtr queue(FB_NEW_POOL(pool) AttachmentsRefHolder(pool)); + // Collect attachments to shut down + { // scope - Sync guard(&dbb->dbb_sync, "JRD_shutdown_attachments"); + Sync guard(&dbb->dbb_sync, FB_FUNCTION); if (!dbb->dbb_sync.ourExclusiveLock()) guard.lock(SYNC_SHARED); for (Jrd::Attachment* attachment = dbb->dbb_attachments; - attachment; - attachment = attachment->att_next) + attachment; attachment = attachment->att_next) { - if (attachment->att_flags & ATT_shutdown) - { - fb_assert(attachment->getStable()); - attachment->getStable()->addRef(); + if (!(attachment->att_flags & ATT_shutdown_manager)) queue->add(attachment->getStable()); - } } } - if (queue.hasData()) + if (queue->hasData()) + { + // Signal attachments for termination + + for (AttachmentsRefHolder::Iterator iter(*queue); *iter; ++iter) + { + StableAttachmentPart* const sAtt = *iter; + + MutexLockGuard guard(*(sAtt->getMutex(true)), FB_FUNCTION); + Attachment* const attachment = sAtt->getHandle(); + + if (attachment && !(attachment->att_flags & ATT_shutdown)) + attachment->signalShutdown(); + } + Thread::start(attachmentShutdownThread, queue.release(), THREAD_high); + } } catch (const Exception&) {} // no-op diff --git a/src/jrd/shut.cpp b/src/jrd/shut.cpp index 05e822643e..ac2a9ef466 100644 --- a/src/jrd/shut.cpp +++ b/src/jrd/shut.cpp @@ -521,26 +521,7 @@ static bool shutdown(thread_db* tdbb, SSHORT flag, bool force) if (force) { - bool found = false; - for (Jrd::Attachment* attachment = dbb->dbb_attachments; - attachment; attachment = attachment->att_next) - { - StableAttachmentPart* const sAtt = attachment->getStable(); - MutexLockGuard guard(*(sAtt->getMutex(true)), FB_FUNCTION); - - if (!(attachment->att_flags & ATT_shutdown_manager)) - { - if (!(attachment->att_flags & ATT_shutdown)) - { - attachment->signalShutdown(); - found = true; - } - } - } - - if (found) - JRD_shutdown_attachments(dbb); - + JRD_shutdown_attachments(dbb); return true; }