Commit cbdc0ec7 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Pass a select operation structure to NTDLL_wait_for_multiple_objects.

parent c2ab7a62
...@@ -230,9 +230,12 @@ static inline NTSTATUS wait_semaphore( RTL_CRITICAL_SECTION *crit, int timeout ) ...@@ -230,9 +230,12 @@ static inline NTSTATUS wait_semaphore( RTL_CRITICAL_SECTION *crit, int timeout )
{ {
HANDLE sem = get_semaphore( crit ); HANDLE sem = get_semaphore( crit );
LARGE_INTEGER time; LARGE_INTEGER time;
select_op_t select_op;
time.QuadPart = timeout * (LONGLONG)-10000000; time.QuadPart = timeout * (LONGLONG)-10000000;
ret = NTDLL_wait_for_multiple_objects( 1, &sem, 0, &time, 0 ); select_op.wait.op = SELECT_WAIT;
select_op.wait.handles[0] = wine_server_obj_handle( sem );
ret = NTDLL_wait_for_multiple_objects( &select_op, offsetof( select_op_t, wait.handles[1] ), 0, &time, 0 );
} }
return ret; return ret;
} }
......
...@@ -81,7 +81,7 @@ void wait_suspend( CONTEXT *context ) ...@@ -81,7 +81,7 @@ void wait_suspend( CONTEXT *context )
/* wait with 0 timeout, will only return once the thread is no longer suspended */ /* wait with 0 timeout, will only return once the thread is no longer suspended */
timeout.QuadPart = 0; timeout.QuadPart = 0;
NTDLL_wait_for_multiple_objects( 0, NULL, SELECT_INTERRUPTIBLE, &timeout, 0 ); NTDLL_wait_for_multiple_objects( NULL, 0, SELECT_INTERRUPTIBLE, &timeout, 0 );
/* retrieve the new context */ /* retrieve the new context */
SERVER_START_REQ( get_suspend_context ) SERVER_START_REQ( get_suspend_context )
...@@ -105,9 +105,10 @@ NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *con ...@@ -105,9 +105,10 @@ NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *con
{ {
NTSTATUS ret; NTSTATUS ret;
DWORD i; DWORD i;
HANDLE handle = 0; obj_handle_t handle = 0;
client_ptr_t params[EXCEPTION_MAXIMUM_PARAMETERS]; client_ptr_t params[EXCEPTION_MAXIMUM_PARAMETERS];
context_t server_context; context_t server_context;
select_op_t select_op;
if (!NtCurrentTeb()->Peb->BeingDebugged) return 0; /* no debugger present */ if (!NtCurrentTeb()->Peb->BeingDebugged) return 0; /* no debugger present */
...@@ -126,16 +127,18 @@ NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *con ...@@ -126,16 +127,18 @@ NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *con
req->len = i * sizeof(params[0]); req->len = i * sizeof(params[0]);
wine_server_add_data( req, params, req->len ); wine_server_add_data( req, params, req->len );
wine_server_add_data( req, &server_context, sizeof(server_context) ); wine_server_add_data( req, &server_context, sizeof(server_context) );
if (!wine_server_call( req )) handle = wine_server_ptr_handle( reply->handle ); if (!wine_server_call( req )) handle = reply->handle;
} }
SERVER_END_REQ; SERVER_END_REQ;
if (!handle) return 0; if (!handle) return 0;
NTDLL_wait_for_multiple_objects( 1, &handle, SELECT_INTERRUPTIBLE, NULL, 0 ); select_op.wait.op = SELECT_WAIT;
select_op.wait.handles[0] = handle;
NTDLL_wait_for_multiple_objects( &select_op, offsetof( select_op_t, wait.handles[1] ), SELECT_INTERRUPTIBLE, NULL, 0 );
SERVER_START_REQ( get_exception_status ) SERVER_START_REQ( get_exception_status )
{ {
req->handle = wine_server_obj_handle( handle ); req->handle = handle;
wine_server_set_reply( req, &server_context, sizeof(server_context) ); wine_server_set_reply( req, &server_context, sizeof(server_context) );
ret = wine_server_call( req ); ret = wine_server_call( req );
} }
......
...@@ -63,7 +63,7 @@ extern LPCSTR debugstr_us( const UNICODE_STRING *str ) DECLSPEC_HIDDEN; ...@@ -63,7 +63,7 @@ extern LPCSTR debugstr_us( const UNICODE_STRING *str ) DECLSPEC_HIDDEN;
extern LPCSTR debugstr_ObjectAttributes(const OBJECT_ATTRIBUTES *oa) DECLSPEC_HIDDEN; extern LPCSTR debugstr_ObjectAttributes(const OBJECT_ATTRIBUTES *oa) DECLSPEC_HIDDEN;
extern NTSTATUS NTDLL_queue_process_apc( HANDLE process, const apc_call_t *call, apc_result_t *result ) DECLSPEC_HIDDEN; extern NTSTATUS NTDLL_queue_process_apc( HANDLE process, const apc_call_t *call, apc_result_t *result ) DECLSPEC_HIDDEN;
extern NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UINT flags, extern NTSTATUS NTDLL_wait_for_multiple_objects( const select_op_t *select_op, data_size_t size, UINT flags,
const LARGE_INTEGER *timeout, HANDLE signal_object ) DECLSPEC_HIDDEN; const LARGE_INTEGER *timeout, HANDLE signal_object ) DECLSPEC_HIDDEN;
/* init routines */ /* init routines */
......
...@@ -1106,12 +1106,10 @@ NTSTATUS NTDLL_queue_process_apc( HANDLE process, const apc_call_t *call, apc_re ...@@ -1106,12 +1106,10 @@ NTSTATUS NTDLL_queue_process_apc( HANDLE process, const apc_call_t *call, apc_re
* *
* Implementation of NtWaitForMultipleObjects * Implementation of NtWaitForMultipleObjects
*/ */
NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UINT flags, NTSTATUS NTDLL_wait_for_multiple_objects( const select_op_t *select_op, data_size_t size, UINT flags,
const LARGE_INTEGER *timeout, HANDLE signal_object ) const LARGE_INTEGER *timeout, HANDLE signal_object )
{ {
select_op_t select_op;
NTSTATUS ret; NTSTATUS ret;
UINT i;
int cookie; int cookie;
BOOL user_apc = FALSE; BOOL user_apc = FALSE;
obj_handle_t apc_handle = 0; obj_handle_t apc_handle = 0;
...@@ -1120,8 +1118,6 @@ NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UIN ...@@ -1120,8 +1118,6 @@ NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UIN
timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE; timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
memset( &result, 0, sizeof(result) ); memset( &result, 0, sizeof(result) );
select_op.wait.op = SELECT_WAIT;
for (i = 0; i < count; i++) select_op.wait.handles[i] = wine_server_obj_handle( handles[i] );
for (;;) for (;;)
{ {
...@@ -1133,7 +1129,7 @@ NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UIN ...@@ -1133,7 +1129,7 @@ NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UIN
req->prev_apc = apc_handle; req->prev_apc = apc_handle;
req->timeout = abs_timeout; req->timeout = abs_timeout;
wine_server_add_data( req, &result, sizeof(result) ); wine_server_add_data( req, &result, sizeof(result) );
wine_server_add_data( req, &select_op, offsetof( select_op_t, wait.handles[count] )); wine_server_add_data( req, select_op, size );
ret = wine_server_call( req ); ret = wine_server_call( req );
abs_timeout = reply->timeout; abs_timeout = reply->timeout;
apc_handle = reply->apc_handle; apc_handle = reply->apc_handle;
...@@ -1172,13 +1168,16 @@ NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles, ...@@ -1172,13 +1168,16 @@ NTSTATUS WINAPI NtWaitForMultipleObjects( DWORD count, const HANDLE *handles,
BOOLEAN wait_all, BOOLEAN alertable, BOOLEAN wait_all, BOOLEAN alertable,
const LARGE_INTEGER *timeout ) const LARGE_INTEGER *timeout )
{ {
UINT flags = SELECT_INTERRUPTIBLE; select_op_t select_op;
UINT i, flags = SELECT_INTERRUPTIBLE;
if (!count || count > MAXIMUM_WAIT_OBJECTS) return STATUS_INVALID_PARAMETER_1; if (!count || count > MAXIMUM_WAIT_OBJECTS) return STATUS_INVALID_PARAMETER_1;
if (wait_all) flags |= SELECT_ALL; if (wait_all) flags |= SELECT_ALL;
if (alertable) flags |= SELECT_ALERTABLE; if (alertable) flags |= SELECT_ALERTABLE;
return NTDLL_wait_for_multiple_objects( count, handles, flags, timeout, 0 ); select_op.wait.op = SELECT_WAIT;
for (i = 0; i < count; i++) select_op.wait.handles[i] = wine_server_obj_handle( handles[i] );
return NTDLL_wait_for_multiple_objects( &select_op, offsetof( select_op_t, wait.handles[count] ), flags, timeout, 0 );
} }
...@@ -1197,11 +1196,14 @@ NTSTATUS WINAPI NtWaitForSingleObject(HANDLE handle, BOOLEAN alertable, const LA ...@@ -1197,11 +1196,14 @@ NTSTATUS WINAPI NtWaitForSingleObject(HANDLE handle, BOOLEAN alertable, const LA
NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE hSignalObject, HANDLE hWaitObject, NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE hSignalObject, HANDLE hWaitObject,
BOOLEAN alertable, const LARGE_INTEGER *timeout ) BOOLEAN alertable, const LARGE_INTEGER *timeout )
{ {
select_op_t select_op;
UINT flags = SELECT_INTERRUPTIBLE; UINT flags = SELECT_INTERRUPTIBLE;
if (!hSignalObject) return STATUS_INVALID_HANDLE; if (!hSignalObject) return STATUS_INVALID_HANDLE;
if (alertable) flags |= SELECT_ALERTABLE; if (alertable) flags |= SELECT_ALERTABLE;
return NTDLL_wait_for_multiple_objects( 1, &hWaitObject, flags, timeout, hSignalObject ); select_op.wait.op = SELECT_WAIT;
select_op.wait.handles[0] = wine_server_obj_handle( hWaitObject );
return NTDLL_wait_for_multiple_objects( &select_op, offsetof( select_op_t, wait.handles[1] ), flags, timeout, hSignalObject );
} }
...@@ -1226,7 +1228,7 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou ...@@ -1226,7 +1228,7 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou
{ {
/* if alertable, we need to query the server */ /* if alertable, we need to query the server */
if (alertable) if (alertable)
return NTDLL_wait_for_multiple_objects( 0, NULL, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, return NTDLL_wait_for_multiple_objects( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE,
timeout, 0 ); timeout, 0 );
if (!timeout || timeout->QuadPart == TIMEOUT_INFINITE) /* sleep forever */ if (!timeout || timeout->QuadPart == TIMEOUT_INFINITE) /* sleep forever */
......
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