mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-22 05:04:30 +02:00
Fix an issue where expired Timer pointers caused other timers to be delayed.
Fixes #6179
This commit is contained in:
parent
4c235f7785
commit
042e4270bf
@ -32,37 +32,17 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
/**
|
struct TimerHolder
|
||||||
* @ingroup base
|
|
||||||
*/
|
|
||||||
struct icinga::TimerNextExtractor
|
|
||||||
{
|
{
|
||||||
typedef double result_type;
|
Timer::WeakPtr Object;
|
||||||
|
double Next;
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef boost::multi_index_container<
|
typedef boost::multi_index_container<
|
||||||
Timer::WeakPtr,
|
TimerHolder,
|
||||||
boost::multi_index::indexed_by<
|
boost::multi_index::indexed_by<
|
||||||
boost::multi_index::ordered_unique<boost::multi_index::identity<Timer::WeakPtr> >,
|
boost::multi_index::ordered_unique<boost::multi_index::member<TimerHolder, Timer::WeakPtr, &TimerHolder::Object> >,
|
||||||
boost::multi_index::ordered_non_unique<TimerNextExtractor>
|
boost::multi_index::ordered_non_unique<boost::multi_index::member<TimerHolder, double, &TimerHolder::Next> >
|
||||||
>
|
>
|
||||||
> TimerSet;
|
> TimerSet;
|
||||||
|
|
||||||
@ -205,7 +185,11 @@ void Timer::Reschedule(double next)
|
|||||||
if (m_Started) {
|
if (m_Started) {
|
||||||
/* Remove and re-add the timer to update the index. */
|
/* Remove and re-add the timer to update the index. */
|
||||||
l_Timers.erase(GetSelf());
|
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. */
|
/* Notify the worker that we've rescheduled a timer. */
|
||||||
l_CV.notify_all();
|
l_CV.notify_all();
|
||||||
@ -242,8 +226,8 @@ void Timer::AdjustTimers(double adjustment)
|
|||||||
|
|
||||||
std::vector<Timer::Ptr> timers;
|
std::vector<Timer::Ptr> timers;
|
||||||
|
|
||||||
BOOST_FOREACH(const Timer::WeakPtr& wtimer, idx) {
|
BOOST_FOREACH(const TimerHolder& th, idx) {
|
||||||
Timer::Ptr timer = wtimer.lock();
|
Timer::Ptr timer = th.Object.lock();
|
||||||
|
|
||||||
if (!timer)
|
if (!timer)
|
||||||
continue;
|
continue;
|
||||||
@ -257,7 +241,11 @@ void Timer::AdjustTimers(double adjustment)
|
|||||||
|
|
||||||
BOOST_FOREACH(const Timer::Ptr& timer, timers) {
|
BOOST_FOREACH(const Timer::Ptr& timer, timers) {
|
||||||
l_Timers.erase(timer);
|
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. */
|
/* Notify the worker that we've rescheduled some timers. */
|
||||||
@ -285,7 +273,7 @@ void Timer::TimerThreadProc(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
NextTimerView::iterator it = idx.begin();
|
NextTimerView::iterator it = idx.begin();
|
||||||
Timer::Ptr timer = it->lock();
|
Timer::Ptr timer = it->Object.lock();
|
||||||
|
|
||||||
if (!timer) {
|
if (!timer) {
|
||||||
/* Remove the timer from the list if it's not alive anymore. */
|
/* Remove the timer from the list if it's not alive anymore. */
|
||||||
|
@ -26,8 +26,6 @@
|
|||||||
|
|
||||||
namespace icinga {
|
namespace icinga {
|
||||||
|
|
||||||
struct TimerNextExtractor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A timer that periodically triggers an event.
|
* A timer that periodically triggers an event.
|
||||||
*
|
*
|
||||||
|
@ -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&, const MessageOrigin&)> Checkable::OnDowntimeRemoved;
|
||||||
boost::signals2::signal<void (const Checkable::Ptr&, const Downtime::Ptr&)> Checkable::OnDowntimeTriggered;
|
boost::signals2::signal<void (const Checkable::Ptr&, const Downtime::Ptr&)> Checkable::OnDowntimeTriggered;
|
||||||
|
|
||||||
|
INITIALIZE_ONCE(&Checkable::StartDowntimesExpiredTimer);
|
||||||
|
|
||||||
int Checkable::GetNextDowntimeID(void)
|
int Checkable::GetNextDowntimeID(void)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(l_DowntimeMutex);
|
boost::mutex::scoped_lock lock(l_DowntimeMutex);
|
||||||
|
@ -37,8 +37,6 @@ using namespace icinga;
|
|||||||
|
|
||||||
REGISTER_TYPE(Checkable);
|
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 String&, const String&, AcknowledgementType, double, const MessageOrigin&)> Checkable::OnAcknowledgementSet;
|
||||||
boost::signals2::signal<void (const Checkable::Ptr&, const MessageOrigin&)> Checkable::OnAcknowledgementCleared;
|
boost::signals2::signal<void (const Checkable::Ptr&, const MessageOrigin&)> Checkable::OnAcknowledgementCleared;
|
||||||
|
|
||||||
|
@ -37,8 +37,6 @@ using namespace icinga;
|
|||||||
|
|
||||||
REGISTER_TYPE(Service);
|
REGISTER_TYPE(Service);
|
||||||
|
|
||||||
INITIALIZE_ONCE(&Service::StartDowntimesExpiredTimer);
|
|
||||||
|
|
||||||
String ServiceNameComposer::MakeName(const String& shortName, const Dictionary::Ptr props) const {
|
String ServiceNameComposer::MakeName(const String& shortName, const Dictionary::Ptr props) const {
|
||||||
if (!props)
|
if (!props)
|
||||||
return "";
|
return "";
|
||||||
|
@ -68,8 +68,8 @@ add_boost_test(base
|
|||||||
base_string/find
|
base_string/find
|
||||||
base_timer/construct
|
base_timer/construct
|
||||||
base_timer/interval
|
base_timer/interval
|
||||||
# base_timer/invoke
|
base_timer/invoke
|
||||||
# base_timer/scope
|
base_timer/scope
|
||||||
base_value/scalar
|
base_value/scalar
|
||||||
base_value/convert
|
base_value/convert
|
||||||
base_value/format
|
base_value/format
|
||||||
|
@ -58,7 +58,7 @@ static void Callback(int *counter)
|
|||||||
(*counter)++;
|
(*counter)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*BOOST_AUTO_TEST_CASE(invoke)
|
BOOST_AUTO_TEST_CASE(invoke)
|
||||||
{
|
{
|
||||||
int counter;
|
int counter;
|
||||||
Timer::Ptr timer = make_shared<Timer>();
|
Timer::Ptr timer = make_shared<Timer>();
|
||||||
@ -87,6 +87,6 @@ BOOST_AUTO_TEST_CASE(scope)
|
|||||||
Utility::Sleep(5.5);
|
Utility::Sleep(5.5);
|
||||||
|
|
||||||
BOOST_CHECK(counter >= 4 && counter <= 6);
|
BOOST_CHECK(counter >= 4 && counter <= 6);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user