You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by sh...@apache.org on 2012/11/26 23:02:08 UTC

svn commit: r1413889 - /qpid/trunk/qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp

Author: shuston
Date: Mon Nov 26 22:02:07 2012
New Revision: 1413889

URL: http://svn.apache.org/viewvc?rev=1413889&view=rev
Log:
Prevent multiple threads from dispatching the condition handling at once. Fixes QPID-4424.

Modified:
    qpid/trunk/qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp

Modified: qpid/trunk/qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp?rev=1413889&r1=1413888&r2=1413889&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp Mon Nov 26 22:02:07 2012
@@ -52,13 +52,14 @@ private:
     PollableCondition& parent;
     boost::shared_ptr<sys::Poller> poller;
     LONG isSet;
+    LONG isDispatching;
 };
 
 PollableConditionPrivate::PollableConditionPrivate(const sys::PollableCondition::Callback& cb,
                                                    sys::PollableCondition& parent,
                                                    const boost::shared_ptr<sys::Poller>& poller)
   : IOHandle(INVALID_SOCKET, boost::bind(&PollableConditionPrivate::dispatch, this, _1)),
-    cb(cb), parent(parent), poller(poller), isSet(0)
+    cb(cb), parent(parent), poller(poller), isSet(0), isDispatching(0)
 {
 }
 
@@ -77,7 +78,12 @@ void PollableConditionPrivate::poke()
 void PollableConditionPrivate::dispatch(windows::AsynchIoResult *result)
 {
     delete result;       // Poller::monitorHandle() allocates this
+    // If isDispatching is already set, just return. Else, enter.
+    if (::InterlockedCompareExchange(&isDispatching, 1, 0) == 1)
+        return;
     cb(parent);
+    LONG oops = ::InterlockedDecrement(&isDispatching);   // Result must be 0
+    assert(!oops);
     if (isSet)
         poke();
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org