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

Side by Side Diff: chromeos/dbus/power_manager_client.cc

Issue 2451013002: chromeos: Avoid crash on synchronous suspend readiness call. (Closed)
Patch Set: Created 4 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chromeos/dbus/power_manager_client.h" 5 #include "chromeos/dbus/power_manager_client.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <memory> 10 #include <memory>
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 : origin_thread_id_(base::PlatformThread::CurrentId()), 52 : origin_thread_id_(base::PlatformThread::CurrentId()),
53 power_manager_proxy_(NULL), 53 power_manager_proxy_(NULL),
54 suspend_delay_id_(-1), 54 suspend_delay_id_(-1),
55 has_suspend_delay_id_(false), 55 has_suspend_delay_id_(false),
56 dark_suspend_delay_id_(-1), 56 dark_suspend_delay_id_(-1),
57 has_dark_suspend_delay_id_(false), 57 has_dark_suspend_delay_id_(false),
58 pending_suspend_id_(-1), 58 pending_suspend_id_(-1),
59 suspend_is_pending_(false), 59 suspend_is_pending_(false),
60 suspending_from_dark_resume_(false), 60 suspending_from_dark_resume_(false),
61 num_pending_suspend_readiness_callbacks_(0), 61 num_pending_suspend_readiness_callbacks_(0),
62 notifying_observers_about_suspend_imminent_(false),
62 last_is_projecting_(false), 63 last_is_projecting_(false),
63 weak_ptr_factory_(this) {} 64 weak_ptr_factory_(this) {}
64 65
65 ~PowerManagerClientImpl() override { 66 ~PowerManagerClientImpl() override {
66 // Here we should unregister suspend notifications from powerd, 67 // Here we should unregister suspend notifications from powerd,
67 // however: 68 // however:
68 // - The lifetime of the PowerManagerClientImpl can extend past that of 69 // - The lifetime of the PowerManagerClientImpl can extend past that of
69 // the objectproxy, 70 // the objectproxy,
70 // - power_manager can already detect that the client is gone and 71 // - power_manager can already detect that the client is gone and
71 // unregister our suspend delay. 72 // unregister our suspend delay.
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 << proto.suspend_id() 538 << proto.suspend_id()
538 << " while still waiting on attempt " 539 << " while still waiting on attempt "
539 << pending_suspend_id_; 540 << pending_suspend_id_;
540 } 541 }
541 542
542 pending_suspend_id_ = proto.suspend_id(); 543 pending_suspend_id_ = proto.suspend_id();
543 suspend_is_pending_ = true; 544 suspend_is_pending_ = true;
544 suspending_from_dark_resume_ = in_dark_resume; 545 suspending_from_dark_resume_ = in_dark_resume;
545 num_pending_suspend_readiness_callbacks_ = 0; 546 num_pending_suspend_readiness_callbacks_ = 0;
546 547
548 // Record the fact that observers are being notified to ensure that we don't
549 // report readiness prematurely if one of them calls
550 // GetSuspendReadinessCallback() and then runs the callback synchonously
551 // instead of asynchronously.
552 notifying_observers_about_suspend_imminent_ = true;
547 if (suspending_from_dark_resume_) 553 if (suspending_from_dark_resume_)
548 FOR_EACH_OBSERVER(Observer, observers_, DarkSuspendImminent()); 554 FOR_EACH_OBSERVER(Observer, observers_, DarkSuspendImminent());
549 else 555 else
550 FOR_EACH_OBSERVER(Observer, observers_, SuspendImminent()); 556 FOR_EACH_OBSERVER(Observer, observers_, SuspendImminent());
557 notifying_observers_about_suspend_imminent_ = false;
558
551 base::PowerMonitorDeviceSource::HandleSystemSuspending(); 559 base::PowerMonitorDeviceSource::HandleSystemSuspending();
552 MaybeReportSuspendReadiness(); 560 MaybeReportSuspendReadiness();
553 } 561 }
554 562
555 void SuspendDoneReceived(dbus::Signal* signal) { 563 void SuspendDoneReceived(dbus::Signal* signal) {
556 dbus::MessageReader reader(signal); 564 dbus::MessageReader reader(signal);
557 power_manager::SuspendDone proto; 565 power_manager::SuspendDone proto;
558 if (!reader.PopArrayOfBytesAsProto(&proto)) { 566 if (!reader.PopArrayOfBytesAsProto(&proto)) {
559 POWER_LOG(ERROR) << "Unable to decode protocol buffer from " 567 POWER_LOG(ERROR) << "Unable to decode protocol buffer from "
560 << power_manager::kSuspendDoneSignal << " signal"; 568 << power_manager::kSuspendDoneSignal << " signal";
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 729
722 num_pending_suspend_readiness_callbacks_--; 730 num_pending_suspend_readiness_callbacks_--;
723 MaybeReportSuspendReadiness(); 731 MaybeReportSuspendReadiness();
724 } 732 }
725 733
726 // Reports suspend readiness to powerd if no observers are still holding 734 // Reports suspend readiness to powerd if no observers are still holding
727 // suspend readiness callbacks. 735 // suspend readiness callbacks.
728 void MaybeReportSuspendReadiness() { 736 void MaybeReportSuspendReadiness() {
729 CHECK(suspend_is_pending_); 737 CHECK(suspend_is_pending_);
730 738
739 // Avoid reporting suspend readiness if some observers have yet to be
740 // notified about the pending attempt.
741 if (notifying_observers_about_suspend_imminent_)
742 return;
743
731 if (num_pending_suspend_readiness_callbacks_ > 0) 744 if (num_pending_suspend_readiness_callbacks_ > 0)
732 return; 745 return;
733 746
734 std::string method_name; 747 std::string method_name;
735 int32_t delay_id = -1; 748 int32_t delay_id = -1;
736 if (suspending_from_dark_resume_) { 749 if (suspending_from_dark_resume_) {
737 method_name = power_manager::kHandleDarkSuspendReadinessMethod; 750 method_name = power_manager::kHandleDarkSuspendReadinessMethod;
738 delay_id = dark_suspend_delay_id_; 751 delay_id = dark_suspend_delay_id_;
739 } else { 752 } else {
740 method_name = power_manager::kHandleSuspendReadinessMethod; 753 method_name = power_manager::kHandleSuspendReadinessMethod;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 // dark resume. Since |pending_suspend_id_| and |suspend_is_pending_| are 803 // dark resume. Since |pending_suspend_id_| and |suspend_is_pending_| are
791 // both shared by normal and dark suspends, |suspending_from_dark_resume_| 804 // both shared by normal and dark suspends, |suspending_from_dark_resume_|
792 // helps distinguish the context within which these variables are being used. 805 // helps distinguish the context within which these variables are being used.
793 bool suspending_from_dark_resume_; 806 bool suspending_from_dark_resume_;
794 807
795 // Number of callbacks that have been returned by 808 // Number of callbacks that have been returned by
796 // GetSuspendReadinessCallback() during the currently-pending suspend 809 // GetSuspendReadinessCallback() during the currently-pending suspend
797 // attempt but have not yet been called. 810 // attempt but have not yet been called.
798 int num_pending_suspend_readiness_callbacks_; 811 int num_pending_suspend_readiness_callbacks_;
799 812
813 // Inspected by MaybeReportSuspendReadiness() to avoid prematurely notifying
814 // powerd about suspend readiness while |observers_|' SuspendImminent()
815 // methods are being called by HandleSuspendImminent().
816 bool notifying_observers_about_suspend_imminent_;
817
800 // Last state passed to SetIsProjecting(). 818 // Last state passed to SetIsProjecting().
801 bool last_is_projecting_; 819 bool last_is_projecting_;
802 820
803 // The delegate used to manage the power consumption of Chrome's renderer 821 // The delegate used to manage the power consumption of Chrome's renderer
804 // processes. 822 // processes.
805 base::WeakPtr<RenderProcessManagerDelegate> render_process_manager_delegate_; 823 base::WeakPtr<RenderProcessManagerDelegate> render_process_manager_delegate_;
806 824
807 // Note: This should remain the last member so it'll be destroyed and 825 // Note: This should remain the last member so it'll be destroyed and
808 // invalidate its weak pointers before any other members are destroyed. 826 // invalidate its weak pointers before any other members are destroyed.
809 base::WeakPtrFactory<PowerManagerClientImpl> weak_ptr_factory_; 827 base::WeakPtrFactory<PowerManagerClientImpl> weak_ptr_factory_;
(...skipping 10 matching lines...) Expand all
820 // static 838 // static
821 PowerManagerClient* PowerManagerClient::Create( 839 PowerManagerClient* PowerManagerClient::Create(
822 DBusClientImplementationType type) { 840 DBusClientImplementationType type) {
823 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) 841 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
824 return new PowerManagerClientImpl(); 842 return new PowerManagerClientImpl();
825 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); 843 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
826 return new FakePowerManagerClient(); 844 return new FakePowerManagerClient();
827 } 845 }
828 846
829 } // namespace chromeos 847 } // namespace chromeos
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698