Commit 4f673d53 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

ntdll: Use server_select in RtlWaitOnAddress.

parent 87012607
...@@ -116,6 +116,8 @@ extern sigset_t server_block_set DECLSPEC_HIDDEN; ...@@ -116,6 +116,8 @@ extern sigset_t server_block_set DECLSPEC_HIDDEN;
extern unsigned int server_call_unlocked( void *req_ptr ) 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_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 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, extern unsigned int server_wait( const select_op_t *select_op, data_size_t size,
UINT flags, const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN; 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 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 ...@@ -127,7 +129,7 @@ extern NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct o
data_size_t *ret_len ) DECLSPEC_HIDDEN; data_size_t *ret_len ) DECLSPEC_HIDDEN;
extern NTSTATUS validate_open_object_attributes( const OBJECT_ATTRIBUTES *attr ) DECLSPEC_HIDDEN; extern NTSTATUS validate_open_object_attributes( const OBJECT_ATTRIBUTES *attr ) DECLSPEC_HIDDEN;
extern int wait_select_reply( void *cookie ) 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 */ /* module handling */
extern LIST_ENTRY tls_links DECLSPEC_HIDDEN; extern LIST_ENTRY tls_links DECLSPEC_HIDDEN;
......
...@@ -381,7 +381,7 @@ int wait_select_reply( void *cookie ) ...@@ -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 ) switch( apc->type )
{ {
...@@ -410,7 +410,7 @@ static void invoke_user_apc( const user_apc_t *apc ) ...@@ -410,7 +410,7 @@ static void invoke_user_apc( const user_apc_t *apc )
* Invoke a single 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; SIZE_T size;
void *addr; void *addr;
...@@ -422,10 +422,6 @@ void invoke_apc( const apc_call_t *call, apc_result_t *result ) ...@@ -422,10 +422,6 @@ void invoke_apc( const apc_call_t *call, apc_result_t *result )
{ {
case APC_NONE: case APC_NONE:
break; break;
case APC_USER:
case APC_TIMER:
invoke_user_apc( &call->user );
break;
case APC_ASYNC_IO: case APC_ASYNC_IO:
{ {
IO_STATUS_BLOCK *iosb = wine_server_get_ptr( call->async_io.sb ); 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 ...@@ -637,7 +633,7 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
SERVER_END_REQ; SERVER_END_REQ;
if (ret != STATUS_KERNEL_APC) break; if (ret != STATUS_KERNEL_APC) break;
invoke_apc( &call, &result ); invoke_system_apc( &call, &result );
/* don't signal multiple times */ /* don't signal multiple times */
if (size >= sizeof(select_op->signal_and_wait) && select_op->op == SELECT_SIGNAL_AND_WAIT) 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 ...@@ -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 ); ret = server_select( select_op, size, flags, abs_timeout, &apc );
if (ret != STATUS_USER_APC) break; 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, /* if we ran a user apc we have to check once more if additional apcs are queued,
* but we don't want to wait */ * 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 ...@@ -727,7 +723,7 @@ unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call, a
if (self) if (self)
{ {
invoke_apc( call, result ); invoke_system_apc( call, result );
} }
else else
{ {
......
...@@ -2458,13 +2458,9 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size ...@@ -2458,13 +2458,9 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
{ {
select_op_t select_op; select_op_t select_op;
NTSTATUS ret; NTSTATUS ret;
int cookie;
BOOL user_apc = FALSE; BOOL user_apc = FALSE;
obj_handle_t apc_handle = 0; timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
apc_call_t call; user_apc_t apc;
apc_result_t result;
abstime_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
sigset_t old_set;
if (size != 1 && size != 2 && size != 4 && size != 8) if (size != 1 && size != 2 && size != 4 && size != 8)
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
...@@ -2476,8 +2472,6 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size ...@@ -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.handle = wine_server_obj_handle( keyed_event );
select_op.keyed_event.key = wine_server_client_ptr( addr ); select_op.keyed_event.key = wine_server_client_ptr( addr );
memset( &result, 0, sizeof(result) );
if (abs_timeout < 0) if (abs_timeout < 0)
{ {
LARGE_INTEGER now; LARGE_INTEGER now;
...@@ -2486,54 +2480,25 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size ...@@ -2486,54 +2480,25 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
abs_timeout -= now.QuadPart; abs_timeout -= now.QuadPart;
} }
do for (;;)
{ {
RtlEnterCriticalSection( &addr_section ); RtlEnterCriticalSection( &addr_section );
if (!compare_addr( addr, cmp, size )) if (!compare_addr( addr, cmp, size ))
{ ret = STATUS_SUCCESS;
RtlLeaveCriticalSection( &addr_section ); else
return STATUS_SUCCESS; ret = server_select( &select_op, sizeof(select_op.keyed_event), SELECT_INTERRUPTIBLE, abs_timeout, &apc );
}
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 );
RtlLeaveCriticalSection( &addr_section ); RtlLeaveCriticalSection( &addr_section );
if (ret == STATUS_USER_APC) if (ret != STATUS_USER_APC) break;
{ invoke_apc( &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_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; if (ret == STATUS_TIMEOUT && user_apc) ret = STATUS_USER_APC;
return ret; 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