Commit 0ea963a4 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

ntdll: Call the select request directly in RtlWaitOnAddress().

parent 9b69fe23
......@@ -104,6 +104,8 @@ extern int server_pipe( int fd[2] ) DECLSPEC_HIDDEN;
extern NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct object_attributes **ret,
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 BOOL invoke_apc( const apc_call_t *call, apc_result_t *result ) DECLSPEC_HIDDEN;
/* module handling */
extern LIST_ENTRY tls_links DECLSPEC_HIDDEN;
......
......@@ -349,7 +349,7 @@ void server_leave_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sig
*
* Wait for a reply on the waiting pipe of the current thread.
*/
static int wait_select_reply( void *cookie )
int wait_select_reply( void *cookie )
{
int signaled;
struct wake_up_reply reply;
......@@ -386,7 +386,7 @@ static int wait_select_reply( void *cookie )
*
* Invoke a single APC. Return TRUE if a user APC has been run.
*/
static BOOL invoke_apc( const apc_call_t *call, apc_result_t *result )
BOOL invoke_apc( const apc_call_t *call, apc_result_t *result )
{
BOOL user_apc = FALSE;
SIZE_T size;
......
......@@ -1961,35 +1961,81 @@ NTSTATUS WINAPI RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable,
return status;
}
/***********************************************************************
* RtlWaitOnAddress (NTDLL.@)
*/
NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size,
const LARGE_INTEGER *timeout )
static BOOL compare_addr( const void *addr, const void *cmp, SIZE_T size )
{
switch (size)
{
case 1:
if (*(const UCHAR *)addr != *(const UCHAR *)cmp)
return STATUS_SUCCESS;
break;
return (*(const UCHAR *)addr == *(const UCHAR *)cmp);
case 2:
if (*(const USHORT *)addr != *(const USHORT *)cmp)
return STATUS_SUCCESS;
break;
return (*(const USHORT *)addr == *(const USHORT *)cmp);
case 4:
if (*(const ULONG *)addr != *(const ULONG *)cmp)
return STATUS_SUCCESS;
break;
return (*(const ULONG *)addr == *(const ULONG *)cmp);
case 8:
if (*(const ULONG64 *)addr != *(const ULONG64 *)cmp)
return STATUS_SUCCESS;
break;
default:
return STATUS_INVALID_PARAMETER;
return (*(const ULONG64 *)addr == *(const ULONG64 *)cmp);
}
return NtWaitForKeyedEvent( 0, addr, 0, timeout );
return FALSE;
}
/***********************************************************************
* RtlWaitOnAddress (NTDLL.@)
*/
NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size,
const LARGE_INTEGER *timeout )
{
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;
timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
if (size != 1 && size != 2 && size != 4 && size != 8)
return STATUS_INVALID_PARAMETER;
select_op.keyed_event.op = SELECT_KEYED_EVENT_WAIT;
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) );
for (;;)
{
if (!compare_addr( addr, cmp, size ))
return STATUS_SUCCESS;
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 = wine_server_call( req );
abs_timeout = reply->timeout;
apc_handle = reply->apc_handle;
call = reply->call;
}
SERVER_END_REQ;
if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie );
if (ret != STATUS_USER_APC) break;
if (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_TIMEOUT && user_apc) ret = STATUS_USER_APC;
return ret;
}
/***********************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment