mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-25 14:44:32 +02:00
parent
41a9b7d5c0
commit
33cf660c04
@ -31,17 +31,11 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
struct TimerHolder
|
|
||||||
{
|
|
||||||
Timer::WeakPtr Object;
|
|
||||||
double Next;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef boost::multi_index_container<
|
typedef boost::multi_index_container<
|
||||||
TimerHolder,
|
Timer::Holder,
|
||||||
boost::multi_index::indexed_by<
|
boost::multi_index::indexed_by<
|
||||||
boost::multi_index::ordered_unique<boost::multi_index::member<TimerHolder, Timer::WeakPtr, &TimerHolder::Object> >,
|
boost::multi_index::ordered_unique<boost::multi_index::const_mem_fun<Timer::Holder, Timer *, &Timer::Holder::GetObject> >,
|
||||||
boost::multi_index::ordered_non_unique<boost::multi_index::member<TimerHolder, double, &TimerHolder::Next> >
|
boost::multi_index::ordered_non_unique<boost::multi_index::const_mem_fun<Timer::Holder, double, &Timer::Holder::GetNextUnlocked> >
|
||||||
>
|
>
|
||||||
> TimerSet;
|
> TimerSet;
|
||||||
|
|
||||||
@ -58,6 +52,14 @@ Timer::Timer(void)
|
|||||||
: m_Interval(0), m_Next(0)
|
: m_Interval(0), m_Next(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor for the Timer class.
|
||||||
|
*/
|
||||||
|
Timer::~Timer(void)
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the timer sub-system.
|
* Initializes the timer sub-system.
|
||||||
*/
|
*/
|
||||||
@ -153,7 +155,7 @@ void Timer::Stop(void)
|
|||||||
boost::mutex::scoped_lock lock(l_Mutex);
|
boost::mutex::scoped_lock lock(l_Mutex);
|
||||||
|
|
||||||
m_Started = false;
|
m_Started = false;
|
||||||
l_Timers.erase(GetSelf());
|
l_Timers.erase(this);
|
||||||
|
|
||||||
/* Notify the worker thread that we've disabled a timer. */
|
/* Notify the worker thread that we've disabled a timer. */
|
||||||
l_CV.notify_all();
|
l_CV.notify_all();
|
||||||
@ -183,12 +185,8 @@ 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(this);
|
||||||
|
l_Timers.insert(this);
|
||||||
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();
|
||||||
@ -223,14 +221,9 @@ void Timer::AdjustTimers(double adjustment)
|
|||||||
typedef boost::multi_index::nth_index<TimerSet, 1>::type TimerView;
|
typedef boost::multi_index::nth_index<TimerSet, 1>::type TimerView;
|
||||||
TimerView& idx = boost::get<1>(l_Timers);
|
TimerView& idx = boost::get<1>(l_Timers);
|
||||||
|
|
||||||
std::vector<Timer::Ptr> timers;
|
std::vector<Timer *> timers;
|
||||||
|
|
||||||
BOOST_FOREACH(const TimerHolder& th, idx) {
|
|
||||||
Timer::Ptr timer = th.Object.lock();
|
|
||||||
|
|
||||||
if (!timer)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
BOOST_FOREACH(Timer *timer, idx) {
|
||||||
if (abs(now - (timer->m_Next + adjustment)) <
|
if (abs(now - (timer->m_Next + adjustment)) <
|
||||||
abs(now - timer->m_Next)) {
|
abs(now - timer->m_Next)) {
|
||||||
timer->m_Next += adjustment;
|
timer->m_Next += adjustment;
|
||||||
@ -238,13 +231,9 @@ void Timer::AdjustTimers(double adjustment)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FOREACH(const Timer::Ptr& timer, timers) {
|
BOOST_FOREACH(Timer *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. */
|
||||||
@ -272,20 +261,11 @@ void Timer::TimerThreadProc(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
NextTimerView::iterator it = idx.begin();
|
NextTimerView::iterator it = idx.begin();
|
||||||
Timer::Ptr timer = it->Object.lock();
|
Timer *timer = *it;
|
||||||
|
|
||||||
if (!timer) {
|
|
||||||
/* Remove the timer from the list if it's not alive anymore. */
|
|
||||||
idx.erase(it);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
double wait = timer->m_Next - Utility::GetTime();
|
double wait = timer->m_Next - Utility::GetTime();
|
||||||
|
|
||||||
if (wait > 0.01) {
|
if (wait > 0.01) {
|
||||||
/* Make sure the timer we just examined can be destroyed while we're waiting. */
|
|
||||||
timer.reset();
|
|
||||||
|
|
||||||
/* Wait for the next timer. */
|
/* Wait for the next timer. */
|
||||||
l_CV.timed_wait(lock, boost::posix_time::milliseconds(wait * 1000));
|
l_CV.timed_wait(lock, boost::posix_time::milliseconds(wait * 1000));
|
||||||
|
|
||||||
@ -296,9 +276,11 @@ void Timer::TimerThreadProc(void)
|
|||||||
* until the current call is completed. */
|
* until the current call is completed. */
|
||||||
l_Timers.erase(timer);
|
l_Timers.erase(timer);
|
||||||
|
|
||||||
|
Timer::Ptr ptimer = timer->GetSelf();
|
||||||
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
/* Asynchronously call the timer. */
|
/* Asynchronously call the timer. */
|
||||||
Utility::QueueAsyncCallback(boost::bind(&Timer::Call, timer));
|
Utility::QueueAsyncCallback(boost::bind(&Timer::Call, ptimer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(Timer);
|
DECLARE_PTR_TYPEDEFS(Timer);
|
||||||
|
|
||||||
Timer(void);
|
Timer(void);
|
||||||
|
~Timer(void);
|
||||||
|
|
||||||
void SetInterval(double interval);
|
void SetInterval(double interval);
|
||||||
double GetInterval(void) const;
|
double GetInterval(void) const;
|
||||||
@ -54,6 +55,31 @@ public:
|
|||||||
static void Initialize(void);
|
static void Initialize(void);
|
||||||
static void Uninitialize(void);
|
static void Uninitialize(void);
|
||||||
|
|
||||||
|
class Holder {
|
||||||
|
public:
|
||||||
|
Holder(Timer *timer)
|
||||||
|
: m_Timer(timer)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
inline Timer *GetObject(void) const
|
||||||
|
{
|
||||||
|
return m_Timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double GetNextUnlocked(void) const
|
||||||
|
{
|
||||||
|
return m_Timer->m_Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator Timer *(void) const
|
||||||
|
{
|
||||||
|
return m_Timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Timer *m_Timer;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double m_Interval; /**< The interval of the timer. */
|
double m_Interval; /**< The interval of the timer. */
|
||||||
double m_Next; /**< When the next event should happen. */
|
double m_Next; /**< When the next event should happen. */
|
||||||
@ -62,8 +88,6 @@ private:
|
|||||||
void Call();
|
void Call();
|
||||||
|
|
||||||
static void TimerThreadProc(void);
|
static void TimerThreadProc(void);
|
||||||
|
|
||||||
friend struct TimerNextExtractor;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user