Rémi Bernon : server: Use STATUS_KERNEL_APC to indicate system APCs.
Alexandre Julliard
julliard at winehq.org
Wed Feb 5 16:53:34 CST 2020
Module: wine
Branch: master
Commit: 676ad9b0afeb1d6e591e2b7d48258730f9f84a83
URL: https://source.winehq.org/git/wine.git/?a=commit;h=676ad9b0afeb1d6e591e2b7d48258730f9f84a83
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Wed Feb 5 11:49:36 2020 +0100
server: Use STATUS_KERNEL_APC to indicate system APCs.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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 089eb3b89a..73f4d86cf4 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 c4885973b6..d09b90a927 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 5844d03968..edf70c61bd 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 c3ec6bf363..79e3f22ee5 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 },
More information about the wine-cvs
mailing list