Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Unified Diff: chromeos/dbus/power_manager_client.cc

Issue 2403733003: chromeos: Avoid crash on synchronous suspend readiness call. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chromeos/dbus/power_manager_client_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chromeos/dbus/power_manager_client.cc
diff --git a/chromeos/dbus/power_manager_client.cc b/chromeos/dbus/power_manager_client.cc
index 0d707e266db358812d22842c43997e3e785e6db6..3186f2ffefca09a4749dba19119694d173ae4b7e 100644
--- a/chromeos/dbus/power_manager_client.cc
+++ b/chromeos/dbus/power_manager_client.cc
@@ -59,6 +59,7 @@ class PowerManagerClientImpl : public PowerManagerClient {
suspend_is_pending_(false),
suspending_from_dark_resume_(false),
num_pending_suspend_readiness_callbacks_(0),
+ notifying_observers_about_suspend_imminent_(false),
last_is_projecting_(false),
weak_ptr_factory_(this) {}
@@ -548,10 +549,17 @@ class PowerManagerClientImpl : public PowerManagerClient {
suspending_from_dark_resume_ = in_dark_resume;
num_pending_suspend_readiness_callbacks_ = 0;
+ // Record the fact that observers are being notified to ensure that we don't
+ // report readiness prematurely if one of them calls
+ // GetSuspendReadinessCallback() and then runs the callback synchonously
+ // instead of asynchronously.
+ notifying_observers_about_suspend_imminent_ = true;
if (suspending_from_dark_resume_)
FOR_EACH_OBSERVER(Observer, observers_, DarkSuspendImminent());
else
FOR_EACH_OBSERVER(Observer, observers_, SuspendImminent());
+ notifying_observers_about_suspend_imminent_ = false;
+
base::PowerMonitorDeviceSource::HandleSystemSuspending();
MaybeReportSuspendReadiness();
}
@@ -748,6 +756,11 @@ class PowerManagerClientImpl : public PowerManagerClient {
void MaybeReportSuspendReadiness() {
CHECK(suspend_is_pending_);
+ // Avoid reporting suspend readiness if some observers have yet to be
+ // notified about the pending attempt.
+ if (notifying_observers_about_suspend_imminent_)
+ return;
+
if (num_pending_suspend_readiness_callbacks_ > 0) {
// TODO(derat): Remove after http://crbug.com/648580 is fixed.
VLOG(1) << "Not reporting suspend readiness; waiting for "
@@ -833,6 +846,11 @@ class PowerManagerClientImpl : public PowerManagerClient {
// attempt but have not yet been called.
int num_pending_suspend_readiness_callbacks_;
+ // Inspected by MaybeReportSuspendReadiness() to avoid prematurely notifying
+ // powerd about suspend readiness while |observers_|' SuspendImminent()
+ // methods are being called by HandleSuspendImminent().
+ bool notifying_observers_about_suspend_imminent_;
+
// Last state passed to SetIsProjecting().
bool last_is_projecting_;
« no previous file with comments | « no previous file | chromeos/dbus/power_manager_client_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698