ntdll: Avoid more race conditions in RtlDeregisterWaitEx.
af35aada9b
left some issues unfixed.
Instead of running the callback and returning a retval that indicates
the callback is not running, we sometimes wait for it when we are not
supposed to.
Signed-off-by: Stefan Dösinger <stefan@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3a2834b3a4
commit
759e6f1d8d
|
@ -81,7 +81,7 @@ struct wait_work_item
|
|||
ULONG Flags;
|
||||
HANDLE CompletionEvent;
|
||||
LONG DeleteCount;
|
||||
BOOLEAN CallbackInProgress;
|
||||
int CallbackInProgress;
|
||||
};
|
||||
|
||||
struct timer_queue;
|
||||
|
@ -530,9 +530,14 @@ static DWORD CALLBACK wait_thread_proc(LPVOID Arg)
|
|||
wait_work_item->Context );
|
||||
TimerOrWaitFired = TRUE;
|
||||
}
|
||||
wait_work_item->CallbackInProgress = TRUE;
|
||||
interlocked_xchg( &wait_work_item->CallbackInProgress, TRUE );
|
||||
if (wait_work_item->CompletionEvent)
|
||||
{
|
||||
TRACE( "Work has been canceled.\n" );
|
||||
break;
|
||||
}
|
||||
wait_work_item->Callback( wait_work_item->Context, TimerOrWaitFired );
|
||||
wait_work_item->CallbackInProgress = FALSE;
|
||||
interlocked_xchg( &wait_work_item->CallbackInProgress, FALSE );
|
||||
|
||||
if (wait_work_item->Flags & WT_EXECUTEONLYONCE)
|
||||
break;
|
||||
|
@ -546,7 +551,8 @@ static DWORD CALLBACK wait_thread_proc(LPVOID Arg)
|
|||
{
|
||||
completion_event = wait_work_item->CompletionEvent;
|
||||
delete_wait_work_item( wait_work_item );
|
||||
if (completion_event) NtSetEvent( completion_event, NULL );
|
||||
if (completion_event && completion_event != INVALID_HANDLE_VALUE)
|
||||
NtSetEvent( completion_event, NULL );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -637,14 +643,16 @@ NTSTATUS WINAPI RtlDeregisterWaitEx(HANDLE WaitHandle, HANDLE CompletionEvent)
|
|||
struct wait_work_item *wait_work_item = WaitHandle;
|
||||
NTSTATUS status;
|
||||
HANDLE LocalEvent = NULL;
|
||||
BOOLEAN CallbackInProgress;
|
||||
int CallbackInProgress;
|
||||
|
||||
TRACE( "(%p %p)\n", WaitHandle, CompletionEvent );
|
||||
|
||||
if (WaitHandle == NULL)
|
||||
return STATUS_INVALID_HANDLE;
|
||||
|
||||
interlocked_xchg_ptr( &wait_work_item->CompletionEvent, INVALID_HANDLE_VALUE );
|
||||
CallbackInProgress = wait_work_item->CallbackInProgress;
|
||||
TRACE( "callback in progress %u\n", CallbackInProgress );
|
||||
if (CompletionEvent == INVALID_HANDLE_VALUE || !CallbackInProgress)
|
||||
{
|
||||
status = NtCreateEvent( &LocalEvent, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE );
|
||||
|
@ -666,6 +674,7 @@ NTSTATUS WINAPI RtlDeregisterWaitEx(HANDLE WaitHandle, HANDLE CompletionEvent)
|
|||
}
|
||||
else if (LocalEvent)
|
||||
{
|
||||
TRACE( "Waiting for completion event\n" );
|
||||
NtWaitForSingleObject( LocalEvent, FALSE, NULL );
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue