diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2021-02-03 17:16:21 -0600 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2021-02-04 22:16:10 -0600 |
commit | dc992c49f30e0d2b912a6449a33b4448ef862f31 (patch) | |
tree | c93be4f365aeb0b87b7a361d55bdb34999b3d2d7 | |
parent | c6c17104b50936432a3fe9ca214ba9a3dfa32780 (diff) | |
download | wix-dc992c49f30e0d2b912a6449a33b4448ef862f31.tar.gz wix-dc992c49f30e0d2b912a6449a33b4448ef862f31.tar.bz2 wix-dc992c49f30e0d2b912a6449a33b4448ef862f31.zip |
Change the implementation of Cache="always" to request the CACHE state.
This makes it possible for the prereq BA to not cache those packages while installing the prereqs, which allows the engine to automatically cleanup if necessary.
#6297 for this commit and the previous 6.
-rw-r--r-- | src/engine/plan.cpp | 96 | ||||
-rw-r--r-- | src/engine/plan.h | 9 | ||||
-rw-r--r-- | src/test/BurnUnitTest/PlanTest.cpp | 2 |
3 files changed, 30 insertions, 77 deletions
diff --git a/src/engine/plan.cpp b/src/engine/plan.cpp index 1aaec252..a11d0e78 100644 --- a/src/engine/plan.cpp +++ b/src/engine/plan.cpp | |||
@@ -153,7 +153,6 @@ static HRESULT CalculateExecuteActions( | |||
153 | __out_opt BOOL* pfBARequestedCache | 153 | __out_opt BOOL* pfBARequestedCache |
154 | ); | 154 | ); |
155 | static BOOL NeedsCache( | 155 | static BOOL NeedsCache( |
156 | __in BURN_PLAN* pPlan, | ||
157 | __in BURN_PACKAGE* pPackage | 156 | __in BURN_PACKAGE* pPackage |
158 | ); | 157 | ); |
159 | static HRESULT CreateContainerProgress( | 158 | static HRESULT CreateContainerProgress( |
@@ -323,6 +322,7 @@ extern "C" HRESULT PlanDefaultPackageRequestState( | |||
323 | __in BURN_PACKAGE_TYPE packageType, | 322 | __in BURN_PACKAGE_TYPE packageType, |
324 | __in BOOTSTRAPPER_PACKAGE_STATE currentState, | 323 | __in BOOTSTRAPPER_PACKAGE_STATE currentState, |
325 | __in BOOL fPermanent, | 324 | __in BOOL fPermanent, |
325 | __in BURN_CACHE_TYPE cacheType, | ||
326 | __in BOOTSTRAPPER_ACTION action, | 326 | __in BOOTSTRAPPER_ACTION action, |
327 | __in BURN_VARIABLES* pVariables, | 327 | __in BURN_VARIABLES* pVariables, |
328 | __in_z_opt LPCWSTR wzInstallCondition, | 328 | __in_z_opt LPCWSTR wzInstallCondition, |
@@ -333,12 +333,19 @@ extern "C" HRESULT PlanDefaultPackageRequestState( | |||
333 | HRESULT hr = S_OK; | 333 | HRESULT hr = S_OK; |
334 | BOOTSTRAPPER_REQUEST_STATE defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; | 334 | BOOTSTRAPPER_REQUEST_STATE defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; |
335 | BOOL fCondition = FALSE; | 335 | BOOL fCondition = FALSE; |
336 | BOOL fFallbackToCache = BURN_CACHE_TYPE_ALWAYS == cacheType && BOOTSTRAPPER_ACTION_UNINSTALL != action && BOOTSTRAPPER_PACKAGE_STATE_CACHED > currentState; | ||
336 | 337 | ||
337 | // If doing layout, then always default to requesting the file be cached. | 338 | // If doing layout, then always default to requesting the file be cached. |
338 | if (BOOTSTRAPPER_ACTION_LAYOUT == action) | 339 | if (BOOTSTRAPPER_ACTION_LAYOUT == action) |
339 | { | 340 | { |
340 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; | 341 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; |
341 | } | 342 | } |
343 | else if (BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED == currentState && BOOTSTRAPPER_ACTION_UNINSTALL != action) | ||
344 | { | ||
345 | // Superseded means the package is on the machine but not active, so only uninstall operations are allowed. | ||
346 | // Requesting present makes sure always-cached packages are cached. | ||
347 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; | ||
348 | } | ||
342 | else if (BOOTSTRAPPER_RELATION_PATCH == relationType && BURN_PACKAGE_TYPE_MSP == packageType) | 349 | else if (BOOTSTRAPPER_RELATION_PATCH == relationType && BURN_PACKAGE_TYPE_MSP == packageType) |
343 | { | 350 | { |
344 | // For patch related bundles, only install a patch if currently absent during install, modify, or repair. | 351 | // For patch related bundles, only install a patch if currently absent during install, modify, or repair. |
@@ -346,22 +353,20 @@ extern "C" HRESULT PlanDefaultPackageRequestState( | |||
346 | { | 353 | { |
347 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; | 354 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; |
348 | } | 355 | } |
356 | else if (fFallbackToCache) | ||
357 | { | ||
358 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; | ||
359 | } | ||
349 | else | 360 | else |
350 | { | 361 | { |
351 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; | 362 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; |
352 | } | 363 | } |
353 | } | 364 | } |
354 | else if (BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED == currentState && BOOTSTRAPPER_ACTION_UNINSTALL != action) | ||
355 | { | ||
356 | // Superseded means the package is on the machine but not active, so only uninstall operations are allowed. | ||
357 | // All other operations do nothing. | ||
358 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
359 | } | ||
360 | else if (BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE == currentState && !(BOOTSTRAPPER_ACTION_UNINSTALL == action && BURN_PACKAGE_TYPE_MSP == packageType)) | 365 | else if (BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE == currentState && !(BOOTSTRAPPER_ACTION_UNINSTALL == action && BURN_PACKAGE_TYPE_MSP == packageType)) |
361 | { | 366 | { |
362 | // Obsolete means the package is not on the machine and should not be installed, *except* patches can be obsolete | 367 | // Obsolete means the package is not on the machine and should not be installed, *except* patches can be obsolete |
363 | // and present so allow them to be removed during uninstall. Everyone else, gets nothing. | 368 | // and present so allow them to be removed during uninstall. Everyone else, gets nothing. |
364 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; | 369 | *pRequestState = fFallbackToCache ? BOOTSTRAPPER_REQUEST_STATE_CACHE : BOOTSTRAPPER_REQUEST_STATE_NONE; |
365 | } | 370 | } |
366 | else // pick the best option for the action state and install condition. | 371 | else // pick the best option for the action state and install condition. |
367 | { | 372 | { |
@@ -381,6 +386,11 @@ extern "C" HRESULT PlanDefaultPackageRequestState( | |||
381 | { | 386 | { |
382 | *pRequestState = defaultRequestState; | 387 | *pRequestState = defaultRequestState; |
383 | } | 388 | } |
389 | |||
390 | if (fFallbackToCache && BOOTSTRAPPER_REQUEST_STATE_CACHE > *pRequestState) | ||
391 | { | ||
392 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; | ||
393 | } | ||
384 | } | 394 | } |
385 | 395 | ||
386 | LExit: | 396 | LExit: |
@@ -816,7 +826,7 @@ static HRESULT ProcessPackage( | |||
816 | BOOL fPlanPackageBegan = FALSE; | 826 | BOOL fPlanPackageBegan = FALSE; |
817 | 827 | ||
818 | // Remember the default requested state so the engine doesn't get blamed for planning the wrong thing if the BA changes it. | 828 | // Remember the default requested state so the engine doesn't get blamed for planning the wrong thing if the BA changes it. |
819 | hr = PlanDefaultPackageRequestState(pPackage->type, pPackage->currentState, !pPackage->fUninstallable, pPlan->action, pVariables, pPackage->sczInstallCondition, relationType, &pPackage->defaultRequested); | 829 | hr = PlanDefaultPackageRequestState(pPackage->type, pPackage->currentState, !pPackage->fUninstallable, pPackage->cacheType, pPlan->action, pVariables, pPackage->sczInstallCondition, relationType, &pPackage->defaultRequested); |
820 | ExitOnFailure(hr, "Failed to set default package state."); | 830 | ExitOnFailure(hr, "Failed to set default package state."); |
821 | 831 | ||
822 | pPackage->requested = pPackage->defaultRequested; | 832 | pPackage->requested = pPackage->defaultRequested; |
@@ -863,18 +873,9 @@ static HRESULT ProcessPackage( | |||
863 | } | 873 | } |
864 | else if (BOOTSTRAPPER_ACTION_LAYOUT != pPlan->action) | 874 | else if (BOOTSTRAPPER_ACTION_LAYOUT != pPlan->action) |
865 | { | 875 | { |
866 | // All packages that have cacheType set to always should be cached if the bundle is going to be present. | 876 | // Make sure the package is properly ref-counted even if no plan is requested. |
867 | if (BURN_CACHE_TYPE_ALWAYS == pPackage->cacheType && BOOTSTRAPPER_ACTION_INSTALL <= pPlan->action) | 877 | hr = PlanDependencyActions(fBundlePerMachine, pPlan, pPackage); |
868 | { | 878 | ExitOnFailure(hr, "Failed to plan dependency actions for package: %ls", pPackage->sczId); |
869 | hr = PlanCachePackage(fBundlePerMachine, pUX, pPlan, pPackage, pVariables, phSyncpointEvent); | ||
870 | ExitOnFailure(hr, "Failed to plan cache package."); | ||
871 | } | ||
872 | else | ||
873 | { | ||
874 | // Make sure the package is properly ref-counted even if no plan is requested. | ||
875 | hr = PlanDependencyActions(fBundlePerMachine, pPlan, pPackage); | ||
876 | ExitOnFailure(hr, "Failed to plan dependency actions for package: %ls", pPackage->sczId); | ||
877 | } | ||
878 | } | 879 | } |
879 | 880 | ||
880 | if (pPackage->fCanAffectRegistration) | 881 | if (pPackage->fCanAffectRegistration) |
@@ -1008,41 +1009,6 @@ LExit: | |||
1008 | return hr; | 1009 | return hr; |
1009 | } | 1010 | } |
1010 | 1011 | ||
1011 | extern "C" HRESULT PlanCachePackage( | ||
1012 | __in BOOL fPerMachine, | ||
1013 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
1014 | __in BURN_PLAN* pPlan, | ||
1015 | __in BURN_PACKAGE* pPackage, | ||
1016 | __in BURN_VARIABLES* pVariables, | ||
1017 | __out HANDLE* phSyncpointEvent | ||
1018 | ) | ||
1019 | { | ||
1020 | HRESULT hr = S_OK; | ||
1021 | BOOL fBARequestedCache = FALSE; | ||
1022 | |||
1023 | // Calculate the execute actions because we need them to decide whether the package should be cached. | ||
1024 | hr = CalculateExecuteActions(pUserExperience, pPackage, pVariables, pPlan->pActiveRollbackBoundary, &fBARequestedCache); | ||
1025 | ExitOnFailure(hr, "Failed to calculate execute actions for package: %ls", pPackage->sczId); | ||
1026 | |||
1027 | if (fBARequestedCache || NeedsCache(pPlan, pPackage)) | ||
1028 | { | ||
1029 | hr = AddCachePackage(pPlan, pPackage, phSyncpointEvent); | ||
1030 | ExitOnFailure(hr, "Failed to plan cache package."); | ||
1031 | |||
1032 | if (pPackage->fPerMachine) | ||
1033 | { | ||
1034 | pPlan->fPerMachine = TRUE; | ||
1035 | } | ||
1036 | } | ||
1037 | |||
1038 | // Make sure the package is properly ref-counted. | ||
1039 | hr = PlanDependencyActions(fPerMachine, pPlan, pPackage); | ||
1040 | ExitOnFailure(hr, "Failed to plan dependency actions for package: %ls", pPackage->sczId); | ||
1041 | |||
1042 | LExit: | ||
1043 | return hr; | ||
1044 | } | ||
1045 | |||
1046 | extern "C" HRESULT PlanExecutePackage( | 1012 | extern "C" HRESULT PlanExecutePackage( |
1047 | __in BOOL fPerMachine, | 1013 | __in BOOL fPerMachine, |
1048 | __in BOOTSTRAPPER_DISPLAY display, | 1014 | __in BOOTSTRAPPER_DISPLAY display, |
@@ -1064,7 +1030,7 @@ extern "C" HRESULT PlanExecutePackage( | |||
1064 | hr = DependencyPlanPackageBegin(fPerMachine, pPackage, pPlan); | 1030 | hr = DependencyPlanPackageBegin(fPerMachine, pPackage, pPlan); |
1065 | ExitOnFailure(hr, "Failed to begin plan dependency actions for package: %ls", pPackage->sczId); | 1031 | ExitOnFailure(hr, "Failed to begin plan dependency actions for package: %ls", pPackage->sczId); |
1066 | 1032 | ||
1067 | if (fBARequestedCache || NeedsCache(pPlan, pPackage)) | 1033 | if (fBARequestedCache || NeedsCache(pPackage)) |
1068 | { | 1034 | { |
1069 | hr = AddCachePackage(pPlan, pPackage, phSyncpointEvent); | 1035 | hr = AddCachePackage(pPlan, pPackage, phSyncpointEvent); |
1070 | ExitOnFailure(hr, "Failed to plan cache package."); | 1036 | ExitOnFailure(hr, "Failed to plan cache package."); |
@@ -1079,12 +1045,12 @@ extern "C" HRESULT PlanExecutePackage( | |||
1079 | 1045 | ||
1080 | // Add the cache and install size to estimated size if it will be on the machine at the end of the install | 1046 | // Add the cache and install size to estimated size if it will be on the machine at the end of the install |
1081 | if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested || | 1047 | if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested || |
1082 | (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == pPackage->currentState && BOOTSTRAPPER_REQUEST_STATE_ABSENT < pPackage->requested) || | 1048 | BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested || |
1083 | BURN_CACHE_TYPE_ALWAYS == pPackage->cacheType | 1049 | (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == pPackage->currentState && BOOTSTRAPPER_REQUEST_STATE_ABSENT < pPackage->requested) |
1084 | ) | 1050 | ) |
1085 | { | 1051 | { |
1086 | // If the package will remain in the cache, add the package size to the estimated size | 1052 | // If the package will remain in the cache, add the package size to the estimated size |
1087 | if (BURN_CACHE_TYPE_YES <= pPackage->cacheType) | 1053 | if (BURN_CACHE_TYPE_NO < pPackage->cacheType) |
1088 | { | 1054 | { |
1089 | pPlan->qwEstimatedSize += pPackage->qwSize; | 1055 | pPlan->qwEstimatedSize += pPackage->qwSize; |
1090 | } | 1056 | } |
@@ -1511,7 +1477,7 @@ extern "C" HRESULT PlanCleanPackage( | |||
1511 | // from the cache. Start by noting that we only clean if the package is being acquired or | 1477 | // from the cache. Start by noting that we only clean if the package is being acquired or |
1512 | // already cached and the package is not supposed to always be cached. | 1478 | // already cached and the package is not supposed to always be cached. |
1513 | if ((pPackage->fAcquire || BURN_CACHE_STATE_PARTIAL == pPackage->cache || BURN_CACHE_STATE_COMPLETE == pPackage->cache) && | 1479 | if ((pPackage->fAcquire || BURN_CACHE_STATE_PARTIAL == pPackage->cache || BURN_CACHE_STATE_COMPLETE == pPackage->cache) && |
1514 | (BURN_CACHE_TYPE_ALWAYS > pPackage->cacheType || BOOTSTRAPPER_ACTION_INSTALL > pPlan->action)) | 1480 | (BURN_CACHE_TYPE_ALWAYS > pPackage->cacheType || BOOTSTRAPPER_ACTION_CACHE > pPlan->action)) |
1515 | { | 1481 | { |
1516 | // The following are all different reasons why the package should be cleaned from the cache. | 1482 | // The following are all different reasons why the package should be cleaned from the cache. |
1517 | // The else-ifs are used to make the conditions easier to see (rather than have them combined | 1483 | // The else-ifs are used to make the conditions easier to see (rather than have them combined |
@@ -2836,16 +2802,10 @@ LExit: | |||
2836 | } | 2802 | } |
2837 | 2803 | ||
2838 | static BOOL NeedsCache( | 2804 | static BOOL NeedsCache( |
2839 | __in BURN_PLAN* pPlan, | ||
2840 | __in BURN_PACKAGE* pPackage | 2805 | __in BURN_PACKAGE* pPackage |
2841 | ) | 2806 | ) |
2842 | { | 2807 | { |
2843 | // All packages that have cacheType set to always should be cached if the bundle is going to be present. | 2808 | if (BURN_PACKAGE_TYPE_EXE == pPackage->type) // Exe packages require the package for all operations (even uninstall). |
2844 | if (BURN_CACHE_TYPE_ALWAYS == pPackage->cacheType && BOOTSTRAPPER_ACTION_INSTALL <= pPlan->action) | ||
2845 | { | ||
2846 | return TRUE; | ||
2847 | } | ||
2848 | else if (BURN_PACKAGE_TYPE_EXE == pPackage->type) // Exe packages require the package for all operations (even uninstall). | ||
2849 | { | 2809 | { |
2850 | return BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute; | 2810 | return BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute; |
2851 | } | 2811 | } |
diff --git a/src/engine/plan.h b/src/engine/plan.h index 6c12b5fa..2f6c9dd3 100644 --- a/src/engine/plan.h +++ b/src/engine/plan.h | |||
@@ -380,6 +380,7 @@ HRESULT PlanDefaultPackageRequestState( | |||
380 | __in BURN_PACKAGE_TYPE packageType, | 380 | __in BURN_PACKAGE_TYPE packageType, |
381 | __in BOOTSTRAPPER_PACKAGE_STATE currentState, | 381 | __in BOOTSTRAPPER_PACKAGE_STATE currentState, |
382 | __in BOOL fPermanent, | 382 | __in BOOL fPermanent, |
383 | __in BURN_CACHE_TYPE cacheType, | ||
383 | __in BOOTSTRAPPER_ACTION action, | 384 | __in BOOTSTRAPPER_ACTION action, |
384 | __in BURN_VARIABLES* pVariables, | 385 | __in BURN_VARIABLES* pVariables, |
385 | __in_z_opt LPCWSTR wzInstallCondition, | 386 | __in_z_opt LPCWSTR wzInstallCondition, |
@@ -439,14 +440,6 @@ HRESULT PlanLayoutPackage( | |||
439 | __in BURN_PACKAGE* pPackage, | 440 | __in BURN_PACKAGE* pPackage, |
440 | __in_z_opt LPCWSTR wzLayoutDirectory | 441 | __in_z_opt LPCWSTR wzLayoutDirectory |
441 | ); | 442 | ); |
442 | HRESULT PlanCachePackage( | ||
443 | __in BOOL fPerMachine, | ||
444 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
445 | __in BURN_PLAN* pPlan, | ||
446 | __in BURN_PACKAGE* pPackage, | ||
447 | __in BURN_VARIABLES* pVariables, | ||
448 | __out HANDLE* phSyncpointEvent | ||
449 | ); | ||
450 | HRESULT PlanExecutePackage( | 443 | HRESULT PlanExecutePackage( |
451 | __in BOOL fPerMachine, | 444 | __in BOOL fPerMachine, |
452 | __in BOOTSTRAPPER_DISPLAY display, | 445 | __in BOOTSTRAPPER_DISPLAY display, |
diff --git a/src/test/BurnUnitTest/PlanTest.cpp b/src/test/BurnUnitTest/PlanTest.cpp index a50c64e1..629c293f 100644 --- a/src/test/BurnUnitTest/PlanTest.cpp +++ b/src/test/BurnUnitTest/PlanTest.cpp | |||
@@ -317,7 +317,7 @@ namespace Bootstrapper | |||
317 | dwIndex = 0; | 317 | dwIndex = 0; |
318 | Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); | 318 | Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); |
319 | 319 | ||
320 | Assert::Equal(0ull, pPlan->qwEstimatedSize); | 320 | Assert::Equal(33743ull, pPlan->qwEstimatedSize); |
321 | Assert::Equal(33743ull, pPlan->qwCacheSizeTotal); | 321 | Assert::Equal(33743ull, pPlan->qwCacheSizeTotal); |
322 | 322 | ||
323 | fRollback = FALSE; | 323 | fRollback = FALSE; |