From e1f55b0f39a109760ce6983d0b8f6f498ec90f52 Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Tue, 21 May 2019 15:21:15 -0700 Subject: [PATCH] Skip an async callback function when the UpdateBootFlagsAction object is destroyed As the callback to MarkBootSuccessfulAsync, UpdateBootFlagsAction's member function CompleteUpdateBootFlags() can still be called even after the current UpdateBootFlagsAction object get destroyed by the action processor. We want to set a static flag in TerminateProcessing() and check its value before executing the callback function. An alternative way is to save and propagate the TaskId when scheduling the task in MarkBootSuccessfulAsync, and cancel the task in UpdateBootFlagsAction's TerminateProcessing(). Bug: 123720545 Test: No longer hit the CHECK after injecting StopProcessing. Change-Id: I98d2cc7b94d4059fb897b89932969b61936e8c2e --- update_boot_flags_action.cc | 17 ++++++++++++++++- update_boot_flags_action.h | 2 ++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/update_boot_flags_action.cc b/update_boot_flags_action.cc index 97ef7f23a..ee92ae0a0 100644 --- a/update_boot_flags_action.cc +++ b/update_boot_flags_action.cc @@ -50,8 +50,11 @@ void UpdateBootFlagsAction::PerformAction() { } } -void UpdateBootFlagsAction::CompleteUpdateBootFlags(bool successful) { +void UpdateBootFlagsAction::TerminateProcessing() { is_running_ = false; +} + +void UpdateBootFlagsAction::CompleteUpdateBootFlags(bool successful) { if (!successful) { // We ignore the failure for now because if the updating boot flags is flaky // or has a bug in a specific release, then blocking the update can cause @@ -61,6 +64,18 @@ void UpdateBootFlagsAction::CompleteUpdateBootFlags(bool successful) { // TODO(ahassani): Add new error code metric for kUpdateBootFlagsFailed. LOG(ERROR) << "Updating boot flags failed, but ignoring its failure."; } + + // As the callback to MarkBootSuccessfulAsync, this function can still be + // called even after the current UpdateBootFlagsAction object get destroyed by + // the action processor. In this case, check the value of the static variable + // |is_running_| and skip executing the callback function. + if (!is_running_) { + LOG(INFO) << "UpdateBootFlagsAction is no longer running."; + return; + } + + is_running_ = false; + updated_boot_flags_ = true; processor_->ActionComplete(this, ErrorCode::kSuccess); } diff --git a/update_boot_flags_action.h b/update_boot_flags_action.h index afa2c3f12..892aab7b5 100644 --- a/update_boot_flags_action.h +++ b/update_boot_flags_action.h @@ -30,6 +30,8 @@ class UpdateBootFlagsAction : public AbstractAction { void PerformAction() override; + void TerminateProcessing() override; + static std::string StaticType() { return "UpdateBootFlagsAction"; } std::string Type() const override { return StaticType(); }