From 676ad9b0afeb1d6e591e2b7d48258730f9f84a83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Wed, 5 Feb 2020 11:49:36 +0100 Subject: [PATCH] server: Use STATUS_KERNEL_APC to indicate system APCs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RĂ©mi Bernon Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/ntdll/server.c | 2 +- dlls/ntdll/sync.c | 2 +- server/thread.c | 22 +++++++++++++++++----- server/trace.c | 1 + 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index 089eb3b89aa..73f4d86cf4d 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -624,7 +624,7 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT } SERVER_END_REQ; if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie ); - if (ret != STATUS_USER_APC) break; + if (ret != STATUS_USER_APC && ret != STATUS_KERNEL_APC) break; if (invoke_apc( &call, &result )) { /* if we ran a user apc we have to check once more if additional apcs are queued, diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index c4885973b68..d09b90a9273 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -2497,7 +2497,7 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size RtlLeaveCriticalSection( &addr_section ); if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie ); - if (ret != STATUS_USER_APC) break; + if (ret != STATUS_USER_APC && ret != STATUS_KERNEL_APC) break; if (invoke_apc( &call, &result )) { /* if we ran a user apc we have to check once more if additional apcs are queued, diff --git a/server/thread.c b/server/thread.c index 5844d039682..edf70c61bde 100644 --- a/server/thread.c +++ b/server/thread.c @@ -747,7 +747,7 @@ static int check_wait( struct thread *thread ) assert( wait ); if ((wait->flags & SELECT_INTERRUPTIBLE) && !list_empty( &thread->system_apc )) - return STATUS_USER_APC; + return STATUS_KERNEL_APC; /* Suspended threads may not acquire locks, but they can run system APCs */ if (thread->process->suspend + thread->suspend > 0) return -1; @@ -1081,12 +1081,11 @@ void thread_cancel_apc( struct thread *thread, struct object *owner, enum apc_ty } /* remove the head apc from the queue; the returned object must be released by the caller */ -static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system_only ) +static struct thread_apc *thread_dequeue_apc( struct thread *thread, int system ) { struct thread_apc *apc = NULL; - struct list *ptr = list_head( &thread->system_apc ); + struct list *ptr = list_head( system ? &thread->system_apc : &thread->user_apc ); - if (!ptr && !system_only) ptr = list_head( &thread->user_apc ); if (ptr) { apc = LIST_ENTRY( ptr, struct thread_apc, entry ); @@ -1581,7 +1580,7 @@ DECL_HANDLER(select) while (get_error() == STATUS_USER_APC) { - if (!(apc = thread_dequeue_apc( current, !(req->flags & SELECT_ALERTABLE) ))) + if (!(apc = thread_dequeue_apc( current, 0 ))) break; /* Optimization: ignore APC_NONE calls, they are only used to * wake up a thread, but since we got here the thread woke up already. @@ -1597,6 +1596,19 @@ DECL_HANDLER(select) wake_up( &apc->obj, 0 ); release_object( apc ); } + + if (get_error() == STATUS_KERNEL_APC) + { + apc = thread_dequeue_apc( current, 1 ); + if ((reply->apc_handle = alloc_handle( current->process, apc, SYNCHRONIZE, 0 ))) + reply->call = apc->call; + else + { + apc->executed = 1; + wake_up( &apc->obj, 0 ); + } + release_object( apc ); + } } /* queue an APC for a thread or process */ diff --git a/server/trace.c b/server/trace.c index c3ec6bf3637..79e3f22ee5e 100644 --- a/server/trace.c +++ b/server/trace.c @@ -5577,6 +5577,7 @@ static const struct { "INVALID_READ_MODE", STATUS_INVALID_READ_MODE }, { "INVALID_SECURITY_DESCR", STATUS_INVALID_SECURITY_DESCR }, { "IO_TIMEOUT", STATUS_IO_TIMEOUT }, + { "KERNEL_APC", STATUS_KERNEL_APC }, { "KEY_DELETED", STATUS_KEY_DELETED }, { "MAPPED_FILE_SIZE_ZERO", STATUS_MAPPED_FILE_SIZE_ZERO }, { "MORE_PROCESSING_REQUIRED", STATUS_MORE_PROCESSING_REQUIRED },