Rémi Bernon : ntdll: Handle system APCs in a separate inner loop.

Alexandre Julliard julliard at winehq.org
Wed Feb 5 16:53:35 CST 2020


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

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Wed Feb  5 11:49:39 2020 +0100

ntdll: Handle system APCs in a separate inner loop.

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 | 39 ++++++++++++++++++++++-----------------
 dlls/ntdll/sync.c   | 31 ++++++++++++++++++-------------
 2 files changed, 40 insertions(+), 30 deletions(-)

diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index c17ab964d5..15d53b348e 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -606,26 +606,31 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
 
     do
     {
-        SERVER_START_REQ( select )
+        for (;;)
         {
-            req->flags    = flags;
-            req->cookie   = wine_server_client_ptr( &cookie );
-            req->prev_apc = apc_handle;
-            req->timeout  = abs_timeout;
-            wine_server_add_data( req, &result, sizeof(result) );
-            wine_server_add_data( req, select_op, size );
-            ret = wine_server_call( req );
-            abs_timeout = reply->timeout;
-            apc_handle  = reply->apc_handle;
-            call        = reply->call;
-        }
-        SERVER_END_REQ;
+            SERVER_START_REQ( select )
+            {
+                req->flags    = flags;
+                req->cookie   = wine_server_client_ptr( &cookie );
+                req->prev_apc = apc_handle;
+                req->timeout  = abs_timeout;
+                wine_server_add_data( req, &result, sizeof(result) );
+                wine_server_add_data( req, select_op, size );
+                ret = wine_server_call( req );
+                abs_timeout = reply->timeout;
+                apc_handle  = reply->apc_handle;
+                call        = reply->call;
+            }
+            SERVER_END_REQ;
+
+            /* don't signal multiple times */
+            if (size >= sizeof(select_op->signal_and_wait) && select_op->op == SELECT_SIGNAL_AND_WAIT)
+                size = offsetof( select_op_t, signal_and_wait.signal );
 
-        /* don't signal multiple times */
-        if (size >= sizeof(select_op->signal_and_wait) && select_op->op == SELECT_SIGNAL_AND_WAIT)
-            size = offsetof( select_op_t, signal_and_wait.signal );
+            if (ret != STATUS_KERNEL_APC) break;
+            invoke_apc( &call, &result );
+        }
 
-        if (ret == STATUS_KERNEL_APC) invoke_apc( &call, &result );
         if (ret == STATUS_USER_APC)
         {
             invoke_apc( &call, &result );
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index 3e670f47f7..8b12e03eef 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -2479,24 +2479,29 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
             return STATUS_SUCCESS;
         }
 
-        SERVER_START_REQ( select )
+        for (;;)
         {
-            req->flags    = SELECT_INTERRUPTIBLE;
-            req->cookie   = wine_server_client_ptr( &cookie );
-            req->prev_apc = apc_handle;
-            req->timeout  = abs_timeout;
-            wine_server_add_data( req, &result, sizeof(result) );
-            wine_server_add_data( req, &select_op, sizeof(select_op.keyed_event) );
-            ret = wine_server_call( req );
-            abs_timeout = reply->timeout;
-            apc_handle  = reply->apc_handle;
-            call        = reply->call;
+            SERVER_START_REQ( select )
+            {
+                req->flags    = SELECT_INTERRUPTIBLE;
+                req->cookie   = wine_server_client_ptr( &cookie );
+                req->prev_apc = apc_handle;
+                req->timeout  = abs_timeout;
+                wine_server_add_data( req, &result, sizeof(result) );
+                wine_server_add_data( req, &select_op, sizeof(select_op.keyed_event) );
+                ret = wine_server_call( req );
+                abs_timeout = reply->timeout;
+                apc_handle  = reply->apc_handle;
+                call        = reply->call;
+            }
+            SERVER_END_REQ;
+
+            if (ret != STATUS_KERNEL_APC) break;
+            invoke_apc( &call, &result );
         }
-        SERVER_END_REQ;
 
         RtlLeaveCriticalSection( &addr_section );
 
-        if (ret == STATUS_KERNEL_APC) invoke_apc( &call, &result );
         if (ret == STATUS_USER_APC)
         {
             invoke_apc( &call, &result );




More information about the wine-cvs mailing list