Module: wine Branch: master Commit: 4f673d5386f44d4af4459a95b3059cfb887db8c9 URL: https://source.winehq.org/git/wine.git/?a=commit;h=4f673d5386f44d4af4459a95b...
Author: Jacek Caban jacek@codeweavers.com Date: Fri Apr 10 01:05:29 2020 +0200
ntdll: Use server_select in RtlWaitOnAddress.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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; }