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; |