[icinga-checkins] icinga.org: icinga2/master: Bugfix: Unlock thread mutex while waiting for events.

git at icinga.org git at icinga.org
Sat Feb 16 07:49:47 CET 2013


Module: icinga2
Branch: master
Commit: 172938b19d948eefd1c875bfbc55b4c2d9eef035
URL:    https://git.icinga.org/?p=icinga2.git;a=commit;h=172938b19d948eefd1c875bfbc55b4c2d9eef035

Author: Gunnar Beutner <gunnar.beutner at netways.de>
Date:   Sat Feb 16 07:27:45 2013 +0100

Bugfix: Unlock thread mutex while waiting for events.

---

 lib/base/application.cpp       |    2 +-
 lib/base/eventqueue.cpp        |   14 +++++++++++---
 lib/base/eventqueue.h          |    4 +++-
 lib/base/scriptinterpreter.cpp |    8 ++++++--
 lib/base/scriptinterpreter.h   |    1 +
 5 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/lib/base/application.cpp b/lib/base/application.cpp
index b9e944f..531a816 100644
--- a/lib/base/application.cpp
+++ b/lib/base/application.cpp
@@ -124,7 +124,7 @@ bool Application::ProcessEvents(void)
 	if (m_ShuttingDown)
 		return false;
 
-	GetEQ().ProcessEvents(boost::posix_time::milliseconds(sleep * 1000));
+	GetEQ().ProcessEvents(m_Mutex, boost::posix_time::milliseconds(sleep * 1000));
 
 	DynamicObject::FlushTx();
 
diff --git a/lib/base/eventqueue.cpp b/lib/base/eventqueue.cpp
index 2b68a78..a236e1c 100644
--- a/lib/base/eventqueue.cpp
+++ b/lib/base/eventqueue.cpp
@@ -46,24 +46,33 @@ void EventQueue::Stop(void)
  * Waits for events using the specified timeout value and processes
  * them.
  *
+ * @param mtx The mutex that should be unlocked while waiting. Caller
+ * 	      must have this mutex locked.
  * @param timeout The wait timeout.
  * @returns false if the queue has been stopped, true otherwise.
  */
-bool EventQueue::ProcessEvents(millisec timeout)
+bool EventQueue::ProcessEvents(boost::mutex& mtx, millisec timeout)
 {
 	vector<Callback> events;
 
+	mtx.unlock();
+
 	{
 		boost::mutex::scoped_lock lock(m_Mutex);
 
 		while (m_Events.empty() && !m_Stopped) {
-			if (!m_EventAvailable.timed_wait(lock, timeout))
+			if (!m_EventAvailable.timed_wait(lock, timeout)) {
+				mtx.lock();
+
 				return !m_Stopped;
+			}
 		}
 
 		events.swap(m_Events);
 	}
 
+	mtx.lock();
+
 	BOOST_FOREACH(const Callback& ev, events) {
 		double st = Utility::GetTime();
 
@@ -100,4 +109,3 @@ void EventQueue::Post(const EventQueue::Callback& callback)
 		m_EventAvailable.notify_all();
 	}
 }
-
diff --git a/lib/base/eventqueue.h b/lib/base/eventqueue.h
index f5c0d70..4227464 100644
--- a/lib/base/eventqueue.h
+++ b/lib/base/eventqueue.h
@@ -35,7 +35,7 @@ public:
 
 	EventQueue(void);
 
-	bool ProcessEvents(millisec timeout = boost::posix_time::milliseconds(30000));
+	bool ProcessEvents(boost::mutex& mtx, millisec timeout = boost::posix_time::milliseconds(30000));
 	void Post(const Callback& callback);
 
 	void Stop(void);
@@ -43,6 +43,8 @@ public:
 	boost::thread::id GetOwner(void) const;
 	void SetOwner(boost::thread::id owner);
 
+	boost::mutex& GetMutex(void);
+
 private:
 	boost::thread::id m_Owner;
 
diff --git a/lib/base/scriptinterpreter.cpp b/lib/base/scriptinterpreter.cpp
index d336d92..2810c09 100644
--- a/lib/base/scriptinterpreter.cpp
+++ b/lib/base/scriptinterpreter.cpp
@@ -55,8 +55,12 @@ void ScriptInterpreter::ThreadWorkerProc(void)
 {
 	m_EQ.SetOwner(boost::this_thread::get_id());
 
-	while (m_EQ.ProcessEvents())
-		; /* empty loop */
+	{
+		boost::mutex::scoped_lock lock(m_Mutex);
+
+		while (m_EQ.ProcessEvents(m_Mutex))
+			; /* empty loop */
+	}
 }
 
 void ScriptInterpreter::ScriptFunctionThunk(const ScriptTask::Ptr& task,
diff --git a/lib/base/scriptinterpreter.h b/lib/base/scriptinterpreter.h
index d687c4f..0ac0cdb 100644
--- a/lib/base/scriptinterpreter.h
+++ b/lib/base/scriptinterpreter.h
@@ -49,6 +49,7 @@ protected:
 	void UnsubscribeFunction(const String& name);
 
 private:
+	boost::mutex m_Mutex;
 	EventQueue m_EQ;
 	set<String> m_SubscribedFunctions;
 	boost::thread m_Thread;





More information about the icinga-checkins mailing list