AU: Catch terminate signals and block exit if necessary.
Adds a global Terminator class to manage signals and exit blocking.
BUG=7392
TEST=unit tests, gmerged on device, initctl stop update-engine
Change-Id: I2291d4eb55240a6662b18ff834af161d957bce2f
Review URL: http://codereview.chromium.org/3608015
diff --git a/delta_performer.cc b/delta_performer.cc
index f807665..10031eb 100644
--- a/delta_performer.cc
+++ b/delta_performer.cc
@@ -23,6 +23,7 @@
#include "update_engine/payload_signer.h"
#include "update_engine/prefs_interface.h"
#include "update_engine/subprocess.h"
+#include "update_engine/terminator.h"
using std::min;
using std::string;
@@ -209,6 +210,8 @@
next_operation_num_ - manifest_.install_operations_size());
if (!CanPerformInstallOperation(op))
break;
+ ScopedTerminatorExitUnblocker exit_unblocker =
+ ScopedTerminatorExitUnblocker(); // Avoids a compiler unused var bug.
// Log every thousandth operation, and also the first and last ones
if ((next_operation_num_ % 1000 == 0) ||
(next_operation_num_ + 1 == total_operations)) {
@@ -221,6 +224,7 @@
// that if the operation gets interrupted, we don't try to resume the
// update.
if (!IsIdempotentOperation(op)) {
+ Terminator::set_exit_blocked(true);
ResetUpdateProgress(prefs_);
}
if (op.type() == DeltaArchiveManifest_InstallOperation_Type_REPLACE ||
@@ -574,9 +578,10 @@
}
bool DeltaPerformer::CheckpointUpdateProgress() {
- // First reset the progress in case we die in the middle of the state update.
- ResetUpdateProgress(prefs_);
+ Terminator::set_exit_blocked(true);
if (last_updated_buffer_offset_ != buffer_offset_) {
+ // Resets the progress in case we die in the middle of the state update.
+ ResetUpdateProgress(prefs_);
TEST_AND_RETURN_FALSE(
prefs_->SetString(kPrefsUpdateStateSHA256Context,
hash_calculator_.GetContext()));