Commit 544fd950 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

ntdll: Process system APCs while the signals are blocked.

This makes sure that system APC, such as APC_BREAK_PROCESS do not get interrupted in the middle of their execution, and that the APC completion notification is always correctly sent back to the caller. Otherwise DbgBreakProcess sometimes did not return until WaitForDebugEvent/ContinueDebugEvent are called, because of a race condition between the APC servicing thread, and the newly created exception thread. Signed-off-by: 's avatarRémi Bernon <rbernon@codeweavers.com> Signed-off-by: 's avatarJacek Caban <jacek@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 2dc99bfb
......@@ -601,11 +601,13 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
apc_call_t call;
apc_result_t result;
timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
sigset_t old_set;
memset( &result, 0, sizeof(result) );
do
{
pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set );
for (;;)
{
SERVER_START_REQ( select )
......@@ -616,7 +618,7 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
req->timeout = abs_timeout;
wine_server_add_data( req, &result, sizeof(result) );
wine_server_add_data( req, select_op, size );
ret = wine_server_call( req );
ret = server_call_unlocked( req );
abs_timeout = reply->timeout;
apc_handle = reply->apc_handle;
call = reply->call;
......@@ -630,6 +632,7 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
if (ret != STATUS_KERNEL_APC) break;
invoke_apc( &call, &result );
}
pthread_sigmask( SIG_SETMASK, &old_set, NULL );
if (ret == STATUS_USER_APC)
{
......
......@@ -2457,6 +2457,7 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
apc_call_t call;
apc_result_t result;
timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
sigset_t old_set;
if (size != 1 && size != 2 && size != 4 && size != 8)
return STATUS_INVALID_PARAMETER;
......@@ -2479,6 +2480,7 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
return STATUS_SUCCESS;
}
pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set );
for (;;)
{
SERVER_START_REQ( select )
......@@ -2489,7 +2491,7 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
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 );
ret = server_call_unlocked( req );
abs_timeout = reply->timeout;
apc_handle = reply->apc_handle;
call = reply->call;
......@@ -2499,6 +2501,7 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
if (ret != STATUS_KERNEL_APC) break;
invoke_apc( &call, &result );
}
pthread_sigmask( SIG_SETMASK, &old_set, NULL );
RtlLeaveCriticalSection( &addr_section );
......
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