diff options
author | Martin Willi <martin@revosec.ch> | 2014-05-28 17:34:48 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2014-06-04 15:53:01 +0200 |
commit | 9dec601f30ca6558c1b070de1d8e1a2a43eaf49e (patch) | |
tree | ae28e06058c7847fd16aaf8d48e578c7081d7069 /src | |
parent | 0fa9c958114f902c55f4922631e2ca4e5e77c736 (diff) | |
download | strongswan-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.c | 17 |
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); } |