[PATCH 2/5] ntdll: Reorder code to make the select logic clearer.
Rémi Bernon
rbernon at codeweavers.com
Tue Feb 4 04:09:22 CST 2020
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 at codeweavers.com>
---
dlls/ntdll/server.c | 15 +++++++++------
dlls/ntdll/sync.c | 8 +++++---
2 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index 73f4d86cf4d..9e5ef4dde12 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -623,9 +623,13 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
call = reply->call;
}
SERVER_END_REQ;
- if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie );
- if (ret != STATUS_USER_APC && ret != STATUS_KERNEL_APC) break;
- if (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_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,
* but we don't want to wait */
@@ -634,9 +638,8 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
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_PENDING) ret = wait_select_reply( &cookie );
+ if (ret != STATUS_USER_APC && ret != STATUS_KERNEL_APC) break;
}
if (ret == STATUS_TIMEOUT && user_apc) ret = STATUS_USER_APC;
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index d09b90a9273..38ed3e04eff 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -2496,15 +2496,17 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
RtlLeaveCriticalSection( &addr_section );
- if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie );
- if (ret != STATUS_USER_APC && ret != STATUS_KERNEL_APC) break;
- if (invoke_apc( &call, &result ))
+ 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,
* but we don't want to wait */
abs_timeout = 0;
user_apc = TRUE;
}
+
+ if (ret == STATUS_PENDING) ret = wait_select_reply( &cookie );
+ if (ret != STATUS_USER_APC && ret != STATUS_KERNEL_APC) break;
}
if (ret == STATUS_TIMEOUT && user_apc) ret = STATUS_USER_APC;
--
2.25.0
More information about the wine-devel
mailing list