Jacek Caban : ntdll: Factor out server_select.

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


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

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

ntdll: Factor out server_select.

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

---

 dlls/ntdll/critsection.c |  2 +-
 dlls/ntdll/exception.c   |  4 +--
 dlls/ntdll/ntdll_misc.h  |  4 +--
 dlls/ntdll/server.c      | 71 +++++++++++++++++++++++++++++++-----------------
 dlls/ntdll/sync.c        | 10 +++----
 5 files changed, 56 insertions(+), 35 deletions(-)

diff --git a/dlls/ntdll/critsection.c b/dlls/ntdll/critsection.c
index e8ffc1ceed..1892d3abcb 100644
--- a/dlls/ntdll/critsection.c
+++ b/dlls/ntdll/critsection.c
@@ -242,7 +242,7 @@ static inline NTSTATUS wait_semaphore( RTL_CRITICAL_SECTION *crit, int timeout )
         time.QuadPart = timeout * (LONGLONG)-10000000;
         select_op.wait.op = SELECT_WAIT;
         select_op.wait.handles[0] = wine_server_obj_handle( sem );
-        ret = server_select( &select_op, offsetof( select_op_t, wait.handles[1] ), 0, &time );
+        ret = server_wait( &select_op, offsetof( select_op_t, wait.handles[1] ), 0, &time );
     }
     return ret;
 }
diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c
index c35312fd1d..7bd7baa135 100644
--- a/dlls/ntdll/exception.c
+++ b/dlls/ntdll/exception.c
@@ -128,7 +128,7 @@ void wait_suspend( CONTEXT *context )
 
     /* wait with 0 timeout, will only return once the thread is no longer suspended */
     timeout.QuadPart = 0;
-    server_select( NULL, 0, SELECT_INTERRUPTIBLE, &timeout );
+    server_wait( NULL, 0, SELECT_INTERRUPTIBLE, &timeout );
 
     /* retrieve the new context */
     SERVER_START_REQ( get_suspend_context )
@@ -185,7 +185,7 @@ NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *con
 
     select_op.wait.op = SELECT_WAIT;
     select_op.wait.handles[0] = handle;
-    server_select( &select_op, offsetof( select_op_t, wait.handles[1] ), SELECT_INTERRUPTIBLE, NULL );
+    server_wait( &select_op, offsetof( select_op_t, wait.handles[1] ), SELECT_INTERRUPTIBLE, NULL );
 
     SERVER_START_REQ( get_exception_status )
     {
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 4601e49034..0c4859343e 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -116,8 +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, const LARGE_INTEGER *timeout ) 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;
 extern int server_remove_fd_from_cache( HANDLE handle ) DECLSPEC_HIDDEN;
 extern int server_get_unix_fd( HANDLE handle, unsigned int access, int *unix_fd,
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index 05f10769a5..f7d8cc90f1 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -606,27 +606,17 @@ void invoke_apc( const apc_call_t *call, apc_result_t *result )
  *              server_select
  */
 unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT flags,
-                            const LARGE_INTEGER *timeout )
+                            timeout_t abs_timeout, user_apc_t *user_apc )
 {
     unsigned int 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;
 
     memset( &result, 0, sizeof(result) );
 
-    if (abs_timeout < 0)
-    {
-        LARGE_INTEGER now;
-
-        RtlQueryPerformanceCounter(&now);
-        abs_timeout -= now.QuadPart;
-    }
-
     do
     {
         pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set );
@@ -646,29 +636,60 @@ 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 );
+
             /* 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 );
         }
         pthread_sigmask( SIG_SETMASK, &old_set, NULL );
+        if (ret != STATUS_PENDING) break;
 
-        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;
-            size = 0;
-        }
-
-        if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie );
+        ret = wait_select_reply( &cookie );
     }
     while (ret == STATUS_USER_APC || ret == STATUS_KERNEL_APC);
 
+    if (ret == STATUS_USER_APC) *user_apc = call.user;
+    return ret;
+}
+
+
+/***********************************************************************
+ *              server_wait
+ */
+unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT flags,
+                          const LARGE_INTEGER *timeout )
+{
+    timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
+    BOOL user_apc = FALSE;
+    unsigned int ret;
+    user_apc_t apc;
+
+    if (abs_timeout < 0)
+    {
+        LARGE_INTEGER now;
+
+        RtlQueryPerformanceCounter(&now);
+        abs_timeout -= now.QuadPart;
+    }
+
+    for (;;)
+    {
+        ret = server_select( select_op, size, flags, abs_timeout, &apc );
+        if (ret != STATUS_USER_APC) break;
+        invoke_user_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 */
+        abs_timeout = 0;
+        user_apc = TRUE;
+        size = 0;
+        /* 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_TIMEOUT && user_apc) ret = STATUS_USER_APC;
 
     /* A test on Windows 2000 shows that Windows always yields during
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index bd71511cfb..a96a120fb6 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -1091,7 +1091,7 @@ static NTSTATUS wait_objects( DWORD count, const HANDLE *handles,
     if (alertable) flags |= SELECT_ALERTABLE;
     select_op.wait.op = wait_any ? SELECT_WAIT : SELECT_WAIT_ALL;
     for (i = 0; i < count; i++) select_op.wait.handles[i] = wine_server_obj_handle( handles[i] );
-    return server_select( &select_op, offsetof( select_op_t, wait.handles[count] ), flags, timeout );
+    return server_wait( &select_op, offsetof( select_op_t, wait.handles[count] ), flags, timeout );
 }
 
 
@@ -1130,7 +1130,7 @@ NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE hSignalObject, HANDLE hWa
     select_op.signal_and_wait.op = SELECT_SIGNAL_AND_WAIT;
     select_op.signal_and_wait.wait = wine_server_obj_handle( hWaitObject );
     select_op.signal_and_wait.signal = wine_server_obj_handle( hSignalObject );
-    return server_select( &select_op, sizeof(select_op.signal_and_wait), flags, timeout );
+    return server_wait( &select_op, sizeof(select_op.signal_and_wait), flags, timeout );
 }
 
 
@@ -1155,7 +1155,7 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou
 {
     /* if alertable, we need to query the server */
     if (alertable)
-        return server_select( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, timeout );
+        return server_wait( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, timeout );
 
     if (!timeout || timeout->QuadPart == TIMEOUT_INFINITE)  /* sleep forever */
     {
@@ -1254,7 +1254,7 @@ NTSTATUS WINAPI NtWaitForKeyedEvent( HANDLE handle, const void *key,
     select_op.keyed_event.op     = SELECT_KEYED_EVENT_WAIT;
     select_op.keyed_event.handle = wine_server_obj_handle( handle );
     select_op.keyed_event.key    = wine_server_client_ptr( key );
-    return server_select( &select_op, sizeof(select_op.keyed_event), flags, timeout );
+    return server_wait( &select_op, sizeof(select_op.keyed_event), flags, timeout );
 }
 
 /******************************************************************************
@@ -1272,7 +1272,7 @@ NTSTATUS WINAPI NtReleaseKeyedEvent( HANDLE handle, const void *key,
     select_op.keyed_event.op     = SELECT_KEYED_EVENT_RELEASE;
     select_op.keyed_event.handle = wine_server_obj_handle( handle );
     select_op.keyed_event.key    = wine_server_client_ptr( key );
-    return server_select( &select_op, sizeof(select_op.keyed_event), flags, timeout );
+    return server_wait( &select_op, sizeof(select_op.keyed_event), flags, timeout );
 }
 
 /******************************************************************




More information about the wine-cvs mailing list