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

Reply via email to