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