Author: astitcher Date: Tue Jun 23 20:02:29 2009 New Revision: 787812 URL: http://svn.apache.org/viewvc?rev=787812&view=rev Log: Add blocking to broker::Timer/TimerTask so cancel and fire() cannot be interleaved.
Modified: qpid/trunk/qpid/cpp/src/qpid/broker/Timer.cpp qpid/trunk/qpid/cpp/src/qpid/broker/Timer.h Modified: qpid/trunk/qpid/cpp/src/qpid/broker/Timer.cpp URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/broker/Timer.cpp?rev=787812&r1=787811&r2=787812&view=diff ============================================================================== --- qpid/trunk/qpid/cpp/src/qpid/broker/Timer.cpp (original) +++ qpid/trunk/qpid/cpp/src/qpid/broker/Timer.cpp Tue Jun 23 20:02:29 2009 @@ -26,6 +26,8 @@ using qpid::sys::Duration; using qpid::sys::Monitor; using qpid::sys::Thread; +using qpid::sys::Mutex; +using qpid::sys::ScopedLock; using namespace qpid::broker; TimerTask::TimerTask(Duration timeout) : @@ -38,7 +40,11 @@ void TimerTask::reset() { time = AbsTime(AbsTime::now(), duration); } -void TimerTask::cancel() { cancelled = true; } +void TimerTask::cancel() { + ScopedLock<Mutex> l(cancelLock); + cancelled = true; +} + bool TimerTask::isCancelled() const { return cancelled; } Timer::Timer() : active(false) @@ -60,16 +66,21 @@ } else { intrusive_ptr<TimerTask> t = tasks.top(); tasks.pop(); + { + ScopedLock<Mutex> l(t->cancelLock); if (t->isCancelled()) { + continue; } else if(t->time < AbsTime::now()) { Monitor::ScopedUnlock u(monitor); t->fire(); + continue; } else { // If the timer was adjusted into the future it might no longer // be the next event, so push and then get top to make sure tasks.push(t); - monitor.wait(tasks.top()->time); } + } + monitor.wait(tasks.top()->time); } } } Modified: qpid/trunk/qpid/cpp/src/qpid/broker/Timer.h URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/broker/Timer.h?rev=787812&r1=787811&r2=787812&view=diff ============================================================================== --- qpid/trunk/qpid/cpp/src/qpid/broker/Timer.h (original) +++ qpid/trunk/qpid/cpp/src/qpid/broker/Timer.h Tue Jun 23 20:02:29 2009 @@ -43,6 +43,7 @@ const qpid::sys::Duration duration; qpid::sys::AbsTime time; volatile bool cancelled; + qpid::sys::Mutex cancelLock; QPID_BROKER_EXTERN TimerTask(qpid::sys::Duration timeout); TimerTask(qpid::sys::AbsTime time); @@ -60,7 +61,7 @@ class Timer : private qpid::sys::Runnable { protected: - qpid::sys::Monitor monitor; + qpid::sys::Monitor monitor; std::priority_queue<boost::intrusive_ptr<TimerTask>, std::vector<boost::intrusive_ptr<TimerTask> >, Later> tasks; --------------------------------------------------------------------- Apache Qpid - AMQP Messaging Implementation Project: http://qpid.apache.org Use/Interact: mailto:commits-subscr...@qpid.apache.org