Commit 7c597313 authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

ntdll: Cancel asyncs when thread is terminated.

parent 5a8ccc15
......@@ -1610,20 +1610,22 @@ NTSTATUS WINAPI NtAlertThread( HANDLE handle )
NTSTATUS WINAPI NtTerminateThread( HANDLE handle, LONG exit_code )
{
NTSTATUS ret;
BOOL self = (handle == GetCurrentThread());
BOOL self;
if (!self || exit_code)
SERVER_START_REQ( terminate_thread )
{
SERVER_START_REQ( terminate_thread )
{
req->handle = wine_server_obj_handle( handle );
req->exit_code = exit_code;
ret = wine_server_call( req );
self = !ret && reply->self;
}
SERVER_END_REQ;
req->handle = wine_server_obj_handle( handle );
req->exit_code = exit_code;
ret = wine_server_call( req );
self = !ret && reply->self;
}
SERVER_END_REQ;
if (self)
{
server_select( NULL, 0, SELECT_INTERRUPTIBLE, 0, NULL, NULL );
exit_thread( exit_code );
}
if (self) exit_thread( exit_code );
return ret;
}
......
......@@ -593,6 +593,22 @@ void cancel_process_asyncs( struct process *process )
cancel_async( process, NULL, NULL, 0 );
}
void cancel_terminating_thread_asyncs( struct thread *thread )
{
struct async *async;
restart:
LIST_FOR_EACH_ENTRY( async, &thread->process->asyncs, struct async, process_entry )
{
if (async->thread != thread || async->terminated || async->canceled) continue;
if (async->completion && async->data.apc_context && !async->event) continue;
async->canceled = 1;
fd_cancel_async( async->fd, async );
goto restart;
}
}
/* wake up async operations on the queue */
void async_wake_up( struct async_queue *queue, unsigned int status )
{
......
......@@ -245,6 +245,7 @@ extern struct iosb *async_get_iosb( struct async *async );
extern struct thread *async_get_thread( struct async *async );
extern struct async *find_pending_async( struct async_queue *queue );
extern void cancel_process_asyncs( struct process *process );
extern void cancel_terminating_thread_asyncs( struct thread *thread );
static inline void init_async_queue( struct async_queue *queue )
{
......
......@@ -1462,6 +1462,7 @@ DECL_HANDLER(terminate_thread)
thread->exit_code = req->exit_code;
if (thread != current) kill_thread( thread, 1 );
else reply->self = 1;
cancel_terminating_thread_asyncs( thread );
release_object( thread );
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment