summaryrefslogtreecommitdiff
path: root/src/libs/dutil/WixToolset.DUtil/monutil.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-06-29 10:28:53 -0500
committerSean Hall <r.sean.hall@gmail.com>2022-06-29 15:08:37 -0500
commit7cca75c8e95f129a21c33f1f4568e90e9e397f9d (patch)
treecb9890caa1ac8bc891d444b6376a5e9f997ca1e3 /src/libs/dutil/WixToolset.DUtil/monutil.cpp
parent3ff6428a068bafd74d8ec072a5fc261c33cc2019 (diff)
downloadwix-7cca75c8e95f129a21c33f1f4568e90e9e397f9d.tar.gz
wix-7cca75c8e95f129a21c33f1f4568e90e9e397f9d.tar.bz2
wix-7cca75c8e95f129a21c33f1f4568e90e9e397f9d.zip
Add AppWaitForSingleObject/MultipleObjects, ThreadWaitForCompletion.
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/monutil.cpp')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/monutil.cpp34
1 files changed, 16 insertions, 18 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/monutil.cpp b/src/libs/dutil/WixToolset.DUtil/monutil.cpp
index 6ad75b56..10954164 100644
--- a/src/libs/dutil/WixToolset.DUtil/monutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/monutil.cpp
@@ -16,6 +16,7 @@
16#define MonExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_MONUTIL, p, x, s, __VA_ARGS__) 16#define MonExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_MONUTIL, p, x, s, __VA_ARGS__)
17#define MonExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_MONUTIL, e, x, s, __VA_ARGS__) 17#define MonExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_MONUTIL, e, x, s, __VA_ARGS__)
18#define MonExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_MONUTIL, g, x, s, __VA_ARGS__) 18#define MonExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_MONUTIL, g, x, s, __VA_ARGS__)
19#define MonExitOnWaitObjectFailure(x, b, s, ...) ExitOnWaitObjectFailureSource(DUTIL_SOURCE_MONUTIL, x, b, s, __VA_ARGS__)
19 20
20const int MON_THREAD_GROWTH = 5; 21const int MON_THREAD_GROWTH = 5;
21const int MON_ARRAY_GROWTH = 40; 22const int MON_ARRAY_GROWTH = 40;
@@ -1101,11 +1102,12 @@ static DWORD WINAPI WaiterThread(
1101{ 1102{
1102 HRESULT hr = S_OK; 1103 HRESULT hr = S_OK;
1103 HRESULT hrTemp = S_OK; 1104 HRESULT hrTemp = S_OK;
1104 DWORD dwRet = 0;
1105 BOOL fAgain = FALSE; 1105 BOOL fAgain = FALSE;
1106 BOOL fContinue = TRUE; 1106 BOOL fContinue = TRUE;
1107 BOOL fNotify = FALSE; 1107 BOOL fNotify = FALSE;
1108 BOOL fRet = FALSE; 1108 BOOL fRet = FALSE;
1109 BOOL fTimedOut = FALSE;
1110 DWORD dwSignaledIndex = 0;
1109 MSG msg = { }; 1111 MSG msg = { };
1110 MON_ADD_MESSAGE *pAddMessage = NULL; 1112 MON_ADD_MESSAGE *pAddMessage = NULL;
1111 MON_REMOVE_MESSAGE *pRemoveMessage = NULL; 1113 MON_REMOVE_MESSAGE *pRemoveMessage = NULL;
@@ -1128,13 +1130,14 @@ static DWORD WINAPI WaiterThread(
1128 1130
1129 do 1131 do
1130 { 1132 {
1131 dwRet = ::WaitForMultipleObjects(pWaiterContext->cHandles - pWaiterContext->cRequestsFailing, pWaiterContext->rgHandles, FALSE, pWaiterContext->cRequestsPending > 0 ? dwWait : INFINITE); 1133 hr = AppWaitForMultipleObjects(pWaiterContext->cHandles - pWaiterContext->cRequestsFailing, pWaiterContext->rgHandles, FALSE, pWaiterContext->cRequestsPending > 0 ? dwWait : INFINITE, &dwSignaledIndex);
1134 MonExitOnWaitObjectFailure(hr, fTimedOut, "Failed to wait for multiple objects.");
1132 1135
1133 uCurrentTime = ::GetTickCount(); 1136 uCurrentTime = ::GetTickCount();
1134 uDeltaInMs = uCurrentTime - uLastTimeInMs; 1137 uDeltaInMs = uCurrentTime - uLastTimeInMs;
1135 uLastTimeInMs = uCurrentTime; 1138 uLastTimeInMs = uCurrentTime;
1136 1139
1137 if (WAIT_OBJECT_0 == dwRet) 1140 if (!fTimedOut && 0 == dwSignaledIndex)
1138 { 1141 {
1139 do 1142 do
1140 { 1143 {
@@ -1391,10 +1394,10 @@ static DWORD WINAPI WaiterThread(
1391 } 1394 }
1392 } while (fAgain); 1395 } while (fAgain);
1393 } 1396 }
1394 else if (dwRet > WAIT_OBJECT_0 && dwRet - WAIT_OBJECT_0 < pWaiterContext->cHandles) 1397 else if (!fTimedOut)
1395 { 1398 {
1396 // OK a handle fired - only notify if it's the actual target, and not just some parent waiting for the target child to exist 1399 // OK a handle fired - only notify if it's the actual target, and not just some parent waiting for the target child to exist
1397 dwRequestIndex = dwRet - WAIT_OBJECT_0 - 1; 1400 dwRequestIndex = dwSignaledIndex - 1;
1398 fNotify = (pWaiterContext->rgRequests[dwRequestIndex].dwPathHierarchyIndex == pWaiterContext->rgRequests[dwRequestIndex].cPathHierarchy - 1); 1401 fNotify = (pWaiterContext->rgRequests[dwRequestIndex].dwPathHierarchyIndex == pWaiterContext->rgRequests[dwRequestIndex].cPathHierarchy - 1);
1399 1402
1400 // Initiate re-waits before we notify callback, to ensure we don't miss a single update 1403 // Initiate re-waits before we notify callback, to ensure we don't miss a single update
@@ -1426,10 +1429,6 @@ static DWORD WINAPI WaiterThread(
1426 } 1429 }
1427 } 1430 }
1428 } 1431 }
1429 else if (WAIT_TIMEOUT != dwRet)
1430 {
1431 MonExitWithLastError(hr, "Failed to wait for multiple objects with return code %u", dwRet);
1432 }
1433 1432
1434 // OK, now that we've checked all triggered handles (resetting silence period timers appropriately), check for any pending notifications that we can finally fire 1433 // OK, now that we've checked all triggered handles (resetting silence period timers appropriately), check for any pending notifications that we can finally fire
1435 // And set dwWait appropriately so we awaken at the right time to fire the next pending notification (in case no further writes occur during that time) 1434 // And set dwWait appropriately so we awaken at the right time to fire the next pending notification (in case no further writes occur during that time)
@@ -1726,10 +1725,10 @@ static LRESULT CALLBACK MonWndProc(
1726 DEV_BROADCAST_HANDLE *pHandle = NULL; 1725 DEV_BROADCAST_HANDLE *pHandle = NULL;
1727 DEV_BROADCAST_VOLUME *pVolume = NULL; 1726 DEV_BROADCAST_VOLUME *pVolume = NULL;
1728 DWORD dwUnitMask = 0; 1727 DWORD dwUnitMask = 0;
1729 DWORD er = ERROR_SUCCESS;
1730 WCHAR chDrive = L'\0'; 1728 WCHAR chDrive = L'\0';
1731 BOOL fArrival = FALSE; 1729 BOOL fArrival = FALSE;
1732 BOOL fReturnTrue = FALSE; 1730 BOOL fReturnTrue = FALSE;
1731 BOOL fTimedOut = FALSE;
1733 CREATESTRUCT *pCreateStruct = NULL; 1732 CREATESTRUCT *pCreateStruct = NULL;
1734 MON_WAITER_CONTEXT *pWaiterContext = NULL; 1733 MON_WAITER_CONTEXT *pWaiterContext = NULL;
1735 MON_STRUCT *pm = NULL; 1734 MON_STRUCT *pm = NULL;
@@ -1821,24 +1820,23 @@ static LRESULT CALLBACK MonWndProc(
1821 } 1820 }
1822 } 1821 }
1823 1822
1824 er = ::WaitForSingleObject(pm->internalWait.hWait, MON_THREAD_WAIT_REMOVE_DEVICE); 1823 hr = AppWaitForSingleObject(pm->internalWait.hWait, MON_THREAD_WAIT_REMOVE_DEVICE);
1824 MonExitOnWaitObjectFailure(hr, fTimedOut, "WaitForSingleObject failed with non-timeout reason while waiting for response from waiter thread");
1825
1825 // Make sure any waiter thread processing really old messages can immediately know that we're no longer waiting for a response 1826 // Make sure any waiter thread processing really old messages can immediately know that we're no longer waiting for a response
1826 if (WAIT_OBJECT_0 == er) 1827 if (!fTimedOut)
1827 { 1828 {
1828 // If the response ID matches what we sent, we actually got a valid reply! 1829 // If the response ID matches what we sent, we actually got a valid reply!
1829 if (pm->internalWait.dwReceiveIteration != pm->internalWait.dwSendIteration) 1830 if (pm->internalWait.dwReceiveIteration != pm->internalWait.dwSendIteration)
1830 { 1831 {
1831 TraceError(HRESULT_FROM_WIN32(er), "Waiter thread received wrong ID reply"); 1832 TraceError(E_UNEXPECTED, "Waiter thread received wrong ID reply");
1832 } 1833 }
1833 } 1834 }
1834 else if (WAIT_TIMEOUT == er)
1835 {
1836 TraceError(HRESULT_FROM_WIN32(er), "No response from any waiter thread for query remove message");
1837 }
1838 else 1835 else
1839 { 1836 {
1840 MonExitWithLastError(hr, "WaitForSingleObject failed with non-timeout reason while waiting for response from waiter thread"); 1837 TraceError(HRESULT_FROM_WIN32(WAIT_TIMEOUT), "No response from any waiter thread for query remove message");
1841 } 1838 }
1839
1842 ++pm->internalWait.dwSendIteration; 1840 ++pm->internalWait.dwSendIteration;
1843 } 1841 }
1844 } 1842 }