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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « no previous file | chromeos/dbus/power_manager_client_unittest.cc » ('j') | 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 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 << proto.suspend_id() 542 << proto.suspend_id()
542 << " while still waiting on attempt " 543 << " while still waiting on attempt "
543 << pending_suspend_id_; 544 << pending_suspend_id_;
544 } 545 }
545 546
546 pending_suspend_id_ = proto.suspend_id(); 547 pending_suspend_id_ = proto.suspend_id();
547 suspend_is_pending_ = true; 548 suspend_is_pending_ = true;
548 suspending_from_dark_resume_ = in_dark_resume; 549 suspending_from_dark_resume_ = in_dark_resume;
549 num_pending_suspend_readiness_callbacks_ = 0; 550 num_pending_suspend_readiness_callbacks_ = 0;
550 551
552 // Record the fact that observers are being notified to ensure that we don't
553 // report readiness prematurely if one of them calls
554 // GetSuspendReadinessCallback() and then runs the callback synchonously
555 // instead of asynchronously.
556 notifying_observers_about_suspend_imminent_ = true;
551 if (suspending_from_dark_resume_) 557 if (suspending_from_dark_resume_)
552 FOR_EACH_OBSERVER(Observer, observers_, DarkSuspendImminent()); 558 FOR_EACH_OBSERVER(Observer, observers_, DarkSuspendImminent());
553 else 559 else
554 FOR_EACH_OBSERVER(Observer, observers_, SuspendImminent()); 560 FOR_EACH_OBSERVER(Observer, observers_, SuspendImminent());
561 notifying_observers_about_suspend_imminent_ = false;
562
555 base::PowerMonitorDeviceSource::HandleSystemSuspending(); 563 base::PowerMonitorDeviceSource::HandleSystemSuspending();
556 MaybeReportSuspendReadiness(); 564 MaybeReportSuspendReadiness();
557 } 565 }
558 566
559 void SuspendDoneReceived(dbus::Signal* signal) { 567 void SuspendDoneReceived(dbus::Signal* signal) {
560 dbus::MessageReader reader(signal); 568 dbus::MessageReader reader(signal);
561 power_manager::SuspendDone proto; 569 power_manager::SuspendDone proto;
562 if (!reader.PopArrayOfBytesAsProto(&proto)) { 570 if (!reader.PopArrayOfBytesAsProto(&proto)) {
563 POWER_LOG(ERROR) << "Unable to decode protocol buffer from " 571 POWER_LOG(ERROR) << "Unable to decode protocol buffer from "
564 << power_manager::kSuspendDoneSignal << " signal"; 572 << power_manager::kSuspendDoneSignal << " signal";
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 749
742 num_pending_suspend_readiness_callbacks_--; 750 num_pending_suspend_readiness_callbacks_--;
743 MaybeReportSuspendReadiness(); 751 MaybeReportSuspendReadiness();
744 } 752 }
745 753
746 // Reports suspend readiness to powerd if no observers are still holding 754 // Reports suspend readiness to powerd if no observers are still holding
747 // suspend readiness callbacks. 755 // suspend readiness callbacks.
748 void MaybeReportSuspendReadiness() { 756 void MaybeReportSuspendReadiness() {
749 CHECK(suspend_is_pending_); 757 CHECK(suspend_is_pending_);
750 758
759 // Avoid reporting suspend readiness if some observers have yet to be
760 // notified about the pending attempt.
761 if (notifying_observers_about_suspend_imminent_)
762 return;
763
751 if (num_pending_suspend_readiness_callbacks_ > 0) { 764 if (num_pending_suspend_readiness_callbacks_ > 0) {
752 // TODO(derat): Remove after http://crbug.com/648580 is fixed. 765 // TODO(derat): Remove after http://crbug.com/648580 is fixed.
753 VLOG(1) << "Not reporting suspend readiness; waiting for " 766 VLOG(1) << "Not reporting suspend readiness; waiting for "
754 << num_pending_suspend_readiness_callbacks_ << " callback(s)"; 767 << num_pending_suspend_readiness_callbacks_ << " callback(s)";
755 return; 768 return;
756 } 769 }
757 770
758 std::string method_name; 771 std::string method_name;
759 int32_t delay_id = -1; 772 int32_t delay_id = -1;
760 if (suspending_from_dark_resume_) { 773 if (suspending_from_dark_resume_) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 // dark resume. Since |pending_suspend_id_| and |suspend_is_pending_| are 839 // dark resume. Since |pending_suspend_id_| and |suspend_is_pending_| are
827 // both shared by normal and dark suspends, |suspending_from_dark_resume_| 840 // both shared by normal and dark suspends, |suspending_from_dark_resume_|
828 // helps distinguish the context within which these variables are being used. 841 // helps distinguish the context within which these variables are being used.
829 bool suspending_from_dark_resume_; 842 bool suspending_from_dark_resume_;
830 843
831 // Number of callbacks that have been returned by 844 // Number of callbacks that have been returned by
832 // GetSuspendReadinessCallback() during the currently-pending suspend 845 // GetSuspendReadinessCallback() during the currently-pending suspend
833 // attempt but have not yet been called. 846 // attempt but have not yet been called.
834 int num_pending_suspend_readiness_callbacks_; 847 int num_pending_suspend_readiness_callbacks_;
835 848
849 // Inspected by MaybeReportSuspendReadiness() to avoid prematurely notifying
850 // powerd about suspend readiness while |observers_|' SuspendImminent()
851 // methods are being called by HandleSuspendImminent().
852 bool notifying_observers_about_suspend_imminent_;
853
836 // Last state passed to SetIsProjecting(). 854 // Last state passed to SetIsProjecting().
837 bool last_is_projecting_; 855 bool last_is_projecting_;
838 856
839 // The delegate used to manage the power consumption of Chrome's renderer 857 // The delegate used to manage the power consumption of Chrome's renderer
840 // processes. 858 // processes.
841 base::WeakPtr<RenderProcessManagerDelegate> render_process_manager_delegate_; 859 base::WeakPtr<RenderProcessManagerDelegate> render_process_manager_delegate_;
842 860
843 // Note: This should remain the last member so it'll be destroyed and 861 // Note: This should remain the last member so it'll be destroyed and
844 // invalidate its weak pointers before any other members are destroyed. 862 // invalidate its weak pointers before any other members are destroyed.
845 base::WeakPtrFactory<PowerManagerClientImpl> weak_ptr_factory_; 863 base::WeakPtrFactory<PowerManagerClientImpl> weak_ptr_factory_;
(...skipping 10 matching lines...) Expand all
856 // static 874 // static
857 PowerManagerClient* PowerManagerClient::Create( 875 PowerManagerClient* PowerManagerClient::Create(
858 DBusClientImplementationType type) { 876 DBusClientImplementationType type) {
859 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) 877 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
860 return new PowerManagerClientImpl(); 878 return new PowerManagerClientImpl();
861 DCHECK_EQ(FAKE_DBUS_CLIENT_IMPLEMENTATION, type); 879 DCHECK_EQ(FAKE_DBUS_CLIENT_IMPLEMENTATION, type);
862 return new FakePowerManagerClient(); 880 return new FakePowerManagerClient();
863 } 881 }
864 882
865 } // namespace chromeos 883 } // namespace chromeos
OLDNEW
« 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