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