aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2014-05-28 17:34:48 +0200
committerMartin Willi <martin@revosec.ch>2014-06-04 15:53:01 +0200
commit9dec601f30ca6558c1b070de1d8e1a2a43eaf49e (patch)
treeae28e06058c7847fd16aaf8d48e578c7081d7069 /src
parent0fa9c958114f902c55f4922631e2ca4e5e77c736 (diff)
downloadstrongswan-9dec601f30ca6558c1b070de1d8e1a2a43eaf49e.tar.bz2
strongswan-9dec601f30ca6558c1b070de1d8e1a2a43eaf49e.tar.xz
windows: Prevent queueing of multiple thread cancel APCs
This avoids any races during cleanup invocation if multiple cancel() requests come in.
Diffstat (limited to 'src')
-rw-r--r--src/libstrongswan/threading/windows/thread.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/src/libstrongswan/threading/windows/thread.c b/src/libstrongswan/threading/windows/thread.c
index 71e56528e..5fa68bb91 100644
--- a/src/libstrongswan/threading/windows/thread.c
+++ b/src/libstrongswan/threading/windows/thread.c
@@ -88,11 +88,16 @@ 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
*/
CONDITION_VARIABLE *condvar;
@@ -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);
}