diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2022-10-19 15:44:40 -0500 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2022-10-25 15:13:06 -0500 |
| commit | 98080672cdbbde00ea40a96c1ce38e8a52f24fee (patch) | |
| tree | 9c0b859f147d55d5c4caadccfd764ca84ed7e648 /src/burn/engine/engine.cpp | |
| parent | 28e9c7c14d2a156b55476f6b8e39e13f17aa87b6 (diff) | |
| download | wix-98080672cdbbde00ea40a96c1ce38e8a52f24fee.tar.gz wix-98080672cdbbde00ea40a96c1ce38e8a52f24fee.tar.bz2 wix-98080672cdbbde00ea40a96c1ce38e8a52f24fee.zip | |
Add queutil so Burn can manage its own queue of BA requested actions.
Fixes 6349
Diffstat (limited to 'src/burn/engine/engine.cpp')
| -rw-r--r-- | src/burn/engine/engine.cpp | 95 |
1 files changed, 53 insertions, 42 deletions
diff --git a/src/burn/engine/engine.cpp b/src/burn/engine/engine.cpp index 48196655..c9d2bdcd 100644 --- a/src/burn/engine/engine.cpp +++ b/src/burn/engine/engine.cpp | |||
| @@ -42,8 +42,8 @@ static HRESULT RunApplication( | |||
| 42 | __out BOOL* pfSkipCleanup | 42 | __out BOOL* pfSkipCleanup |
| 43 | ); | 43 | ); |
| 44 | static HRESULT ProcessMessage( | 44 | static HRESULT ProcessMessage( |
| 45 | __in BURN_ENGINE_STATE* pEngineState, | 45 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
| 46 | __in const MSG* pmsg | 46 | __in BOOTSTRAPPER_ENGINE_ACTION* pAction |
| 47 | ); | 47 | ); |
| 48 | static HRESULT DAPI RedirectLoggingOverPipe( | 48 | static HRESULT DAPI RedirectLoggingOverPipe( |
| 49 | __in_z LPCSTR szString, | 49 | __in_z LPCSTR szString, |
| @@ -790,6 +790,19 @@ LExit: | |||
| 790 | return hr; | 790 | return hr; |
| 791 | } | 791 | } |
| 792 | 792 | ||
| 793 | static void CALLBACK FreeQueueItem( | ||
| 794 | __in void* pvValue, | ||
| 795 | __in void* /*pvContext*/ | ||
| 796 | ) | ||
| 797 | { | ||
| 798 | BOOTSTRAPPER_ENGINE_ACTION* pAction = reinterpret_cast<BOOTSTRAPPER_ENGINE_ACTION*>(pvValue); | ||
| 799 | |||
| 800 | LogId(REPORT_WARNING, MSG_IGNORE_OPERATION_AFTER_QUIT, LoggingBurnMessageToString(pAction->dwMessage)); | ||
| 801 | |||
| 802 | CoreBootstrapperEngineActionUninitialize(pAction); | ||
| 803 | MemFree(pAction); | ||
| 804 | } | ||
| 805 | |||
| 793 | static HRESULT RunApplication( | 806 | static HRESULT RunApplication( |
| 794 | __in BURN_ENGINE_STATE* pEngineState, | 807 | __in BURN_ENGINE_STATE* pEngineState, |
| 795 | __out BOOL* pfReloadApp, | 808 | __out BOOL* pfReloadApp, |
| @@ -799,16 +812,20 @@ static HRESULT RunApplication( | |||
| 799 | HRESULT hr = S_OK; | 812 | HRESULT hr = S_OK; |
| 800 | BOOTSTRAPPER_ENGINE_CONTEXT engineContext = { }; | 813 | BOOTSTRAPPER_ENGINE_CONTEXT engineContext = { }; |
| 801 | BOOL fStartupCalled = FALSE; | 814 | BOOL fStartupCalled = FALSE; |
| 802 | BOOL fRet = FALSE; | ||
| 803 | MSG msg = { }; | ||
| 804 | BOOTSTRAPPER_SHUTDOWN_ACTION shutdownAction = BOOTSTRAPPER_SHUTDOWN_ACTION_NONE; | 815 | BOOTSTRAPPER_SHUTDOWN_ACTION shutdownAction = BOOTSTRAPPER_SHUTDOWN_ACTION_NONE; |
| 805 | 816 | BOOTSTRAPPER_ENGINE_ACTION* pAction = NULL; | |
| 806 | ::PeekMessageW(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); | ||
| 807 | 817 | ||
| 808 | // Setup the bootstrapper engine. | 818 | // Setup the bootstrapper engine. |
| 809 | engineContext.dwThreadId = ::GetCurrentThreadId(); | ||
| 810 | engineContext.pEngineState = pEngineState; | 819 | engineContext.pEngineState = pEngineState; |
| 811 | 820 | ||
| 821 | ::InitializeCriticalSection(&engineContext.csQueue); | ||
| 822 | |||
| 823 | engineContext.hQueueSemaphore = ::CreateSemaphoreW(NULL, 0, LONG_MAX, NULL); | ||
| 824 | ExitOnNullWithLastError(engineContext.hQueueSemaphore, hr, "Failed to create semaphore for queue."); | ||
| 825 | |||
| 826 | hr = QueCreate(&engineContext.hQueue); | ||
| 827 | ExitOnFailure(hr, "Failed to create queue for bootstrapper engine."); | ||
| 828 | |||
| 812 | // Load the bootstrapper application. | 829 | // Load the bootstrapper application. |
| 813 | hr = UserExperienceLoad(&pEngineState->userExperience, &engineContext, &pEngineState->command); | 830 | hr = UserExperienceLoad(&pEngineState->userExperience, &engineContext, &pEngineState->command); |
| 814 | ExitOnFailure(hr, "Failed to load BA."); | 831 | ExitOnFailure(hr, "Failed to load BA."); |
| @@ -817,28 +834,24 @@ static HRESULT RunApplication( | |||
| 817 | hr = UserExperienceOnStartup(&pEngineState->userExperience); | 834 | hr = UserExperienceOnStartup(&pEngineState->userExperience); |
| 818 | ExitOnFailure(hr, "Failed to start bootstrapper application."); | 835 | ExitOnFailure(hr, "Failed to start bootstrapper application."); |
| 819 | 836 | ||
| 820 | // Enter the message pump. | 837 | while (!pEngineState->fQuit) |
| 821 | while (0 != (fRet = ::GetMessageW(&msg, NULL, 0, 0))) | ||
| 822 | { | 838 | { |
| 823 | if (-1 == fRet) | 839 | hr = AppWaitForSingleObject(engineContext.hQueueSemaphore, INFINITE); |
| 824 | { | 840 | ExitOnFailure(hr, "Failed to wait on queue event."); |
| 825 | hr = E_UNEXPECTED; | ||
| 826 | ExitOnRootFailure(hr, "Unexpected return value from message pump."); | ||
| 827 | } | ||
| 828 | else | ||
| 829 | { | ||
| 830 | // When the BA makes a request from its own thread, it's common for the PostThreadMessage in externalengine.cpp | ||
| 831 | // to block until this thread waits on something. It's also common for Detect and Plan to never wait on something. | ||
| 832 | // In the extreme case, the engine could be elevating in Apply before the Detect call returned to the BA. | ||
| 833 | // This helps to avoid that situation, which could be blocking a UI thread. | ||
| 834 | ::Sleep(0); | ||
| 835 | 841 | ||
| 836 | ProcessMessage(pEngineState, &msg); | 842 | ::EnterCriticalSection(&engineContext.csQueue); |
| 837 | } | 843 | |
| 838 | } | 844 | hr = QueDequeue(engineContext.hQueue, reinterpret_cast<void**>(&pAction)); |
| 845 | |||
| 846 | ::LeaveCriticalSection(&engineContext.csQueue); | ||
| 839 | 847 | ||
| 840 | // Get exit code. | 848 | ExitOnFailure(hr, "Failed to dequeue action."); |
| 841 | pEngineState->userExperience.dwExitCode = (DWORD)msg.wParam; | 849 | |
| 850 | ProcessMessage(&engineContext, pAction); | ||
| 851 | |||
| 852 | CoreBootstrapperEngineActionUninitialize(pAction); | ||
| 853 | MemFree(pAction); | ||
| 854 | } | ||
| 842 | 855 | ||
| 843 | LExit: | 856 | LExit: |
| 844 | if (fStartupCalled) | 857 | if (fStartupCalled) |
| @@ -864,52 +877,50 @@ LExit: | |||
| 864 | // Unload BA. | 877 | // Unload BA. |
| 865 | UserExperienceUnload(&pEngineState->userExperience, *pfReloadApp); | 878 | UserExperienceUnload(&pEngineState->userExperience, *pfReloadApp); |
| 866 | 879 | ||
| 880 | ::DeleteCriticalSection(&engineContext.csQueue); | ||
| 881 | ReleaseHandle(engineContext.hQueueSemaphore); | ||
| 882 | ReleaseQueue(engineContext.hQueue, FreeQueueItem, &engineContext); | ||
| 883 | |||
| 867 | return hr; | 884 | return hr; |
| 868 | } | 885 | } |
| 869 | 886 | ||
| 870 | static HRESULT ProcessMessage( | 887 | static HRESULT ProcessMessage( |
| 871 | __in BURN_ENGINE_STATE* pEngineState, | 888 | __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, |
| 872 | __in const MSG* pmsg | 889 | __in BOOTSTRAPPER_ENGINE_ACTION* pAction |
| 873 | ) | 890 | ) |
| 874 | { | 891 | { |
| 875 | HRESULT hr = S_OK; | 892 | HRESULT hr = S_OK; |
| 893 | BURN_ENGINE_STATE* pEngineState = pEngineContext->pEngineState; | ||
| 876 | 894 | ||
| 877 | UserExperienceActivateEngine(&pEngineState->userExperience); | 895 | UserExperienceActivateEngine(&pEngineState->userExperience); |
| 878 | 896 | ||
| 879 | if (pEngineState->fQuit) | 897 | switch (pAction->dwMessage) |
| 880 | { | ||
| 881 | LogId(REPORT_WARNING, MSG_IGNORE_OPERATION_AFTER_QUIT, LoggingBurnMessageToString(pmsg->message)); | ||
| 882 | ExitFunction1(hr = E_INVALIDSTATE); | ||
| 883 | } | ||
| 884 | |||
| 885 | switch (pmsg->message) | ||
| 886 | { | 898 | { |
| 887 | case WM_BURN_DETECT: | 899 | case WM_BURN_DETECT: |
| 888 | hr = CoreDetect(pEngineState, reinterpret_cast<HWND>(pmsg->lParam)); | 900 | hr = CoreDetect(pEngineState, pAction->detect.hwndParent); |
| 889 | break; | 901 | break; |
| 890 | 902 | ||
| 891 | case WM_BURN_PLAN: | 903 | case WM_BURN_PLAN: |
| 892 | hr = CorePlan(pEngineState, static_cast<BOOTSTRAPPER_ACTION>(pmsg->lParam)); | 904 | hr = CorePlan(pEngineState, pAction->plan.action); |
| 893 | break; | 905 | break; |
| 894 | 906 | ||
| 895 | case WM_BURN_ELEVATE: | 907 | case WM_BURN_ELEVATE: |
| 896 | hr = CoreElevate(pEngineState, WM_BURN_ELEVATE, reinterpret_cast<HWND>(pmsg->lParam)); | 908 | hr = CoreElevate(pEngineState, WM_BURN_ELEVATE, pAction->elevate.hwndParent); |
| 897 | break; | 909 | break; |
| 898 | 910 | ||
| 899 | case WM_BURN_APPLY: | 911 | case WM_BURN_APPLY: |
| 900 | hr = CoreApply(pEngineState, reinterpret_cast<HWND>(pmsg->lParam)); | 912 | hr = CoreApply(pEngineState, pAction->apply.hwndParent); |
| 901 | break; | 913 | break; |
| 902 | 914 | ||
| 903 | case WM_BURN_LAUNCH_APPROVED_EXE: | 915 | case WM_BURN_LAUNCH_APPROVED_EXE: |
| 904 | hr = CoreLaunchApprovedExe(pEngineState, reinterpret_cast<BURN_LAUNCH_APPROVED_EXE*>(pmsg->lParam)); | 916 | hr = CoreLaunchApprovedExe(pEngineState, &pAction->launchApprovedExe); |
| 905 | break; | 917 | break; |
| 906 | 918 | ||
| 907 | case WM_BURN_QUIT: | 919 | case WM_BURN_QUIT: |
| 908 | hr = CoreQuit(pEngineState, static_cast<int>(pmsg->wParam)); | 920 | CoreQuit(pEngineContext, pAction->quit.dwExitCode); |
| 909 | break; | 921 | break; |
| 910 | } | 922 | } |
| 911 | 923 | ||
| 912 | LExit: | ||
| 913 | UserExperienceDeactivateEngine(&pEngineState->userExperience); | 924 | UserExperienceDeactivateEngine(&pEngineState->userExperience); |
| 914 | 925 | ||
| 915 | return hr; | 926 | return hr; |
