namespace Msp {
namespace Time {
-Timer::Timer():
- slots(slot_compare)
-{ }
-
Timer::~Timer()
{
- while(!slots.empty())
- {
- delete slots.top();
- slots.pop();
- }
+ for(set<SlotProxy>::iterator i=slots.begin(); i!=slots.end(); ++i)
+ delete i->slot;
}
Timer::Slot &Timer::add(const TimeDelta &td)
{
Slot *s=new Slot(td);
mutex.lock();
- slots.push(s);
+ slots.insert(s);
mutex.unlock();
sem.signal();
return *s;
Timer::Slot &Timer::add(const TimeStamp &ts)
{
Slot *s=new Slot(ts);
- mutex.lock();
- slots.push(s);
- mutex.unlock();
+ {
+ MutexLock l(mutex);
+ slots.insert(s);
+ }
sem.signal();
return *s;
}
+void Timer::cancel(Slot &slot)
+{
+ MutexLock l(mutex);
+ if(slots.erase(&slot))
+ delete &slot;
+}
+
void Timer::tick(bool block)
{
if(slots.empty())
{
if(block)
sem.wait();
- return;
+ else
+ return;
}
- mutex.lock();
- Slot *next=slots.top();
- mutex.unlock();
+ Slot *next;
+ {
+ MutexLock l(mutex);
+ next=slots.begin()->slot;
+ }
const TimeStamp &stamp=next->get_timeout();
const TimeStamp t=now();
if(stamp<=t || (block && sem.wait(stamp-t)==1))
{
- slots.pop();
+ slots.erase(slots.begin());
if(next->signal_timeout.emit() && next->increment())
- slots.push(next);
+ slots.insert(next);
else
delete next;
}
}
-bool Timer::slot_compare(Slot *a, Slot *b)
+TimeStamp Timer::get_next_timeout() const
{
- return *a<*b;
+ if(slots.empty())
+ return TimeStamp();
+ return slots.begin()->slot->get_timeout();
}
return true;
}
-bool Timer::Slot::operator<(const Slot &other) const
+
+Timer::SlotProxy::SlotProxy(Slot *s):
+ slot(s)
+{ }
+
+bool Timer::SlotProxy::operator<(const SlotProxy &sp) const
{
- return timeout<other.timeout;
+ return slot->get_timeout()<sp.slot->get_timeout();
}
} // namespace Time