From d4492eea92d27e78f151e11bf6de49765d4abe5f Mon Sep 17 00:00:00 2001 From: dimitr Date: Sun, 10 Aug 2014 20:11:41 +0000 Subject: [PATCH] Better (methinks) synchronization for the monitoring stuff. Being field tested. --- src/jrd/Attachment.cpp | 23 +++++++++++++---------- src/jrd/Attachment.h | 4 ++-- src/jrd/Monitoring.cpp | 25 +++++++++++-------------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/jrd/Attachment.cpp b/src/jrd/Attachment.cpp index 1c4e98b4c8..d4ce3d58f0 100644 --- a/src/jrd/Attachment.cpp +++ b/src/jrd/Attachment.cpp @@ -434,7 +434,7 @@ void Jrd::Attachment::initLocks(thread_db* tdbb) Lock(tdbb, sizeof(SLONG), LCK_monitor, this, blockingAstMonitor); att_monitor_lock = lock; lock->lck_key.lck_long = att_attachment_id; - LCK_lock(tdbb, lock, LCK_SR, LCK_WAIT); + LCK_lock(tdbb, lock, LCK_EX, LCK_WAIT); // Unless we're a system attachment, allocate the cancellation lock @@ -644,17 +644,20 @@ int Jrd::Attachment::blockingAstMonitor(void* ast_object) AsyncContextHolder tdbb(dbb, FB_FUNCTION, attachment->att_monitor_lock); - try + if (!(attachment->att_flags & ATT_monitor_done)) { - Monitoring::dumpAttachment(tdbb, attachment, true); - } - catch (const Exception& ex) - { - iscLogException("Cannot dump the monitoring data", ex); - } + try + { + Monitoring::dumpAttachment(tdbb, attachment, true); + } + catch (const Exception& ex) + { + iscLogException("Cannot dump the monitoring data", ex); + } - LCK_release(tdbb, attachment->att_monitor_lock); - attachment->att_flags |= ATT_monitor_off; + LCK_downgrade(tdbb, attachment->att_monitor_lock); + attachment->att_flags |= ATT_monitor_done; + } } catch (const Exception&) {} // no-op diff --git a/src/jrd/Attachment.h b/src/jrd/Attachment.h index 10268e7695..f24f228f22 100644 --- a/src/jrd/Attachment.h +++ b/src/jrd/Attachment.h @@ -478,8 +478,8 @@ const ULONG ATT_manual_lock = 0x00800L; // Was locked manually const ULONG ATT_async_manual_lock = 0x01000L; // Async mutex was locked manually const ULONG ATT_purge_started = 0x02000L; // Purge already started - avoid 2 purges at once const ULONG ATT_system = 0x04000L; // Special system attachment -const ULONG ATT_creator = 0x08000L; // This attachment created the DB. -const ULONG ATT_monitor_off = 0x10000L; // Monitoring lock is released +const ULONG ATT_creator = 0x08000L; // This attachment created the DB +const ULONG ATT_monitor_done = 0x10000L; // Monitoring data is refreshed const ULONG ATT_NO_CLEANUP = (ATT_no_cleanup | ATT_notify_gc); diff --git a/src/jrd/Monitoring.cpp b/src/jrd/Monitoring.cpp index 380f641653..232b169b04 100644 --- a/src/jrd/Monitoring.cpp +++ b/src/jrd/Monitoring.cpp @@ -351,15 +351,16 @@ MonitoringSnapshot::MonitoringSnapshot(thread_db* tdbb, MemoryPool& pool) RecordBuffer* const ctx_var_buffer = allocBuffer(tdbb, pool, rel_mon_ctx_vars); RecordBuffer* const mem_usage_buffer = allocBuffer(tdbb, pool, rel_mon_mem_usage); - // Release our own lock - - LCK_release(tdbb, attachment->att_monitor_lock); - attachment->att_flags &= ~ATT_monitor_off; - - // Dump our own data + // Dump our own data and downgrade the lock, if required Monitoring::dumpAttachment(tdbb, attachment, false); + if (!(attachment->att_flags & ATT_monitor_done)) + { + LCK_convert(tdbb, attachment->att_monitor_lock, LCK_SR, LCK_NO_WAIT); + attachment->att_flags |= ATT_monitor_done; + } + // Enumerate active sessions MonitoringData::SessionList sessions(pool); @@ -384,7 +385,7 @@ MonitoringSnapshot::MonitoringSnapshot(thread_db* tdbb, MemoryPool& pool) { lock->lck_key.lck_long = *iter; - if (LCK_lock(tdbb, lock, LCK_EX, LCK_WAIT)) + if (LCK_lock(tdbb, lock, LCK_SR, LCK_WAIT)) LCK_release(tdbb, lock); } } @@ -419,10 +420,6 @@ MonitoringSnapshot::MonitoringSnapshot(thread_db* tdbb, MemoryPool& pool) dbb->dbb_monitoring_data->read(self_att_id, temp_space); } - // Mark our attachment as requesting a new lock - - attachment->att_flags |= ATT_monitor_off; - string databaseName(dbb->dbb_database_name.c_str()); ISC_systemToUtf8(databaseName); @@ -1148,11 +1145,11 @@ void Monitoring::checkState(thread_db* tdbb) Jrd::Attachment* const attachment = tdbb->getAttachment(); - if (attachment->att_flags & ATT_monitor_off) + if (attachment->att_flags & ATT_monitor_done) { // Enable signal handler for the monitoring stuff - attachment->att_flags &= ~ATT_monitor_off; - LCK_lock(tdbb, attachment->att_monitor_lock, LCK_SR, LCK_WAIT); + attachment->att_flags &= ~ATT_monitor_done; + LCK_convert(tdbb, attachment->att_monitor_lock, LCK_EX, LCK_WAIT); } }