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 ) ...@@ -1610,20 +1610,22 @@ NTSTATUS WINAPI NtAlertThread( HANDLE handle )
NTSTATUS WINAPI NtTerminateThread( HANDLE handle, LONG exit_code ) NTSTATUS WINAPI NtTerminateThread( HANDLE handle, LONG exit_code )
{ {
NTSTATUS ret; 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;
req->handle = wine_server_obj_handle( handle ); ret = wine_server_call( req );
req->exit_code = exit_code; self = !ret && reply->self;
ret = wine_server_call( req ); }
self = !ret && reply->self; SERVER_END_REQ;
}
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; return ret;
} }
......
...@@ -593,6 +593,22 @@ void cancel_process_asyncs( struct process *process ) ...@@ -593,6 +593,22 @@ void cancel_process_asyncs( struct process *process )
cancel_async( process, NULL, NULL, 0 ); 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 */ /* wake up async operations on the queue */
void async_wake_up( struct async_queue *queue, unsigned int status ) void async_wake_up( struct async_queue *queue, unsigned int status )
{ {
......
...@@ -245,6 +245,7 @@ extern struct iosb *async_get_iosb( struct async *async ); ...@@ -245,6 +245,7 @@ extern struct iosb *async_get_iosb( struct async *async );
extern struct thread *async_get_thread( struct async *async ); extern struct thread *async_get_thread( struct async *async );
extern struct async *find_pending_async( struct async_queue *queue ); extern struct async *find_pending_async( struct async_queue *queue );
extern void cancel_process_asyncs( struct process *process ); 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 ) static inline void init_async_queue( struct async_queue *queue )
{ {
......
...@@ -1462,6 +1462,7 @@ DECL_HANDLER(terminate_thread) ...@@ -1462,6 +1462,7 @@ DECL_HANDLER(terminate_thread)
thread->exit_code = req->exit_code; thread->exit_code = req->exit_code;
if (thread != current) kill_thread( thread, 1 ); if (thread != current) kill_thread( thread, 1 );
else reply->self = 1; else reply->self = 1;
cancel_terminating_thread_asyncs( thread );
release_object( 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