Besides still assuming the old condvar-style semantics, it was also
horribly broken and contained potential deadlocks and race conditions.
Not to mention unusable due to a missing constructor.
namespace Msp {
namespace Time {
+Timer::Timer():
+ sem(1),
+ blocking(false)
+{ }
+
Timer::~Timer()
{
for(vector<SlotProxy>::iterator i=slots.begin(); i!=slots.end(); ++i)
Timer::Slot &Timer::add(const TimeDelta &td)
{
Slot *s = new Slot(td);
- mutex.lock();
+ MutexLock l(mutex);
slots.push_back(s);
push_heap(slots.begin(), slots.end());
- mutex.unlock();
- sem.signal();
+ if(blocking)
+ sem.signal();
return *s;
}
Timer::Slot &Timer::add(const TimeStamp &ts)
{
Slot *s = new Slot(ts);
- {
- MutexLock l(mutex);
- slots.push_back(s);
- push_heap(slots.begin(), slots.end());
- }
- sem.signal();
+ MutexLock l(mutex);
+ slots.push_back(s);
+ push_heap(slots.begin(), slots.end());
+ if(blocking)
+ sem.signal();
return *s;
}
if(slots.empty())
{
if(block)
+ {
+ blocking = true;
+ mutex.unlock();
sem.wait();
+ mutex.lock();
+ }
else
return;
}
if(stamp<=t)
break;
else if(block)
+ {
+ blocking = true;
+ mutex.unlock();
sem.wait(stamp-t);
+ mutex.lock();
+ }
else
return;
}
std::vector<SlotProxy> slots;
Semaphore sem;
Mutex mutex;
+ bool blocking;
public:
+ Timer();
~Timer();
/** Adds a timer that will be executed periodically as long as the timeout