]> granicus.if.org Git - icinga2/commitdiff
Fix an issue where expired Timer pointers caused other timers to be delayed.
authorGunnar Beutner <gunnar.beutner@netways.de>
Fri, 9 May 2014 17:26:31 +0000 (19:26 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Fri, 9 May 2014 17:26:31 +0000 (19:26 +0200)
Fixes #6179

lib/base/timer.cpp
lib/base/timer.h
lib/icinga/checkable-downtime.cpp
lib/icinga/checkable.cpp
lib/icinga/service.cpp
test/CMakeLists.txt
test/base-timer.cpp

index 8afe259d742baf221a24835fde1f5a7329752bb5..323afc156e8ba6588ce46c878ccd048fc6864dbf 100644 (file)
 
 using namespace icinga;
 
-/**
- * @ingroup base
- */
-struct icinga::TimerNextExtractor
+struct TimerHolder
 {
-       typedef double result_type;
-
-       /**
-        * Extracts the next timestamp from a Timer.
-        *
-        * Note: Caller must hold l_Mutex.
-        *
-        * @param wtimer Weak pointer to the timer.
-        * @returns The next timestamp
-        */
-       double operator()(const weak_ptr<Timer>& wtimer) const
-       {
-               Timer::Ptr timer = wtimer.lock();
-
-               if (!timer)
-                       return 0;
-
-               return timer->m_Next;
-       }
+       Timer::WeakPtr Object;
+       double Next;
 };
 
 typedef boost::multi_index_container<
-       Timer::WeakPtr,
+       TimerHolder,
        boost::multi_index::indexed_by<
-               boost::multi_index::ordered_unique<boost::multi_index::identity<Timer::WeakPtr> >,
-               boost::multi_index::ordered_non_unique<TimerNextExtractor>
+               boost::multi_index::ordered_unique<boost::multi_index::member<TimerHolder, Timer::WeakPtr, &TimerHolder::Object> >,
+               boost::multi_index::ordered_non_unique<boost::multi_index::member<TimerHolder, double, &TimerHolder::Next> >
        >
 > TimerSet;
 
@@ -205,7 +185,11 @@ void Timer::Reschedule(double next)
        if (m_Started) {
                /* Remove and re-add the timer to update the index. */
                l_Timers.erase(GetSelf());
-               l_Timers.insert(GetSelf());
+
+               TimerHolder th;
+               th.Object = GetSelf();
+               th.Next = m_Next;
+               l_Timers.insert(th);
 
                /* Notify the worker that we've rescheduled a timer. */
                l_CV.notify_all();
@@ -242,8 +226,8 @@ void Timer::AdjustTimers(double adjustment)
 
        std::vector<Timer::Ptr> timers;
 
-       BOOST_FOREACH(const Timer::WeakPtr& wtimer, idx) {
-               Timer::Ptr timer = wtimer.lock();
+       BOOST_FOREACH(const TimerHolder& th, idx) {
+               Timer::Ptr timer = th.Object.lock();
 
                if (!timer)
                        continue;
@@ -257,7 +241,11 @@ void Timer::AdjustTimers(double adjustment)
 
        BOOST_FOREACH(const Timer::Ptr& timer, timers) {
                l_Timers.erase(timer);
-               l_Timers.insert(timer);
+
+               TimerHolder th;
+               th.Object = timer;
+               th.Next = timer->m_Next;
+               l_Timers.insert(th);
        }
 
        /* Notify the worker that we've rescheduled some timers. */
@@ -285,7 +273,7 @@ void Timer::TimerThreadProc(void)
                        break;
 
                NextTimerView::iterator it = idx.begin();
-               Timer::Ptr timer = it->lock();
+               Timer::Ptr timer = it->Object.lock();
 
                if (!timer) {
                        /* Remove the timer from the list if it's not alive anymore. */
index 9c089904716cf46089e46bc4c21ea5b1a74a4c30..cb0a81320cdbc79ce72a83dc394bf8ea1e9a22ea 100644 (file)
@@ -26,8 +26,6 @@
 
 namespace icinga {
 
-struct TimerNextExtractor;
-
 /**
  * A timer that periodically triggers an event.
  *
index 62fc77d476c41bced14029a710652438a40c374c..bf0e6b4f8c13af4a5ed82d6494a429c7d7ea5c1b 100644 (file)
@@ -39,6 +39,8 @@ boost::signals2::signal<void (const Checkable::Ptr&, const Downtime::Ptr&, const
 boost::signals2::signal<void (const Checkable::Ptr&, const Downtime::Ptr&, const MessageOrigin&)> Checkable::OnDowntimeRemoved;
 boost::signals2::signal<void (const Checkable::Ptr&, const Downtime::Ptr&)> Checkable::OnDowntimeTriggered;
 
+INITIALIZE_ONCE(&Checkable::StartDowntimesExpiredTimer);
+
 int Checkable::GetNextDowntimeID(void)
 {
        boost::mutex::scoped_lock lock(l_DowntimeMutex);
index 9daf9c88f934ddcaad61fef2068799a7a1ba438c..cf589c492d7208c2ec0a6f3afb00280078437c8b 100644 (file)
@@ -37,8 +37,6 @@ using namespace icinga;
 
 REGISTER_TYPE(Checkable);
 
-INITIALIZE_ONCE(&Checkable::StartDowntimesExpiredTimer);
-
 boost::signals2::signal<void (const Checkable::Ptr&, const String&, const String&, AcknowledgementType, double, const MessageOrigin&)> Checkable::OnAcknowledgementSet;
 boost::signals2::signal<void (const Checkable::Ptr&, const MessageOrigin&)> Checkable::OnAcknowledgementCleared;
 
index 65e2d359dba34c36f55b71c391014ca254e45adb..bb311d70a2f12c3a5352fe5bf10a62729c1a7c82 100644 (file)
@@ -37,8 +37,6 @@ using namespace icinga;
 
 REGISTER_TYPE(Service);
 
-INITIALIZE_ONCE(&Service::StartDowntimesExpiredTimer);
-
 String ServiceNameComposer::MakeName(const String& shortName, const Dictionary::Ptr props) const {
        if (!props)
                return "";
index eb947631fd18deef5f97fae68a8b5db65c9f4fad..cea166d0d68226d289d13a9b31e1dd2251605e6d 100644 (file)
@@ -68,8 +68,8 @@ add_boost_test(base
         base_string/find
         base_timer/construct
         base_timer/interval
-#        base_timer/invoke
-#        base_timer/scope
+        base_timer/invoke
+        base_timer/scope
         base_value/scalar
         base_value/convert
         base_value/format
index 1a75b3fd9700e92ac71e0e81e6ee9ff83fa294b4..1dfaa19f4b420fe89d512cee8ee35c523fa8063b 100644 (file)
@@ -58,7 +58,7 @@ static void Callback(int *counter)
        (*counter)++;
 }
 
-/*BOOST_AUTO_TEST_CASE(invoke)
+BOOST_AUTO_TEST_CASE(invoke)
 {
        int counter;
        Timer::Ptr timer = make_shared<Timer>();
@@ -87,6 +87,6 @@ BOOST_AUTO_TEST_CASE(scope)
        Utility::Sleep(5.5);
 
        BOOST_CHECK(counter >= 4 && counter <= 6);
-}*/
+}
 
 BOOST_AUTO_TEST_SUITE_END()