From: Gunnar Beutner Date: Sat, 16 Feb 2013 06:27:45 +0000 (+0100) Subject: Bugfix: Unlock thread mutex while waiting for events. X-Git-Tag: v0.0.2~397 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=172938b19d948eefd1c875bfbc55b4c2d9eef035;p=icinga2 Bugfix: Unlock thread mutex while waiting for events. --- diff --git a/lib/base/application.cpp b/lib/base/application.cpp index b9e944f3b..531a8168d 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 2b68a784d..a236e1cf1 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 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 f5c0d70fe..422746482 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 d336d92a3..2810c0948 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 d687c4fc5..0ac0cdb58 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 m_SubscribedFunctions; boost::thread m_Thread;