ntdll: Reorder code to make the select logic clearer.
The wait_select_reply call may return STATUS_USER_APC/STATUS_KERNEL_APC, depending on which APC is about to be returned but the apc call will always be APC_NONE right after the wait. It needs an additional select request to actually return the call. Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
676ad9b0af
commit
6cb2336217
|
@ -607,7 +607,7 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
|
||||||
|
|
||||||
memset( &result, 0, sizeof(result) );
|
memset( &result, 0, sizeof(result) );
|
||||||
|
|
||||||
for (;;)
|
do
|
||||||
{
|
{
|
||||||
SERVER_START_REQ( select )
|
SERVER_START_REQ( select )
|
||||||
{
|
{
|
||||||
|
@ -623,9 +623,13 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
|
||||||
call = reply->call;
|
call = reply->call;
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie );
|
|
||||||
if (ret != STATUS_USER_APC && ret != STATUS_KERNEL_APC) break;
|
/* don't signal multiple times */
|
||||||
if (invoke_apc( &call, &result ))
|
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_USER_APC || ret == STATUS_KERNEL_APC) &&
|
||||||
|
invoke_apc( &call, &result ))
|
||||||
{
|
{
|
||||||
/* 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 */
|
||||||
|
@ -634,10 +638,9 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
|
||||||
size = 0;
|
size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* don't signal multiple times */
|
if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie );
|
||||||
if (size >= sizeof(select_op->signal_and_wait) && select_op->op == SELECT_SIGNAL_AND_WAIT)
|
|
||||||
size = offsetof( select_op_t, signal_and_wait.signal );
|
|
||||||
}
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
|
@ -2470,7 +2470,7 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
|
||||||
|
|
||||||
memset( &result, 0, sizeof(result) );
|
memset( &result, 0, sizeof(result) );
|
||||||
|
|
||||||
for (;;)
|
do
|
||||||
{
|
{
|
||||||
RtlEnterCriticalSection( &addr_section );
|
RtlEnterCriticalSection( &addr_section );
|
||||||
if (!compare_addr( addr, cmp, size ))
|
if (!compare_addr( addr, cmp, size ))
|
||||||
|
@ -2496,16 +2496,18 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
|
||||||
|
|
||||||
RtlLeaveCriticalSection( &addr_section );
|
RtlLeaveCriticalSection( &addr_section );
|
||||||
|
|
||||||
if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie );
|
if ((ret == STATUS_USER_APC || ret == STATUS_KERNEL_APC) &&
|
||||||
if (ret != STATUS_USER_APC && ret != STATUS_KERNEL_APC) break;
|
invoke_apc( &call, &result ))
|
||||||
if (invoke_apc( &call, &result ))
|
|
||||||
{
|
{
|
||||||
/* 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 */
|
||||||
abs_timeout = 0;
|
abs_timeout = 0;
|
||||||
user_apc = TRUE;
|
user_apc = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie );
|
||||||
}
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue