Alexandre Julliard : server: Don't bother queuing APC_NONE apcs.

Alexandre Julliard julliard at winehq.org
Fri Apr 30 16:03:27 CDT 2021


Module: wine
Branch: master
Commit: f3d41cc7897635311cf868759f95b4bf5253703b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=f3d41cc7897635311cf868759f95b4bf5253703b

Author: Alexandre Julliard <julliard at 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 at 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 ))
         {




More information about the wine-cvs mailing list