winpr: fix WaitForMultipleObjectsEx(alertable) call from non winpr threads

When WaitForMultipleObjectsEx is called with the alertable flag set from a non
WinPR thread, we shall not try to treat APC, as for sure there is no APC scheduled,
as previous call that would have scheduled such APC would have failed.
This commit is contained in:
David Fort 2023-03-03 15:45:15 +01:00 committed by akallabeth
parent 2450bf75e8
commit 7c4a774e4e
2 changed files with 32 additions and 23 deletions

View File

@ -63,15 +63,17 @@ DWORD SleepEx(DWORD dwMilliseconds, BOOL bAlertable)
DWORD ret = WAIT_FAILED;
BOOL autoSignalled;
if (!thread)
if (thread)
{
WLog_ERR(TAG, "unable to retrieve currentThread");
return WAIT_FAILED;
/* treat re-entrancy if a completion is calling us */
if (thread->apc.treatingCompletions)
bAlertable = FALSE;
}
/* treat re-entrancy if a completion is calling us */
if (thread->apc.treatingCompletions)
else
{
/* called from a non WinPR thread */
bAlertable = FALSE;
}
if (!bAlertable || !thread->apc.length)
{

View File

@ -263,18 +263,20 @@ DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertabl
if (bAlertable)
{
thread = (WINPR_THREAD*)_GetCurrentThread();
if (!thread)
if (thread)
{
WLog_ERR(TAG, "failed to retrieve currentThread");
return WAIT_FAILED;
/* treat reentrancy, we can't switch to alertable state when we're already
treating completions */
if (thread->apc.treatingCompletions)
bAlertable = FALSE;
else
extraFds = thread->apc.length;
}
/* treat reentrancy, we can't switch to alertable state when we're already
treating completions */
if (thread->apc.treatingCompletions)
bAlertable = FALSE;
else
extraFds = thread->apc.length;
{
/* called from a non WinPR thread */
bAlertable = FALSE;
}
}
int fd = winpr_Handle_getFd(Object);
@ -365,15 +367,20 @@ DWORD WaitForMultipleObjectsEx(DWORD nCount, const HANDLE* lpHandles, BOOL bWait
if (bAlertable)
{
thread = winpr_GetCurrentThread();
if (!thread)
return WAIT_FAILED;
/* treat reentrancy, we can't switch to alertable state when we're already
treating completions */
if (thread->apc.treatingCompletions)
bAlertable = FALSE;
if (thread)
{
/* treat reentrancy, we can't switch to alertable state when we're already
treating completions */
if (thread->apc.treatingCompletions)
bAlertable = FALSE;
else
extraFds = thread->apc.length;
}
else
extraFds = thread->apc.length;
{
/* most probably we're not called from WinPR thread, so we can't have any APC */
bAlertable = FALSE;
}
}
if (!pollset_init(&pollset, nCount + extraFds))