From: Martin Willi Date: Wed, 28 May 2014 15:34:48 +0000 (+0200) Subject: windows: Prevent queueing of multiple thread cancel APCs X-Git-Tag: 5.2.0dr6~24^2~94 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9dec601f30ca6558c1b070de1d8e1a2a43eaf49e;p=thirdparty%2Fstrongswan.git windows: Prevent queueing of multiple thread cancel APCs This avoids any races during cleanup invocation if multiple cancel() requests come in. --- diff --git a/src/libstrongswan/threading/windows/thread.c b/src/libstrongswan/threading/windows/thread.c index 71e56528ed..5fa68bb91c 100644 --- a/src/libstrongswan/threading/windows/thread.c +++ b/src/libstrongswan/threading/windows/thread.c @@ -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); }