ntdll: Factor out server_select.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4f9cc93108
commit
8701260768
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
|
|
Loading…
Reference in New Issue