diff options
author | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-04 04:18:41 +0000 |
---|---|---|
committer | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-04 04:18:41 +0000 |
commit | 7e15d35c1dbbec11794d2754ba80b0ff872d144b (patch) | |
tree | 0052e9a1223443bf45ad0a317963def153955132 /base | |
parent | fa2601abcdde27adbdba2b5de8d849908ad41704 (diff) | |
download | chromium_src-7e15d35c1dbbec11794d2754ba80b0ff872d144b.zip chromium_src-7e15d35c1dbbec11794d2754ba80b0ff872d144b.tar.gz chromium_src-7e15d35c1dbbec11794d2754ba80b0ff872d144b.tar.bz2 |
Mac: Split SystemMonitor initialization so it's not blocked by the Sandbox.
In OS X 10.7 Lion, the IO port we listen on to monitor system power events is blocked by the Sandbox.
Move the allocation of the IO port so it happens early on during Chrome startup.
BUG=83783
TEST=When putting a system to sleep with Chrome running, the browser shouldn't crash. Also, need to monitor crash logs to see that this crash goes away.
Review URL: http://codereview.chromium.org/7235023
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@91462 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/system_monitor/system_monitor.h | 13 | ||||
-rw-r--r-- | base/system_monitor/system_monitor_mac.mm | 40 | ||||
-rw-r--r-- | base/system_monitor/system_monitor_unittest.cc | 4 |
3 files changed, 40 insertions, 17 deletions
diff --git a/base/system_monitor/system_monitor.h b/base/system_monitor/system_monitor.h index e2de14c..78ab50a 100644 --- a/base/system_monitor/system_monitor.h +++ b/base/system_monitor/system_monitor.h @@ -50,6 +50,14 @@ class BASE_API SystemMonitor { // Get the application-wide SystemMonitor (if not present, returns NULL). static SystemMonitor* Get(); +#if defined(OS_MACOSX) + // Allocate system resources needed by the SystemMonitor class. + // + // This function must be called before instantiating an instance of the class + // and before the Sandbox is initialized. + static void AllocateSystemIOPorts(); +#endif + // // Power-related APIs // @@ -130,11 +138,6 @@ class BASE_API SystemMonitor { base::OneShotTimer<SystemMonitor> delayed_battery_check_; #endif -#if defined(OS_MACOSX) - IONotificationPortRef notification_port_ref_; - io_object_t notifier_object_; -#endif - DISALLOW_COPY_AND_ASSIGN(SystemMonitor); }; diff --git a/base/system_monitor/system_monitor_mac.mm b/base/system_monitor/system_monitor_mac.mm index 6192a26..baaadf0 100644 --- a/base/system_monitor/system_monitor_mac.mm +++ b/base/system_monitor/system_monitor_mac.mm @@ -15,13 +15,15 @@ namespace base { namespace { io_connect_t g_system_power_io_port = 0; +IONotificationPortRef g_notification_port_ref = 0; +io_object_t g_notifier_object = 0; -void SystemPowerEventCallback(void* system_monitor, +void SystemPowerEventCallback(void*, io_service_t service, natural_t message_type, void* message_argument) { - DCHECK(system_monitor); - SystemMonitor* sys_monitor = reinterpret_cast<SystemMonitor*>(system_monitor); + SystemMonitor* sys_monitor = SystemMonitor::Get(); + DCHECK(sys_monitor); switch (message_type) { case kIOMessageSystemWillSleep: sys_monitor->ProcessPowerMessage(SystemMonitor::SUSPEND_EVENT); @@ -37,22 +39,36 @@ void SystemPowerEventCallback(void* system_monitor, } // namespace -void SystemMonitor::PlatformInit() { +// The reason we can't include this code in the constructor is because +// PlatformInit() requires an active runloop and the IO port needs to be +// allocated at sandbox initialization time, before there's a runloop. +// See crbug.com/83783 . + +// static +void SystemMonitor::AllocateSystemIOPorts() { DCHECK_EQ(g_system_power_io_port, 0u); // Notification port allocated by IORegisterForSystemPower. g_system_power_io_port = IORegisterForSystemPower( - this, ¬ification_port_ref_, SystemPowerEventCallback, - ¬ifier_object_); + NULL, &g_notification_port_ref, SystemPowerEventCallback, + &g_notifier_object); + + DCHECK_NE(g_system_power_io_port, 0u); +} + +void SystemMonitor::PlatformInit() { + // Need to call AllocateSystemIOPorts() before constructing a SystemMonitor + // object. DCHECK_NE(g_system_power_io_port, 0u); if (g_system_power_io_port == 0) return; // Add the notification port to the application runloop - CFRunLoopAddSource(CFRunLoopGetCurrent(), - IONotificationPortGetRunLoopSource(notification_port_ref_), - kCFRunLoopCommonModes); + CFRunLoopAddSource( + CFRunLoopGetCurrent(), + IONotificationPortGetRunLoopSource(g_notification_port_ref), + kCFRunLoopCommonModes); } void SystemMonitor::PlatformDestroy() { @@ -63,11 +79,11 @@ void SystemMonitor::PlatformDestroy() { // Remove the sleep notification port from the application runloop CFRunLoopRemoveSource( CFRunLoopGetCurrent(), - IONotificationPortGetRunLoopSource(notification_port_ref_), + IONotificationPortGetRunLoopSource(g_notification_port_ref), kCFRunLoopCommonModes); // Deregister for system sleep notifications - IODeregisterForSystemPower(¬ifier_object_); + IODeregisterForSystemPower(&g_notifier_object); // IORegisterForSystemPower implicitly opens the Root Power Domain IOService, // so we close it here. @@ -76,7 +92,7 @@ void SystemMonitor::PlatformDestroy() { g_system_power_io_port = 0; // Destroy the notification port allocated by IORegisterForSystemPower. - IONotificationPortDestroy(notification_port_ref_); + IONotificationPortDestroy(g_notification_port_ref); } } // namespace base diff --git a/base/system_monitor/system_monitor_unittest.cc b/base/system_monitor/system_monitor_unittest.cc index 8756c58..f4a4e73 100644 --- a/base/system_monitor/system_monitor_unittest.cc +++ b/base/system_monitor/system_monitor_unittest.cc @@ -48,6 +48,10 @@ TEST(SystemMonitor, PowerNotifications) { // Initialize a message loop for this to run on. MessageLoop loop; +#if defined(OS_MACOSX) + SystemMonitor::AllocateSystemIOPorts(); +#endif + SystemMonitor system_monitor; PowerTest test[kObservers]; for (int index = 0; index < kObservers; ++index) |