[Merge M70] chaps: Fix crash in ~SystemShutdownBlocker
Fix crash caused by iterating and erasing over |blocked_slots_| in
~SystemShutdownBlocker.
BUG=chromium:902177
TEST=none
Change-Id: Ia4e7b77596e66a75991e544f1ca9dfcfa09d0227
Reviewed-on: https://chromium-review.googlesource.com/1319094
Commit-Ready: Maksim Ivanov <emaxx@chromium.org>
Tested-by: Alexander Hendrich <hendrich@chromium.org>
Reviewed-by: Maksim Ivanov <emaxx@chromium.org>
Reviewed-by: Andrey Pronin <apronin@chromium.org>
(cherry picked from commit 586c307cf05f0085abfe1bbeed8ba12c5b9c73e2)
Reviewed-on: https://chromium-review.googlesource.com/c/1325842
Commit-Queue: Alexander Hendrich <hendrich@chromium.org>
Reviewed-by: Pavol Marko <pmarko@chromium.org>
diff --git a/chaps/system_shutdown_blocker.cc b/chaps/system_shutdown_blocker.cc
index 3a2f819..23e6891 100644
--- a/chaps/system_shutdown_blocker.cc
+++ b/chaps/system_shutdown_blocker.cc
@@ -21,6 +21,7 @@
SystemShutdownBlocker::~SystemShutdownBlocker() {
for (int slot_id : blocked_slots_)
PerformUnblock(slot_id);
+ blocked_slots_.clear();
}
void SystemShutdownBlocker::Block(int slot_id,
@@ -32,18 +33,20 @@
origin_thread_task_runner_->PostTask(FROM_HERE, perform_block_task);
// Post delayed unblock task (fallback).
- auto perform_unblock_task = base::Bind(&SystemShutdownBlocker::PerformUnblock,
- base::Unretained(this),
- slot_id);
+ auto perform_unblock_task =
+ base::Bind(&SystemShutdownBlocker::PerformUnblockIfBlocked,
+ base::Unretained(this),
+ slot_id);
origin_thread_task_runner_->PostDelayedTask(FROM_HERE, perform_unblock_task,
fallback_timeout);
}
void SystemShutdownBlocker::Unblock(int slot_id) {
// Post unblock task.
- auto perform_unblock_task = base::Bind(&SystemShutdownBlocker::PerformUnblock,
- base::Unretained(this),
- slot_id);
+ auto perform_unblock_task =
+ base::Bind(&SystemShutdownBlocker::PerformUnblockIfBlocked,
+ base::Unretained(this),
+ slot_id);
origin_thread_task_runner_->PostTask(FROM_HERE, perform_unblock_task);
}
@@ -74,22 +77,24 @@
LOG(INFO) << "Created lock file: " << lock_path.value();
}
-void SystemShutdownBlocker::PerformUnblock(int slot_id) {
- if (blocked_slots_.find(slot_id) == blocked_slots_.end())
- return;
+void SystemShutdownBlocker::PerformUnblockIfBlocked(int slot_id) {
+ if (blocked_slots_.count(slot_id) && PerformUnblock(slot_id))
+ blocked_slots_.erase(slot_id);
+}
+bool SystemShutdownBlocker::PerformUnblock(int slot_id) {
const base::FilePath lock_path = GetPowerdLockFilePath(slot_id);
if (!base::PathExists(lock_path)) {
LOG(WARNING) << "Couldn't delete lock file (not existant): "
<< lock_path.value();
- return;
+ return true;
}
if (!base::DeleteFile(lock_path, false /* recursive */)) {
PLOG(ERROR) << "Couldn't delete lock file: " << lock_path.value();
- return;
+ return false;
}
- blocked_slots_.erase(slot_id);
LOG(INFO) << "Deleted lock file: " << lock_path.value();
+ return true;
}
base::FilePath SystemShutdownBlocker::GetPowerdLockFilePath(int slot_id) const {
diff --git a/chaps/system_shutdown_blocker.h b/chaps/system_shutdown_blocker.h
index e3b5173..df2171b 100644
--- a/chaps/system_shutdown_blocker.h
+++ b/chaps/system_shutdown_blocker.h
@@ -33,15 +33,19 @@
// |origin_thread_task_runner_|.
void Unblock(int slot_id);
+ private:
// Creates a lock file readable by powerd with chapsd's PID and marks the slot
// as blocked in |blocked_slots|.
void PerformBlock(int slot_id);
- // Deletes the lock file if the slot is marked as blocked in |blocked_slots_|,
- // otherwise no-op.
- void PerformUnblock(int slot_id);
+ // Calls |PerformUnblock()| and removes the block mark if the slot is marked
+ // as blocked in |blocked_slots_|, otherwise no-op.
+ void PerformUnblockIfBlocked(int slot_id);
- private:
+ // Deletes the lock file and returns whether or not the slot is unblocked
+ // (i.e. lock file removed).
+ bool PerformUnblock(int slot_id);
+
// Gets the corresponding lock file path for |slot_id|
// (/run/lock/power_override/chapsd_token_init_slot_<<<SLOT_ID>>>.lock).
base::FilePath GetPowerdLockFilePath(int slot_id) const;