Jacek Caban : ntdll: Use server_select in RtlWaitOnAddress.

Alexandre Julliard julliard at winehq.org
Mon Apr 13 15:05:56 CDT 2020


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Apr 10 01:05:29 2020 +0200

ntdll: Use server_select in RtlWaitOnAddress.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/ntdll_misc.h |  4 +++-
 dlls/ntdll/server.c     | 14 +++++-------
 dlls/ntdll/sync.c       | 59 ++++++++++---------------------------------------
 3 files changed, 20 insertions(+), 57 deletions(-)

diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 0c4859343e..f18ab1f227 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -116,6 +116,8 @@ extern sigset_t server_block_set DECLSPEC_HIDDEN;
 extern unsigned int server_call_unlocked( void *req_ptr ) DECLSPEC_HIDDEN;
 extern void server_enter_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset ) DECLSPEC_HIDDEN;
 extern void server_leave_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset ) DECLSPEC_HIDDEN;
+extern unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT flags,
+                                   timeout_t abs_timeout, user_apc_t *user_apc ) DECLSPEC_HIDDEN;
 extern unsigned int server_wait( const select_op_t *select_op, data_size_t size,
                                  UINT flags, const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
 extern unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call, apc_result_t *result ) DECLSPEC_HIDDEN;
@@ -127,7 +129,7 @@ extern NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct o
                                          data_size_t *ret_len ) DECLSPEC_HIDDEN;
 extern NTSTATUS validate_open_object_attributes( const OBJECT_ATTRIBUTES *attr ) DECLSPEC_HIDDEN;
 extern int wait_select_reply( void *cookie ) DECLSPEC_HIDDEN;
-extern void invoke_apc( const apc_call_t *call, apc_result_t *result ) DECLSPEC_HIDDEN;
+extern void invoke_apc( const user_apc_t *apc ) DECLSPEC_HIDDEN;
 
 /* module handling */
 extern LIST_ENTRY tls_links DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index f7d8cc90f1..9053ad2042 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -381,7 +381,7 @@ int wait_select_reply( void *cookie )
 }
 
 
-static void invoke_user_apc( const user_apc_t *apc )
+void invoke_apc( const user_apc_t *apc )
 {
     switch( apc->type )
     {
@@ -410,7 +410,7 @@ static void invoke_user_apc( const user_apc_t *apc )
  * Invoke a single APC.
  *
  */
-void invoke_apc( const apc_call_t *call, apc_result_t *result )
+static void invoke_system_apc( const apc_call_t *call, apc_result_t *result )
 {
     SIZE_T size;
     void *addr;
@@ -422,10 +422,6 @@ void invoke_apc( const apc_call_t *call, apc_result_t *result )
     {
     case APC_NONE:
         break;
-    case APC_USER:
-    case APC_TIMER:
-        invoke_user_apc( &call->user );
-        break;
     case APC_ASYNC_IO:
     {
         IO_STATUS_BLOCK *iosb = wine_server_get_ptr( call->async_io.sb );
@@ -637,7 +633,7 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
             SERVER_END_REQ;
 
             if (ret != STATUS_KERNEL_APC) break;
-            invoke_apc( &call, &result );
+            invoke_system_apc( &call, &result );
 
             /* don't signal multiple times */
             if (size >= sizeof(select_op->signal_and_wait) && select_op->op == SELECT_SIGNAL_AND_WAIT)
@@ -678,7 +674,7 @@ unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT f
     {
         ret = server_select( select_op, size, flags, abs_timeout, &apc );
         if (ret != STATUS_USER_APC) break;
-        invoke_user_apc( &apc );
+        invoke_apc( &apc );
 
         /* if we ran a user apc we have to check once more if additional apcs are queued,
          * but we don't want to wait */
@@ -727,7 +723,7 @@ unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call, a
 
         if (self)
         {
-            invoke_apc( call, result );
+            invoke_system_apc( call, result );
         }
         else
         {
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index a96a120fb6..5ae3b5bacd 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -2458,13 +2458,9 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
 {
     select_op_t select_op;
     NTSTATUS ret;
-    int cookie;
     BOOL user_apc = FALSE;
-    obj_handle_t apc_handle = 0;
-    apc_call_t call;
-    apc_result_t result;
-    abstime_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
-    sigset_t old_set;
+    timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
+    user_apc_t apc;
 
     if (size != 1 && size != 2 && size != 4 && size != 8)
         return STATUS_INVALID_PARAMETER;
@@ -2476,8 +2472,6 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
     select_op.keyed_event.handle = wine_server_obj_handle( keyed_event );
     select_op.keyed_event.key    = wine_server_client_ptr( addr );
 
-    memset( &result, 0, sizeof(result) );
-
     if (abs_timeout < 0)
     {
         LARGE_INTEGER now;
@@ -2486,54 +2480,25 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
         abs_timeout -= now.QuadPart;
     }
 
-    do
+    for (;;)
     {
         RtlEnterCriticalSection( &addr_section );
         if (!compare_addr( addr, cmp, size ))
-        {
-            RtlLeaveCriticalSection( &addr_section );
-            return STATUS_SUCCESS;
-        }
-
-        pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set );
-        for (;;)
-        {
-            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 = server_call_unlocked( req );
-                apc_handle  = reply->apc_handle;
-                call        = reply->call;
-            }
-            SERVER_END_REQ;
-
-            if (ret != STATUS_KERNEL_APC) break;
-            invoke_apc( &call, &result );
-        }
-        pthread_sigmask( SIG_SETMASK, &old_set, NULL );
-
+            ret = STATUS_SUCCESS;
+        else
+            ret = server_select( &select_op, sizeof(select_op.keyed_event), SELECT_INTERRUPTIBLE, abs_timeout, &apc );
         RtlLeaveCriticalSection( &addr_section );
 
-        if (ret == STATUS_USER_APC)
-        {
-            invoke_apc( &call, &result );
-            /* if we ran a user apc we have to check once more if additional apcs are queued,
-             * but we don't want to wait */
-            abs_timeout = 0;
-            user_apc = TRUE;
-        }
+        if (ret != STATUS_USER_APC) break;
+        invoke_apc( &apc );
 
-        if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie );
+        /* if we ran a user apc we have to check once more if additional apcs are queued,
+         * but we don't want to wait */
+        abs_timeout = 0;
+        user_apc = TRUE;
     }
-    while (ret == STATUS_USER_APC || ret == STATUS_KERNEL_APC);
 
     if (ret == STATUS_TIMEOUT && user_apc) ret = STATUS_USER_APC;
-
     return ret;
 }
 




More information about the wine-cvs mailing list