aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-05-02 17:49:18 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-05-11 19:11:19 -0500
commit8b8029f15e6e3de2fcf855037fe75dbb765475dc (patch)
treee48ee1df07f278a7a0414e9bb41d4880a126a9cd
parent4e2054b3ee31b2b9fae3269d76e08817a36fb51f (diff)
downloadwix-8b8029f15e6e3de2fcf855037fe75dbb765475dc.tar.gz
wix-8b8029f15e6e3de2fcf855037fe75dbb765475dc.tar.bz2
wix-8b8029f15e6e3de2fcf855037fe75dbb765475dc.zip
Synchronize access to cOverallProgressTicks between Cache and Execute.
#4414
-rw-r--r--src/burn/engine/apply.cpp62
-rw-r--r--src/burn/engine/apply.h7
-rw-r--r--src/burn/engine/core.cpp43
-rw-r--r--src/burn/engine/core.h8
4 files changed, 60 insertions, 60 deletions
diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp
index f0b78e81..b4fa9dac 100644
--- a/src/burn/engine/apply.cpp
+++ b/src/burn/engine/apply.cpp
@@ -56,11 +56,11 @@ typedef struct _BURN_CACHE_PROGRESS_CONTEXT
56typedef struct _BURN_EXECUTE_CONTEXT 56typedef struct _BURN_EXECUTE_CONTEXT
57{ 57{
58 BURN_USER_EXPERIENCE* pUX; 58 BURN_USER_EXPERIENCE* pUX;
59 BURN_APPLY_CONTEXT* pApplyContext;
59 BOOL fRollback; 60 BOOL fRollback;
60 BURN_PACKAGE* pExecutingPackage; 61 BURN_PACKAGE* pExecutingPackage;
61 DWORD cExecutedPackages; 62 DWORD cExecutedPackages;
62 DWORD cExecutePackagesTotal; 63 DWORD cExecutePackagesTotal;
63 DWORD* pcOverallProgressTicks;
64} BURN_EXECUTE_CONTEXT; 64} BURN_EXECUTE_CONTEXT;
65 65
66 66
@@ -187,7 +187,6 @@ static void DoRollbackCache(
187static HRESULT DoExecuteAction( 187static HRESULT DoExecuteAction(
188 __in BURN_ENGINE_STATE* pEngineState, 188 __in BURN_ENGINE_STATE* pEngineState,
189 __in BURN_EXECUTE_ACTION* pExecuteAction, 189 __in BURN_EXECUTE_ACTION* pExecuteAction,
190 __in_opt HANDLE hCacheThread,
191 __in BURN_EXECUTE_CONTEXT* pContext, 190 __in BURN_EXECUTE_CONTEXT* pContext,
192 __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary, 191 __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary,
193 __inout BURN_EXECUTE_ACTION_CHECKPOINT** ppCheckpoint, 192 __inout BURN_EXECUTE_ACTION_CHECKPOINT** ppCheckpoint,
@@ -284,7 +283,7 @@ static HRESULT ReportOverallProgressTicks(
284 __in BURN_USER_EXPERIENCE* pUX, 283 __in BURN_USER_EXPERIENCE* pUX,
285 __in BOOL fRollback, 284 __in BOOL fRollback,
286 __in DWORD cOverallProgressTicksTotal, 285 __in DWORD cOverallProgressTicksTotal,
287 __in DWORD cOverallProgressTicks 286 __in BURN_APPLY_CONTEXT* pApplyContext
288 ); 287 );
289static HRESULT ExecutePackageComplete( 288static HRESULT ExecutePackageComplete(
290 __in BURN_USER_EXPERIENCE* pUX, 289 __in BURN_USER_EXPERIENCE* pUX,
@@ -499,8 +498,7 @@ extern "C" HRESULT ApplyCache(
499 __in BURN_VARIABLES* pVariables, 498 __in BURN_VARIABLES* pVariables,
500 __in BURN_PLAN* pPlan, 499 __in BURN_PLAN* pPlan,
501 __in HANDLE hPipe, 500 __in HANDLE hPipe,
502 __inout DWORD* pcOverallProgressTicks, 501 __in BURN_APPLY_CONTEXT* pContext
503 __inout BOOL* pfRollback
504 ) 502 )
505{ 503{
506 HRESULT hr = S_OK; 504 HRESULT hr = S_OK;
@@ -508,8 +506,6 @@ extern "C" HRESULT ApplyCache(
508 BURN_CACHE_CONTEXT cacheContext = { }; 506 BURN_CACHE_CONTEXT cacheContext = { };
509 BURN_PACKAGE* pPackage = NULL; 507 BURN_PACKAGE* pPackage = NULL;
510 508
511 *pfRollback = FALSE;
512
513 hr = UserExperienceOnCacheBegin(pUX); 509 hr = UserExperienceOnCacheBegin(pUX);
514 ExitOnRootFailure(hr, "BA aborted cache."); 510 ExitOnRootFailure(hr, "BA aborted cache.");
515 511
@@ -539,9 +535,7 @@ extern "C" HRESULT ApplyCache(
539 hr = ApplyLayoutBundle(&cacheContext, pCacheAction->bundleLayout.pPayloadGroup, pCacheAction->bundleLayout.sczExecutableName, pCacheAction->bundleLayout.sczUnverifiedPath, pCacheAction->bundleLayout.qwBundleSize); 535 hr = ApplyLayoutBundle(&cacheContext, pCacheAction->bundleLayout.pPayloadGroup, pCacheAction->bundleLayout.sczExecutableName, pCacheAction->bundleLayout.sczUnverifiedPath, pCacheAction->bundleLayout.qwBundleSize);
540 ExitOnFailure(hr, "Failed cache action: %ls", L"layout bundle"); 536 ExitOnFailure(hr, "Failed cache action: %ls", L"layout bundle");
541 537
542 ++(*pcOverallProgressTicks); 538 hr = ReportOverallProgressTicks(pUX, FALSE, pPlan->cOverallProgressTicksTotal, pContext);
543
544 hr = ReportOverallProgressTicks(pUX, FALSE, pPlan->cOverallProgressTicksTotal, *pcOverallProgressTicks);
545 LogExitOnFailure(hr, MSG_USER_CANCELED, "Cancel during cache: %ls", L"layout bundle"); 539 LogExitOnFailure(hr, MSG_USER_CANCELED, "Cancel during cache: %ls", L"layout bundle");
546 540
547 break; 541 break;
@@ -567,9 +561,7 @@ extern "C" HRESULT ApplyCache(
567 hr = ApplyCachePackage(&cacheContext, pPackage); 561 hr = ApplyCachePackage(&cacheContext, pPackage);
568 ExitOnFailure(hr, "Failed cache action: %ls", L"cache package"); 562 ExitOnFailure(hr, "Failed cache action: %ls", L"cache package");
569 563
570 ++(*pcOverallProgressTicks); 564 hr = ReportOverallProgressTicks(pUX, FALSE, pPlan->cOverallProgressTicksTotal, pContext);
571
572 hr = ReportOverallProgressTicks(pUX, FALSE, pPlan->cOverallProgressTicksTotal, *pcOverallProgressTicks);
573 LogExitOnFailure(hr, MSG_USER_CANCELED, "Cancel during cache: %ls", L"cache package"); 565 LogExitOnFailure(hr, MSG_USER_CANCELED, "Cancel during cache: %ls", L"cache package");
574 566
575 break; 567 break;
@@ -598,7 +590,7 @@ LExit:
598 if (FAILED(hr)) 590 if (FAILED(hr))
599 { 591 {
600 DoRollbackCache(pUX, pPlan, hPipe, dwCheckpoint); 592 DoRollbackCache(pUX, pPlan, hPipe, dwCheckpoint);
601 *pfRollback = TRUE; 593 pContext->fRollback = TRUE;
602 } 594 }
603 595
604 // Clean up any remanents in the cache. 596 // Clean up any remanents in the cache.
@@ -622,9 +614,7 @@ LExit:
622 614
623extern "C" HRESULT ApplyExecute( 615extern "C" HRESULT ApplyExecute(
624 __in BURN_ENGINE_STATE* pEngineState, 616 __in BURN_ENGINE_STATE* pEngineState,
625 __in_opt HANDLE hCacheThread, 617 __in BURN_APPLY_CONTEXT* pApplyContext,
626 __inout DWORD* pcOverallProgressTicks,
627 __out BOOL* pfRollback,
628 __out BOOL* pfSuspend, 618 __out BOOL* pfSuspend,
629 __out BOOTSTRAPPER_APPLY_RESTART* pRestart 619 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
630 ) 620 )
@@ -637,10 +627,9 @@ extern "C" HRESULT ApplyExecute(
637 BOOL fSeekNextRollbackBoundary = FALSE; 627 BOOL fSeekNextRollbackBoundary = FALSE;
638 628
639 context.pUX = &pEngineState->userExperience; 629 context.pUX = &pEngineState->userExperience;
630 context.pApplyContext = pApplyContext;
640 context.cExecutePackagesTotal = pEngineState->plan.cExecutePackagesTotal; 631 context.cExecutePackagesTotal = pEngineState->plan.cExecutePackagesTotal;
641 context.pcOverallProgressTicks = pcOverallProgressTicks;
642 632
643 *pfRollback = FALSE;
644 *pfSuspend = FALSE; 633 *pfSuspend = FALSE;
645 634
646 // Send execute begin to BA. 635 // Send execute begin to BA.
@@ -670,7 +659,7 @@ extern "C" HRESULT ApplyExecute(
670 } 659 }
671 660
672 // Execute the action. 661 // Execute the action.
673 hr = DoExecuteAction(pEngineState, pExecuteAction, hCacheThread, &context, &pRollbackBoundary, &pCheckpoint, pfSuspend, pRestart); 662 hr = DoExecuteAction(pEngineState, pExecuteAction, &context, &pRollbackBoundary, &pCheckpoint, pfSuspend, pRestart);
674 663
675 if (*pfSuspend || BOOTSTRAPPER_APPLY_RESTART_INITIATED == *pRestart) 664 if (*pfSuspend || BOOTSTRAPPER_APPLY_RESTART_INITIATED == *pRestart)
676 { 665 {
@@ -698,7 +687,7 @@ extern "C" HRESULT ApplyExecute(
698 IgnoreRollbackError(hrRollback, "Failed commit transaction from disable rollback"); 687 IgnoreRollbackError(hrRollback, "Failed commit transaction from disable rollback");
699 } 688 }
700 689
701 *pfRollback = TRUE; 690 pApplyContext->fRollback = TRUE;
702 break; 691 break;
703 } 692 }
704 693
@@ -719,7 +708,7 @@ extern "C" HRESULT ApplyExecute(
719 // If the rollback boundary is vital, end execution here. 708 // If the rollback boundary is vital, end execution here.
720 if (pRollbackBoundary && pRollbackBoundary->fVital) 709 if (pRollbackBoundary && pRollbackBoundary->fVital)
721 { 710 {
722 *pfRollback = TRUE; 711 pApplyContext->fRollback = TRUE;
723 break; 712 break;
724 } 713 }
725 714
@@ -2163,7 +2152,6 @@ static void DoRollbackCache(
2163static HRESULT DoExecuteAction( 2152static HRESULT DoExecuteAction(
2164 __in BURN_ENGINE_STATE* pEngineState, 2153 __in BURN_ENGINE_STATE* pEngineState,
2165 __in BURN_EXECUTE_ACTION* pExecuteAction, 2154 __in BURN_EXECUTE_ACTION* pExecuteAction,
2166 __in_opt HANDLE hCacheThread,
2167 __in BURN_EXECUTE_CONTEXT* pContext, 2155 __in BURN_EXECUTE_CONTEXT* pContext,
2168 __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary, 2156 __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary,
2169 __inout BURN_EXECUTE_ACTION_CHECKPOINT** ppCheckpoint, 2157 __inout BURN_EXECUTE_ACTION_CHECKPOINT** ppCheckpoint,
@@ -2195,14 +2183,14 @@ static HRESULT DoExecuteAction(
2195 case BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT: 2183 case BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT:
2196 // wait for cache sync-point 2184 // wait for cache sync-point
2197 rghWait[0] = pExecuteAction->syncpoint.hEvent; 2185 rghWait[0] = pExecuteAction->syncpoint.hEvent;
2198 rghWait[1] = hCacheThread; 2186 rghWait[1] = pContext->pApplyContext->hCacheThread;
2199 switch (::WaitForMultipleObjects(rghWait[1] ? 2 : 1, rghWait, FALSE, INFINITE)) 2187 switch (::WaitForMultipleObjects(rghWait[1] ? 2 : 1, rghWait, FALSE, INFINITE))
2200 { 2188 {
2201 case WAIT_OBJECT_0: 2189 case WAIT_OBJECT_0:
2202 break; 2190 break;
2203 2191
2204 case WAIT_OBJECT_0 + 1: 2192 case WAIT_OBJECT_0 + 1:
2205 if (!::GetExitCodeThread(hCacheThread, (DWORD*)&hr)) 2193 if (!::GetExitCodeThread(pContext->pApplyContext->hCacheThread, (DWORD*)&hr))
2206 { 2194 {
2207 ExitWithLastError(hr, "Failed to get cache thread exit code."); 2195 ExitWithLastError(hr, "Failed to get cache thread exit code.");
2208 } 2196 }
@@ -2449,9 +2437,8 @@ static HRESULT ExecuteExePackage(
2449 ExitOnRootFailure(hr, "BA aborted EXE progress."); 2437 ExitOnRootFailure(hr, "BA aborted EXE progress.");
2450 2438
2451 pContext->cExecutedPackages += fRollback ? -1 : 1; 2439 pContext->cExecutedPackages += fRollback ? -1 : 1;
2452 (*pContext->pcOverallProgressTicks) += fRollback ? -1 : 1;
2453 2440
2454 hr = ReportOverallProgressTicks(&pEngineState->userExperience, fRollback, pEngineState->plan.cOverallProgressTicksTotal, *pContext->pcOverallProgressTicks); 2441 hr = ReportOverallProgressTicks(&pEngineState->userExperience, fRollback, pEngineState->plan.cOverallProgressTicksTotal, pContext->pApplyContext);
2455 ExitOnRootFailure(hr, "BA aborted EXE package execute progress."); 2442 ExitOnRootFailure(hr, "BA aborted EXE package execute progress.");
2456 2443
2457LExit: 2444LExit:
@@ -2514,9 +2501,8 @@ static HRESULT ExecuteMsiPackage(
2514 } 2501 }
2515 2502
2516 pContext->cExecutedPackages += fRollback ? -1 : 1; 2503 pContext->cExecutedPackages += fRollback ? -1 : 1;
2517 (*pContext->pcOverallProgressTicks) += fRollback ? -1 : 1;
2518 2504
2519 hr = ReportOverallProgressTicks(&pEngineState->userExperience, fRollback, pEngineState->plan.cOverallProgressTicksTotal, *pContext->pcOverallProgressTicks); 2505 hr = ReportOverallProgressTicks(&pEngineState->userExperience, fRollback, pEngineState->plan.cOverallProgressTicksTotal, pContext->pApplyContext);
2520 ExitOnRootFailure(hr, "BA aborted MSI package execute progress."); 2506 ExitOnRootFailure(hr, "BA aborted MSI package execute progress.");
2521 2507
2522LExit: 2508LExit:
@@ -2588,9 +2574,8 @@ static HRESULT ExecuteMspPackage(
2588 } 2574 }
2589 2575
2590 pContext->cExecutedPackages += fRollback ? -1 : 1; 2576 pContext->cExecutedPackages += fRollback ? -1 : 1;
2591 (*pContext->pcOverallProgressTicks) += fRollback ? -1 : 1;
2592 2577
2593 hr = ReportOverallProgressTicks(&pEngineState->userExperience, fRollback, pEngineState->plan.cOverallProgressTicksTotal, *pContext->pcOverallProgressTicks); 2578 hr = ReportOverallProgressTicks(&pEngineState->userExperience, fRollback, pEngineState->plan.cOverallProgressTicksTotal, pContext->pApplyContext);
2594 ExitOnRootFailure(hr, "BA aborted MSP package execute progress."); 2579 ExitOnRootFailure(hr, "BA aborted MSP package execute progress.");
2595 2580
2596LExit: 2581LExit:
@@ -2669,9 +2654,8 @@ static HRESULT ExecuteMsuPackage(
2669 ExitOnRootFailure(hr, "BA aborted MSU progress."); 2654 ExitOnRootFailure(hr, "BA aborted MSU progress.");
2670 2655
2671 pContext->cExecutedPackages += fRollback ? -1 : 1; 2656 pContext->cExecutedPackages += fRollback ? -1 : 1;
2672 (*pContext->pcOverallProgressTicks) += fRollback ? -1 : 1;
2673 2657
2674 hr = ReportOverallProgressTicks(&pEngineState->userExperience, fRollback, pEngineState->plan.cOverallProgressTicksTotal, *pContext->pcOverallProgressTicks); 2658 hr = ReportOverallProgressTicks(&pEngineState->userExperience, fRollback, pEngineState->plan.cOverallProgressTicksTotal, pContext->pApplyContext);
2675 ExitOnRootFailure(hr, "BA aborted MSU package execute progress."); 2659 ExitOnRootFailure(hr, "BA aborted MSU package execute progress.");
2676 2660
2677LExit: 2661LExit:
@@ -3040,15 +3024,23 @@ static HRESULT ReportOverallProgressTicks(
3040 __in BURN_USER_EXPERIENCE* pUX, 3024 __in BURN_USER_EXPERIENCE* pUX,
3041 __in BOOL fRollback, 3025 __in BOOL fRollback,
3042 __in DWORD cOverallProgressTicksTotal, 3026 __in DWORD cOverallProgressTicksTotal,
3043 __in DWORD cOverallProgressTicks 3027 __in BURN_APPLY_CONTEXT* pApplyContext
3044 ) 3028 )
3045{ 3029{
3046 HRESULT hr = S_OK; 3030 HRESULT hr = S_OK;
3047 DWORD dwProgress = cOverallProgressTicksTotal ? (cOverallProgressTicks * 100 / cOverallProgressTicksTotal) : 0; 3031 DWORD dwProgress = 0;
3032
3033 ::EnterCriticalSection(&pApplyContext->csApply);
3034
3035 pApplyContext->cOverallProgressTicks += fRollback ? -1 : 1;
3036
3037 dwProgress = cOverallProgressTicksTotal ? (pApplyContext->cOverallProgressTicks * 100 / cOverallProgressTicksTotal) : 0;
3048 3038
3049 // TODO: consider sending different progress numbers in the future. 3039 // TODO: consider sending different progress numbers in the future.
3050 hr = UserExperienceOnProgress(pUX, fRollback, dwProgress, dwProgress); 3040 hr = UserExperienceOnProgress(pUX, fRollback, dwProgress, dwProgress);
3051 3041
3042 ::LeaveCriticalSection(&pApplyContext->csApply);
3043
3052 return hr; 3044 return hr;
3053} 3045}
3054 3046
diff --git a/src/burn/engine/apply.h b/src/burn/engine/apply.h
index 548e147d..39580297 100644
--- a/src/burn/engine/apply.h
+++ b/src/burn/engine/apply.h
@@ -81,14 +81,11 @@ HRESULT ApplyCache(
81 __in BURN_VARIABLES* pVariables, 81 __in BURN_VARIABLES* pVariables,
82 __in BURN_PLAN* pPlan, 82 __in BURN_PLAN* pPlan,
83 __in HANDLE hPipe, 83 __in HANDLE hPipe,
84 __inout DWORD* pcOverallProgressTicks, 84 __in BURN_APPLY_CONTEXT* pContext
85 __inout BOOL* pfRollback
86 ); 85 );
87HRESULT ApplyExecute( 86HRESULT ApplyExecute(
88 __in BURN_ENGINE_STATE* pEngineState, 87 __in BURN_ENGINE_STATE* pEngineState,
89 __in_opt HANDLE hCacheThread, 88 __in BURN_APPLY_CONTEXT* pApplyContext,
90 __inout DWORD* pcOverallProgressTicks,
91 __out BOOL* pfRollback,
92 __out BOOL* pfSuspend, 89 __out BOOL* pfSuspend,
93 __out BOOTSTRAPPER_APPLY_RESTART* pRestart 90 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
94 ); 91 );
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp
index 535043af..02cab7e6 100644
--- a/src/burn/engine/core.cpp
+++ b/src/burn/engine/core.cpp
@@ -8,8 +8,7 @@
8struct BURN_CACHE_THREAD_CONTEXT 8struct BURN_CACHE_THREAD_CONTEXT
9{ 9{
10 BURN_ENGINE_STATE* pEngineState; 10 BURN_ENGINE_STATE* pEngineState;
11 DWORD* pcOverallProgressTicks; 11 BURN_APPLY_CONTEXT* pApplyContext;
12 BOOL* pfRollback;
13}; 12};
14 13
15 14
@@ -606,14 +605,13 @@ extern "C" HRESULT CoreApply(
606{ 605{
607 HRESULT hr = S_OK; 606 HRESULT hr = S_OK;
608 HANDLE hLock = NULL; 607 HANDLE hLock = NULL;
609 DWORD cOverallProgressTicks = 0;
610 HANDLE hCacheThread = NULL;
611 BOOL fApplyInitialize = FALSE; 608 BOOL fApplyInitialize = FALSE;
612 BOOL fElevated = FALSE; 609 BOOL fElevated = FALSE;
613 BOOL fRegistered = FALSE; 610 BOOL fRegistered = FALSE;
614 BOOL fRollback = FALSE;
615 BOOL fSuspend = FALSE; 611 BOOL fSuspend = FALSE;
616 BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE; 612 BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE;
613 BURN_APPLY_CONTEXT applyContext = { };
614 BOOL fDeleteApplyCs = FALSE;
617 BURN_CACHE_THREAD_CONTEXT cacheThreadContext = { }; 615 BURN_CACHE_THREAD_CONTEXT cacheThreadContext = { };
618 DWORD dwPhaseCount = 0; 616 DWORD dwPhaseCount = 0;
619 BOOTSTRAPPER_APPLYCOMPLETE_ACTION applyCompleteAction = BOOTSTRAPPER_APPLYCOMPLETE_ACTION_NONE; 617 BOOTSTRAPPER_APPLYCOMPLETE_ACTION applyCompleteAction = BOOTSTRAPPER_APPLYCOMPLETE_ACTION_NONE;
@@ -675,6 +673,9 @@ extern "C" HRESULT CoreApply(
675 ExitFunction(); 673 ExitFunction();
676 } 674 }
677 675
676 fDeleteApplyCs = TRUE;
677 ::InitializeCriticalSection(&applyContext.csApply);
678
678 // Ensure the engine is cached to the working path. 679 // Ensure the engine is cached to the working path.
679 if (!pEngineState->sczBundleEngineWorkingPath) 680 if (!pEngineState->sczBundleEngineWorkingPath)
680 { 681 {
@@ -707,33 +708,32 @@ extern "C" HRESULT CoreApply(
707 { 708 {
708 // Launch the cache thread. 709 // Launch the cache thread.
709 cacheThreadContext.pEngineState = pEngineState; 710 cacheThreadContext.pEngineState = pEngineState;
710 cacheThreadContext.pcOverallProgressTicks = &cOverallProgressTicks; 711 cacheThreadContext.pApplyContext = &applyContext;
711 cacheThreadContext.pfRollback = &fRollback;
712 712
713 hCacheThread = ::CreateThread(NULL, 0, CacheThreadProc, &cacheThreadContext, 0, NULL); 713 applyContext.hCacheThread = ::CreateThread(NULL, 0, CacheThreadProc, &cacheThreadContext, 0, NULL);
714 ExitOnNullWithLastError(hCacheThread, hr, "Failed to create cache thread."); 714 ExitOnNullWithLastError(applyContext.hCacheThread, hr, "Failed to create cache thread.");
715 715
716 // If we're not caching in parallel, wait for the cache thread to terminate. 716 // If we're not caching in parallel, wait for the cache thread to terminate.
717 if (!pEngineState->fParallelCacheAndExecute) 717 if (!pEngineState->fParallelCacheAndExecute)
718 { 718 {
719 hr = WaitForCacheThread(hCacheThread); 719 hr = WaitForCacheThread(applyContext.hCacheThread);
720 ExitOnFailure(hr, "Failed while caching, aborting execution."); 720 ExitOnFailure(hr, "Failed while caching, aborting execution.");
721 721
722 ReleaseHandle(hCacheThread); 722 ReleaseHandle(applyContext.hCacheThread);
723 } 723 }
724 } 724 }
725 725
726 // Execute. 726 // Execute.
727 if (pEngineState->plan.cExecuteActions) 727 if (pEngineState->plan.cExecuteActions)
728 { 728 {
729 hr = ApplyExecute(pEngineState, hCacheThread, &cOverallProgressTicks, &fRollback, &fSuspend, &restart); 729 hr = ApplyExecute(pEngineState, &applyContext, &fSuspend, &restart);
730 UserExperienceExecutePhaseComplete(&pEngineState->userExperience, hr); // signal that execute completed. 730 UserExperienceExecutePhaseComplete(&pEngineState->userExperience, hr); // signal that execute completed.
731 } 731 }
732 732
733 // Wait for cache thread to terminate, this should return immediately unless we're waiting for layout to complete. 733 // Wait for cache thread to terminate, this should return immediately unless we're waiting for layout to complete.
734 if (hCacheThread) 734 if (applyContext.hCacheThread)
735 { 735 {
736 HRESULT hrCached = WaitForCacheThread(hCacheThread); 736 HRESULT hrCached = WaitForCacheThread(applyContext.hCacheThread);
737 if (SUCCEEDED(hr)) 737 if (SUCCEEDED(hr))
738 { 738 {
739 hr = hrCached; 739 hr = hrCached;
@@ -741,7 +741,7 @@ extern "C" HRESULT CoreApply(
741 } 741 }
742 742
743 // If something went wrong or force restarted, skip cleaning. 743 // If something went wrong or force restarted, skip cleaning.
744 if (FAILED(hr) || fRollback || fSuspend || BOOTSTRAPPER_APPLY_RESTART_INITIATED == restart) 744 if (FAILED(hr) || applyContext.fRollback || fSuspend || BOOTSTRAPPER_APPLY_RESTART_INITIATED == restart)
745 { 745 {
746 ExitFunction(); 746 ExitFunction();
747 } 747 }
@@ -756,7 +756,7 @@ LExit:
756 // Unregister. 756 // Unregister.
757 if (fRegistered) 757 if (fRegistered)
758 { 758 {
759 ApplyUnregister(pEngineState, FAILED(hr) || fRollback, fSuspend, restart); 759 ApplyUnregister(pEngineState, FAILED(hr) || applyContext.fRollback, fSuspend, restart);
760 } 760 }
761 761
762 if (fElevated) 762 if (fElevated)
@@ -777,7 +777,12 @@ LExit:
777 ::CloseHandle(hLock); 777 ::CloseHandle(hLock);
778 } 778 }
779 779
780 ReleaseHandle(hCacheThread); 780 ReleaseHandle(applyContext.hCacheThread);
781
782 if (fDeleteApplyCs)
783 {
784 DeleteCriticalSection(&applyContext.csApply);
785 }
781 786
782 UserExperienceOnApplyComplete(&pEngineState->userExperience, hr, restart, &applyCompleteAction); 787 UserExperienceOnApplyComplete(&pEngineState->userExperience, hr, restart, &applyCompleteAction);
783 if (BOOTSTRAPPER_APPLYCOMPLETE_ACTION_RESTART == applyCompleteAction) 788 if (BOOTSTRAPPER_APPLYCOMPLETE_ACTION_RESTART == applyCompleteAction)
@@ -1712,8 +1717,6 @@ static DWORD WINAPI CacheThreadProc(
1712 HRESULT hr = S_OK; 1717 HRESULT hr = S_OK;
1713 BURN_CACHE_THREAD_CONTEXT* pContext = reinterpret_cast<BURN_CACHE_THREAD_CONTEXT*>(lpThreadParameter); 1718 BURN_CACHE_THREAD_CONTEXT* pContext = reinterpret_cast<BURN_CACHE_THREAD_CONTEXT*>(lpThreadParameter);
1714 BURN_ENGINE_STATE* pEngineState = pContext->pEngineState; 1719 BURN_ENGINE_STATE* pEngineState = pContext->pEngineState;
1715 DWORD* pcOverallProgressTicks = pContext->pcOverallProgressTicks;
1716 BOOL* pfRollback = pContext->pfRollback;
1717 BOOL fComInitialized = FALSE; 1720 BOOL fComInitialized = FALSE;
1718 1721
1719 // initialize COM 1722 // initialize COM
@@ -1722,7 +1725,7 @@ static DWORD WINAPI CacheThreadProc(
1722 fComInitialized = TRUE; 1725 fComInitialized = TRUE;
1723 1726
1724 // cache packages 1727 // cache packages
1725 hr = ApplyCache(pEngineState->section.hSourceEngineFile, &pEngineState->userExperience, &pEngineState->variables, &pEngineState->plan, pEngineState->companionConnection.hCachePipe, pcOverallProgressTicks, pfRollback); 1728 hr = ApplyCache(pEngineState->section.hSourceEngineFile, &pEngineState->userExperience, &pEngineState->variables, &pEngineState->plan, pEngineState->companionConnection.hCachePipe, pContext->pApplyContext);
1726 1729
1727LExit: 1730LExit:
1728 UserExperienceExecutePhaseComplete(&pEngineState->userExperience, hr); // signal that cache completed. 1731 UserExperienceExecutePhaseComplete(&pEngineState->userExperience, hr); // signal that cache completed.
diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h
index e96440bb..9f779366 100644
--- a/src/burn/engine/core.h
+++ b/src/burn/engine/core.h
@@ -134,6 +134,14 @@ typedef struct _BURN_ENGINE_STATE
134 LPWSTR* argv; 134 LPWSTR* argv;
135} BURN_ENGINE_STATE; 135} BURN_ENGINE_STATE;
136 136
137typedef struct _BURN_APPLY_CONTEXT
138{
139 CRITICAL_SECTION csApply;
140 DWORD cOverallProgressTicks;
141 BOOL fRollback;
142 HANDLE hCacheThread;
143} BURN_APPLY_CONTEXT;
144
137 145
138// function declarations 146// function declarations
139 147