AU: block exit / reset update progress for non-idempotent ops as late as possible.
BUG=2390
TEST=unit tests, gmerged on device
Change-Id: I569dd1c2efc8056bd20b77e10d7ba50ddd2c55e6
Review URL: http://codereview.chromium.org/3603015
diff --git a/delta_performer.cc b/delta_performer.cc
index 8fc479b..3c24d5b 100644
--- a/delta_performer.cc
+++ b/delta_performer.cc
@@ -222,6 +222,7 @@
next_operation_num_ - manifest_.install_operations_size());
if (!CanPerformInstallOperation(op))
break;
+ // Makes sure we unblock exit when this operation completes.
ScopedTerminatorExitUnblocker exit_unblocker =
ScopedTerminatorExitUnblocker(); // Avoids a compiler unused var bug.
// Log every thousandth operation, and also the first and last ones
@@ -232,13 +233,6 @@
}
bool is_kernel_partition =
(next_operation_num_ >= manifest_.install_operations_size());
- // If about to start a non-idempotent operation, clear the update state so
- // that if the operation gets interrupted, we don't try to resume the
- // update.
- if (!IsIdempotentOperation(op)) {
- Terminator::set_exit_blocked(true);
- ResetUpdateProgress(prefs_, true);
- }
if (op.type() == DeltaArchiveManifest_InstallOperation_Type_REPLACE ||
op.type() == DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ) {
if (!PerformReplaceOperation(op, is_kernel_partition)) {
@@ -371,6 +365,14 @@
bytes_read += bytes_read_this_iteration;
}
+ // If this is a non-idempotent operation, request a delayed exit and clear the
+ // update state in case the operation gets interrupted. Do this as late as
+ // possible.
+ if (!IsIdempotentOperation(operation)) {
+ Terminator::set_exit_blocked(true);
+ ResetUpdateProgress(prefs_, true);
+ }
+
// Write bytes out.
ssize_t bytes_written = 0;
for (int i = 0; i < operation.dst_extents_size(); i++) {
@@ -446,6 +448,14 @@
int fd = is_kernel_partition ? kernel_fd_ : fd_;
const string& path = is_kernel_partition ? kernel_path_ : path_;
+ // If this is a non-idempotent operation, request a delayed exit and clear the
+ // update state in case the operation gets interrupted. Do this as late as
+ // possible.
+ if (!IsIdempotentOperation(operation)) {
+ Terminator::set_exit_blocked(true);
+ ResetUpdateProgress(prefs_, true);
+ }
+
vector<string> cmd;
cmd.push_back(kBspatchPath);
cmd.push_back(path);