Module: wine Branch: master Commit: f3d41cc7897635311cf868759f95b4bf5253703b URL: https://source.winehq.org/git/wine.git/?a=commit;h=f3d41cc7897635311cf868759...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Apr 30 12:02:19 2021 +0200
server: Don't bother queuing APC_NONE apcs.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernel32/tests/sync.c | 12 ++++++++++++ server/thread.c | 14 +++++--------- server/timer.c | 13 +++++-------- 3 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c index f1c5f01fa84..bde3e15fe26 100644 --- a/dlls/kernel32/tests/sync.c +++ b/dlls/kernel32/tests/sync.c @@ -2738,6 +2738,8 @@ static void test_QueueUserAPC(void)
ret = pNtQueueApcThread(thread, call_user_apc, (ULONG_PTR)user_apc, 0, 0); ok(ret == STATUS_UNSUCCESSFUL, "got %#x\n", ret); + ret = pNtQueueApcThread(thread, NULL, 0, 0, 0); + ok(ret == STATUS_UNSUCCESSFUL, "got %#x\n", ret);
SetLastError(0xdeadbeef); ret = QueueUserAPC(user_apc, thread, 0); @@ -2745,6 +2747,16 @@ static void test_QueueUserAPC(void) ok(GetLastError() == ERROR_GEN_FAILURE, "got %u\n", GetLastError());
CloseHandle(thread); + + ret = QueueUserAPC(user_apc, GetCurrentThread(), 0); + ok(ret, "QueueUserAPC failed err %u\n", GetLastError()); + ret = SleepEx( 100, TRUE ); + ok( ret == WAIT_IO_COMPLETION, "SleepEx returned %u\n", ret); + + ret = pNtQueueApcThread( GetCurrentThread(), NULL, 0, 0, 0 ); + ok( !ret, "got %#x\n", ret); + ret = SleepEx( 100, TRUE ); + ok( ret == WAIT_OBJECT_0, "SleepEx returned %u\n", ret); }
START_TEST(sync) diff --git a/server/thread.c b/server/thread.c index 878ddc08119..7b248f24a30 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1061,6 +1061,7 @@ static inline struct list *get_apc_queue( struct thread *thread, enum apc_type t switch(type) { case APC_NONE: + return NULL; case APC_USER: case APC_TIMER: return &thread->user_apc; @@ -1111,12 +1112,12 @@ static int queue_apc( struct process *process, struct thread *thread, struct thr } } if (!thread) return 0; /* nothing found */ - queue = get_apc_queue( thread, apc->call.type ); + if (!(queue = get_apc_queue( thread, apc->call.type ))) return 1; } else { if (thread->state == TERMINATED) return 0; - queue = get_apc_queue( thread, apc->call.type ); + if (!(queue = get_apc_queue( thread, apc->call.type ))) return 1; /* send signal for system APCs if needed */ if (queue == &thread->system_apc && list_empty( queue ) && !is_in_apc_wait( thread )) { @@ -1640,13 +1641,8 @@ DECL_HANDLER(select)
while (get_error() == STATUS_USER_APC) { - 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. - */ - if (apc->call.type != APC_NONE && - (reply->apc_handle = alloc_handle( current->process, apc, SYNCHRONIZE, 0 ))) + apc = thread_dequeue_apc( current, 0 ); + if ((reply->apc_handle = alloc_handle( current->process, apc, SYNCHRONIZE, 0 ))) { reply->call = apc->call; release_object( apc ); diff --git a/server/timer.c b/server/timer.c index 49483d9ae13..0c787d0b7e0 100644 --- a/server/timer.c +++ b/server/timer.c @@ -126,15 +126,12 @@ static void timer_callback( void *private ) { apc_call_t data;
+ assert (timer->callback); memset( &data, 0, sizeof(data) ); - if (timer->callback) - { - data.type = APC_TIMER; - data.user.timer.func = timer->callback; - data.user.timer.time = timer->when; - data.user.timer.arg = timer->arg; - } - else data.type = APC_NONE; /* wake up only */ + data.type = APC_TIMER; + data.user.timer.func = timer->callback; + data.user.timer.time = timer->when; + data.user.timer.arg = timer->arg;
if (!thread_queue_apc( NULL, timer->thread, &timer->obj, &data )) {