| Index: base/system_monitor/system_monitor_mac.mm
|
| diff --git a/base/system_monitor/system_monitor_mac.mm b/base/system_monitor/system_monitor_mac.mm
|
| index 6192a2692429bb76d539782a6e89205e7ad980b0..baaadf052db913eb7f3c548f81c545901f6192e8 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
|
|
|