Fix a mutex abandon case with WaitHandle.WaitAll in the PAL (#25452)
authorKoundinya Veluri <kouvel@users.noreply.github.com>
Sat, 29 Jun 2019 07:27:20 +0000 (00:27 -0700)
committerGitHub <noreply@github.com>
Sat, 29 Jun 2019 07:27:20 +0000 (00:27 -0700)
Fixes https://github.com/dotnet/coreclr/issues/25108
- Upon a `WaitAll` when all waits are already satisfied, the abandoned flag is overwritten with the abandoned state of the last wait object in the array
- So if the first wait object is an abandoned mutex and the second wait object is a signaled event, the `WaitAll` succeeds and does not report that anything was abandoned
- Fixed to accumulate into the flag instead of overwriting it

src/pal/src/synchmgr/wait.cpp

index 31153ae..1f20ba2 100644 (file)
@@ -531,8 +531,8 @@ DWORD CorUnix::InternalWaitForMultipleObjectsEx(
     iSignaledObjIndex = -1;
     for (i=0;i<(int)nCount;i++)
     {
-        bool fValue;
-        palErr = ppISyncWaitCtrlrs[i]->CanThreadWaitWithoutBlocking(&fValue, &fAbandoned);
+        bool fValue, fWaitObjectAbandoned = false;
+        palErr = ppISyncWaitCtrlrs[i]->CanThreadWaitWithoutBlocking(&fValue, &fWaitObjectAbandoned);
         if (NO_ERROR != palErr)
         {
             ERROR("ISynchWaitController::CanThreadWaitWithoutBlocking() failed for "
@@ -540,6 +540,10 @@ DWORD CorUnix::InternalWaitForMultipleObjectsEx(
             pThread->SetLastError(ERROR_INTERNAL_ERROR);
             goto WFMOExIntReleaseControllers;            
         }
+        if (fWaitObjectAbandoned)
+        {
+            fAbandoned = true;
+        }
         if (fValue)
         {
             iSignaledObjCount++;