windows: Prevent queueing of multiple thread cancel APCs
This avoids any races during cleanup invocation if multiple cancel() requests come in.
This commit is contained in:
@@ -88,10 +88,15 @@ struct private_thread_t {
|
|||||||
bool cancelability;
|
bool cancelability;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has the thread been cancelled
|
* Has the thread been cancelled by thread->cancel()?
|
||||||
*/
|
*/
|
||||||
bool canceled;
|
bool canceled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Did we schedule an APC to docancel()?
|
||||||
|
*/
|
||||||
|
bool cancel_pending;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Active condition variable thread is waiting in, if any
|
* Active condition variable thread is waiting in, if any
|
||||||
*/
|
*/
|
||||||
@@ -357,10 +362,14 @@ METHOD(thread_t, cancel, void,
|
|||||||
if (this->cancelability)
|
if (this->cancelability)
|
||||||
{
|
{
|
||||||
threads_lock->lock(threads_lock);
|
threads_lock->lock(threads_lock);
|
||||||
QueueUserAPC((void*)docancel, this->handle, (uintptr_t)this);
|
if (!this->cancel_pending)
|
||||||
if (this->condvar)
|
|
||||||
{
|
{
|
||||||
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);
|
threads_lock->unlock(threads_lock);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user