8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 23:23:04 +01:00

Avoid not synchronized access to the shared list + some minor adjustments

This commit is contained in:
Dmitry Yemanov 2018-06-01 17:05:58 +03:00
parent 08f8f7ca52
commit fd614b807a
3 changed files with 40 additions and 38 deletions

View File

@ -521,6 +521,16 @@ public:
} }
} }
bool isEmpty() const
{
return m_attachments.isEmpty();
}
bool hasData() const
{
return m_attachments.hasData();
}
void add(StableAttachmentPart* jAtt) void add(StableAttachmentPart* jAtt)
{ {
if (jAtt) if (jAtt)

View File

@ -7350,9 +7350,9 @@ namespace
StableAttachmentPart* const sAtt = *iter; StableAttachmentPart* const sAtt = *iter;
MutexLockGuard guard(*(sAtt->getMutex(true)), FB_FUNCTION); 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(); attachment->signalShutdown();
} }
} }
@ -7402,7 +7402,7 @@ namespace
MutexLockGuard guard(shutdownMutex, FB_FUNCTION); MutexLockGuard guard(shutdownMutex, FB_FUNCTION);
if (engineShutdown) if (engineShutdown)
{ {
// Shutdown was done, all attachmnets are gone // Shutdown was done, all attachments are gone
return 0; return 0;
} }
@ -8024,16 +8024,15 @@ void JRD_shutdown_attachment(Attachment* attachment)
try try
{ {
fb_assert(attachment->att_flags & ATT_shutdown);
MemoryPool& pool = *getDefaultMemoryPool(); MemoryPool& pool = *getDefaultMemoryPool();
AttachmentsRefHolder* queue = FB_NEW_POOL(pool) AttachmentsRefHolder(pool); AutoPtr<AttachmentsRefHolder> queue(FB_NEW_POOL(pool) AttachmentsRefHolder(pool));
fb_assert(attachment->getStable());
attachment->getStable()->addRef();
queue->add(attachment->getStable()); 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&) catch (const Exception&)
{} // no-op {} // no-op
@ -8059,26 +8058,38 @@ void JRD_shutdown_attachments(Database* dbb)
MemoryPool& pool = *getDefaultMemoryPool(); MemoryPool& pool = *getDefaultMemoryPool();
AutoPtr<AttachmentsRefHolder> queue(FB_NEW_POOL(pool) AttachmentsRefHolder(pool)); AutoPtr<AttachmentsRefHolder> queue(FB_NEW_POOL(pool) AttachmentsRefHolder(pool));
// Collect attachments to shut down
{ // scope { // scope
Sync guard(&dbb->dbb_sync, "JRD_shutdown_attachments"); Sync guard(&dbb->dbb_sync, FB_FUNCTION);
if (!dbb->dbb_sync.ourExclusiveLock()) if (!dbb->dbb_sync.ourExclusiveLock())
guard.lock(SYNC_SHARED); guard.lock(SYNC_SHARED);
for (Jrd::Attachment* attachment = dbb->dbb_attachments; for (Jrd::Attachment* attachment = dbb->dbb_attachments;
attachment; attachment; attachment = attachment->att_next)
attachment = attachment->att_next)
{ {
if (attachment->att_flags & ATT_shutdown) if (!(attachment->att_flags & ATT_shutdown_manager))
{
fb_assert(attachment->getStable());
attachment->getStable()->addRef();
queue->add(attachment->getStable()); 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); Thread::start(attachmentShutdownThread, queue.release(), THREAD_high);
}
} }
catch (const Exception&) catch (const Exception&)
{} // no-op {} // no-op

View File

@ -521,26 +521,7 @@ static bool shutdown(thread_db* tdbb, SSHORT flag, bool force)
if (force) if (force)
{ {
bool found = false; JRD_shutdown_attachments(dbb);
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);
return true; return true;
} }