summaryrefslogtreecommitdiff
path: root/src/burn/engine/apply.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/burn/engine/apply.cpp')
-rw-r--r--src/burn/engine/apply.cpp99
1 files changed, 58 insertions, 41 deletions
diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp
index 4d527409..aad9e6eb 100644
--- a/src/burn/engine/apply.cpp
+++ b/src/burn/engine/apply.cpp
@@ -335,6 +335,7 @@ extern "C" void ApplyReset(
335 { 335 {
336 BURN_PACKAGE* pPackage = pPackages->rgPackages + i; 336 BURN_PACKAGE* pPackage = pPackages->rgPackages + i;
337 pPackage->hrCacheResult = S_OK; 337 pPackage->hrCacheResult = S_OK;
338 pPackage->fReachedExecution = FALSE;
338 pPackage->transactionRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; 339 pPackage->transactionRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
339 } 340 }
340} 341}
@@ -433,7 +434,7 @@ LExit:
433 434
434extern "C" HRESULT ApplyUnregister( 435extern "C" HRESULT ApplyUnregister(
435 __in BURN_ENGINE_STATE* pEngineState, 436 __in BURN_ENGINE_STATE* pEngineState,
436 __in BOOL fFailedOrRollback, 437 __in BOOL fFailed,
437 __in BOOL fSuspend, 438 __in BOOL fSuspend,
438 __in BOOTSTRAPPER_APPLY_RESTART restart 439 __in BOOTSTRAPPER_APPLY_RESTART restart
439 ) 440 )
@@ -466,7 +467,7 @@ extern "C" HRESULT ApplyUnregister(
466 467
467 // If apply failed in any way and we're going to be keeping the bundle registered then 468 // If apply failed in any way and we're going to be keeping the bundle registered then
468 // execute any rollback dependency registration actions. 469 // execute any rollback dependency registration actions.
469 if (fFailedOrRollback && fKeepRegistration) 470 if (fFailed && fKeepRegistration)
470 { 471 {
471 // Execute any rollback registration actions. 472 // Execute any rollback registration actions.
472 HRESULT hrRegistrationRollback = ExecuteDependentRegistrationActions(pEngineState->companionConnection.hPipe, &pEngineState->registration, pEngineState->plan.rgRollbackRegistrationActions, pEngineState->plan.cRollbackRegistrationActions); 473 HRESULT hrRegistrationRollback = ExecuteDependentRegistrationActions(pEngineState->companionConnection.hPipe, &pEngineState->registration, pEngineState->plan.rgRollbackRegistrationActions, pEngineState->plan.cRollbackRegistrationActions);
@@ -587,11 +588,7 @@ extern "C" HRESULT ApplyCache(
587 } 588 }
588 589
589LExit: 590LExit:
590 if (FAILED(hr)) 591 pContext->dwCacheCheckpoint = dwCheckpoint;
591 {
592 DoRollbackCache(pUX, pPlan, hPipe, dwCheckpoint);
593 pContext->fRollback = TRUE;
594 }
595 592
596 // Clean up any remanents in the cache. 593 // Clean up any remanents in the cache.
597 if (INVALID_HANDLE_VALUE != hPipe) 594 if (INVALID_HANDLE_VALUE != hPipe)
@@ -612,6 +609,16 @@ LExit:
612 return hr; 609 return hr;
613} 610}
614 611
612extern "C" void ApplyCacheRollback(
613 __in BURN_USER_EXPERIENCE* pUX,
614 __in BURN_PLAN* pPlan,
615 __in HANDLE hPipe,
616 __in BURN_APPLY_CONTEXT* pContext
617 )
618{
619 DoRollbackCache(pUX, pPlan, hPipe, pContext->dwCacheCheckpoint);
620}
621
615extern "C" HRESULT ApplyExecute( 622extern "C" HRESULT ApplyExecute(
616 __in BURN_ENGINE_STATE* pEngineState, 623 __in BURN_ENGINE_STATE* pEngineState,
617 __in BURN_APPLY_CONTEXT* pApplyContext, 624 __in BURN_APPLY_CONTEXT* pApplyContext,
@@ -687,7 +694,6 @@ extern "C" HRESULT ApplyExecute(
687 IgnoreRollbackError(hrRollback, "Failed commit transaction from disable rollback"); 694 IgnoreRollbackError(hrRollback, "Failed commit transaction from disable rollback");
688 } 695 }
689 696
690 pApplyContext->fRollback = TRUE;
691 break; 697 break;
692 } 698 }
693 699
@@ -708,7 +714,6 @@ extern "C" HRESULT ApplyExecute(
708 // If the rollback boundary is vital, end execution here. 714 // If the rollback boundary is vital, end execution here.
709 if (pRollbackBoundary && pRollbackBoundary->fVital) 715 if (pRollbackBoundary && pRollbackBoundary->fVital)
710 { 716 {
711 pApplyContext->fRollback = TRUE;
712 break; 717 break;
713 } 718 }
714 719
@@ -2110,41 +2115,44 @@ static void DoRollbackCache(
2110 ) 2115 )
2111{ 2116{
2112 HRESULT hr = S_OK; 2117 HRESULT hr = S_OK;
2113 DWORD iCheckpoint = 0; 2118 BURN_PACKAGE* pPackage = NULL;
2119 DWORD dwLastCheckpoint = 0;
2114 2120
2115 // Scan to last checkpoint. 2121 // Rollback cache actions.
2116 for (DWORD i = 0; i < pPlan->cRollbackCacheActions; ++i) 2122 for (DWORD i = pPlan->cRollbackCacheActions; i > 0; --i)
2117 { 2123 {
2118 BURN_CACHE_ACTION* pRollbackCacheAction = &pPlan->rgRollbackCacheActions[i]; 2124 BURN_CACHE_ACTION* pRollbackCacheAction = &pPlan->rgRollbackCacheActions[i - 1];
2119 2125
2120 if (BURN_CACHE_ACTION_TYPE_CHECKPOINT == pRollbackCacheAction->type && pRollbackCacheAction->checkpoint.dwId == dwCheckpoint) 2126 switch (pRollbackCacheAction->type)
2121 { 2127 {
2122 iCheckpoint = i; 2128 case BURN_CACHE_ACTION_TYPE_CHECKPOINT:
2129 dwLastCheckpoint = pRollbackCacheAction->checkpoint.dwId;
2123 break; 2130 break;
2124 }
2125 }
2126 2131
2127 // Rollback cache actions. 2132 case BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE:
2128 if (iCheckpoint) 2133 pPackage = pRollbackCacheAction->rollbackPackage.pPackage;
2129 {
2130 // i has to be a signed integer so it doesn't get decremented to 0xFFFFFFFF.
2131 for (int i = iCheckpoint - 1; i >= 0; --i)
2132 {
2133 BURN_CACHE_ACTION* pRollbackCacheAction = &pPlan->rgRollbackCacheActions[i];
2134 2134
2135 switch (pRollbackCacheAction->type) 2135 // If the package was executed then it's up to ApplyExecute to rollback its cache.
2136 if (!pPackage->fReachedExecution)
2136 { 2137 {
2137 case BURN_CACHE_ACTION_TYPE_CHECKPOINT: 2138 if (!pPackage->fCached) // only rollback when it wasn't already cached.
2138 break; 2139 {
2139 2140 if (dwLastCheckpoint <= dwCheckpoint) // only rollback when it was attempted to be cached.
2140 case BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE: 2141 {
2141 hr = CleanPackage(hPipe, pRollbackCacheAction->rollbackPackage.pPackage); 2142 hr = CleanPackage(hPipe, pPackage);
2142 break; 2143 }
2143 2144 }
2144 default: 2145 else if (pPackage->fCanAffectRegistration)
2145 AssertSz(FALSE, "Invalid rollback cache action."); 2146 {
2146 break; 2147 // Don't let this already cached package cause the registration to be kept if the bundle failed and wasn't already registered.
2148 pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
2149 }
2147 } 2150 }
2151 break;
2152
2153 default:
2154 AssertSz(FALSE, "Invalid rollback cache action.");
2155 break;
2148 } 2156 }
2149 } 2157 }
2150} 2158}
@@ -2180,9 +2188,11 @@ static HRESULT DoExecuteAction(
2180 *ppCheckpoint = &pExecuteAction->checkpoint; 2188 *ppCheckpoint = &pExecuteAction->checkpoint;
2181 break; 2189 break;
2182 2190
2183 case BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT: 2191 case BURN_EXECUTE_ACTION_TYPE_WAIT_CACHE_PACKAGE:
2192 pExecuteAction->waitCachePackage.pPackage->fReachedExecution = TRUE;
2193
2184 // wait for cache sync-point 2194 // wait for cache sync-point
2185 rghWait[0] = pExecuteAction->syncpoint.hEvent; 2195 rghWait[0] = pExecuteAction->waitCachePackage.pPackage->hCacheEvent;
2186 rghWait[1] = pContext->pApplyContext->hCacheThread; 2196 rghWait[1] = pContext->pApplyContext->hCacheThread;
2187 switch (::WaitForMultipleObjects(rghWait[1] ? 2 : 1, rghWait, FALSE, INFINITE)) 2197 switch (::WaitForMultipleObjects(rghWait[1] ? 2 : 1, rghWait, FALSE, INFINITE))
2188 { 2198 {
@@ -2354,10 +2364,17 @@ static HRESULT DoRollbackActions(
2354 ExitFunction1(hr = S_OK); 2364 ExitFunction1(hr = S_OK);
2355 2365
2356 case BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE: 2366 case BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE:
2357 // TODO: This used to be skipped if the package was already cached. 2367 if (!pRollbackAction->uncachePackage.pPackage->fCached) // only rollback when it wasn't already cached.
2358 // Need to figure out new logic for when (if?) to skip it. 2368 {
2359 hr = CleanPackage(pEngineState->companionConnection.hPipe, pRollbackAction->uncachePackage.pPackage); 2369 hr = CleanPackage(pEngineState->companionConnection.hPipe, pRollbackAction->uncachePackage.pPackage);
2360 IgnoreRollbackError(hr, "Failed to uncache package for rollback."); 2370 IgnoreRollbackError(hr, "Failed to uncache package for rollback.");
2371 }
2372 else if (pRollbackAction->uncachePackage.pPackage->fCanAffectRegistration)
2373 {
2374 // Don't let this already cached package cause the registration to be kept if the bundle failed and wasn't already registered.
2375 pRollbackAction->uncachePackage.pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
2376 }
2377
2361 break; 2378 break;
2362 2379
2363 default: 2380 default: