]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
windows: Prevent queueing of multiple thread cancel APCs
authorMartin Willi <martin@revosec.ch>
Wed, 28 May 2014 15:34:48 +0000 (17:34 +0200)
committerMartin Willi <martin@revosec.ch>
Wed, 4 Jun 2014 13:53:01 +0000 (15:53 +0200)
This avoids any races during cleanup invocation if multiple cancel() requests
come in.

src/libstrongswan/threading/windows/thread.c

index 71e56528edb923f50e01db3616eddf02cd914978..5fa68bb91cf605d21c557e4804e47f25bb03ff0b 100644 (file)
@@ -88,10 +88,15 @@ struct private_thread_t {
        bool cancelability;
 
        /**
-        * Has the thread been cancelled
+        * Has the thread been cancelled by thread->cancel()?
         */
        bool canceled;
 
+       /**
+        * Did we schedule an APC to docancel()?
+        */
+       bool cancel_pending;
+
        /**
         * Active condition variable thread is waiting in, if any
         */
@@ -357,10 +362,14 @@ METHOD(thread_t, cancel, void,
        if (this->cancelability)
        {
                threads_lock->lock(threads_lock);
-               QueueUserAPC((void*)docancel, this->handle, (uintptr_t)this);
-               if (this->condvar)
+               if (!this->cancel_pending)
                {
-                       WakeAllConditionVariable(this->condvar);
+                       this->cancel_pending = TRUE;
+                       QueueUserAPC((void*)docancel, this->handle, (uintptr_t)this);
+                       if (this->condvar)
+                       {
+                               WakeAllConditionVariable(this->condvar);
+                       }
                }
                threads_lock->unlock(threads_lock);
        }