0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
SleepWakeNotifier.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 3
9  * of the License, or any later version.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21 
29 #include <Common/Compat.h>
30 
31 #include "SleepWakeNotifier.h"
32 
33 #include <Common/Logger.h>
34 
35 #if defined(__APPLE__)
36 #include <mach/mach_port.h>
37 #include <mach/mach_interface.h>
38 #include <mach/mach_init.h>
39 #include <IOKit/pwr_mgt/IOPMLib.h>
40 #include <IOKit/IOMessage.h>
41 #endif
42 
43 
44 using namespace Hypertable;
45 
46 SleepWakeNotifier::SleepWakeNotifier(std::function<void()> sleep_callback,
47  std::function<void()> wakeup_callback)
48  : m_thread(&SleepWakeNotifier::thread_func, this),
49  m_callback_sleep(sleep_callback), m_callback_wakeup(wakeup_callback) {
50 }
51 
53  if (m_callback_sleep)
55 }
56 
60 }
61 
62 
63 #if defined(__APPLE__)
64 
65 void system_sleep_callback(void * refCon, io_service_t service,
66  natural_t messageType, void * messageArgument) {
67  SleepWakeNotifier *sleep_wake_notifier = (SleepWakeNotifier *)refCon;
68 
69  switch ( messageType ) {
70 
71  case kIOMessageCanSystemSleep:
72  /* Idle sleep is about to kick in. This message will not be sent for forced sleep.
73  Applications have a chance to prevent sleep by calling IOCancelPowerChange.
74  Most applications should not prevent idle sleep.
75 
76  Power Management waits up to 30 seconds for you to either allow or deny idle
77  sleep. If you don't acknowledge this power change by calling either
78  IOAllowPowerChange or IOCancelPowerChange, the system will wait 30
79  seconds then go to sleep.
80  */
81 
82  //Uncomment to cancel idle sleep
83  //IOCancelPowerChange( root_port, (long)messageArgument );
84  // we will allow idle sleep
85  //sleep_wake_notifier->handle_sleep();
86  IOAllowPowerChange( sleep_wake_notifier->get_root_port(), (long)messageArgument );
87  break;
88 
89  case kIOMessageSystemWillSleep:
90  /* The system WILL go to sleep. If you do not call IOAllowPowerChange or
91  IOCancelPowerChange to acknowledge this message, sleep will be
92  delayed by 30 seconds.
93 
94  NOTE: If you call IOCancelPowerChange to deny sleep it returns
95  kIOReturnSuccess, however the system WILL still go to sleep.
96  */
97  sleep_wake_notifier->handle_sleep();
98  IOAllowPowerChange( sleep_wake_notifier->get_root_port(), (long)messageArgument );
99  break;
100 
101  case kIOMessageSystemWillPowerOn:
102  //System has started the wake up process...
103  sleep_wake_notifier->handle_wakeup();
104  break;
105 
106  case kIOMessageSystemHasPoweredOn:
107  //System has finished waking up...
108  break;
109 
110  default:
111  break;
112  }
113 }
114 
115 #endif
116 
117 
119 
120 #if defined(__APPLE__)
121 
122  // register to receive system sleep notifications
123  m_root_port = IORegisterForSystemPower(this, &m_notify_port_ref,
124  system_sleep_callback,
125  &m_notifier_object);
126  if ( m_root_port == 0 ) {
127  HT_INFO("IORegisterForSystemPower failed");
128  return;
129  }
130 
131  // add the notification port to the application runloop
132  CFRunLoopAddSource( CFRunLoopGetCurrent(),
133  IONotificationPortGetRunLoopSource(m_notify_port_ref), kCFRunLoopCommonModes );
134 
135  // get current thread's run loop
136  m_run_loop = CFRunLoopGetCurrent();
137 
138  // start the run loop to receive sleep notifications.
139  CFRunLoopRun();
140 
141 #else
142 
143 #endif
144 
145 }
146 
147 
149 
150 #if defined(__APPLE__)
151  // remove the sleep notification port from the application runloop
152  CFRunLoopRemoveSource( CFRunLoopGetCurrent(),
153  IONotificationPortGetRunLoopSource(m_notify_port_ref),
154  kCFRunLoopCommonModes );
155 
156  // deregister for system sleep notifications
157  IODeregisterForSystemPower( &m_notifier_object );
158 
159  // IORegisterForSystemPower implicitly opens the Root Power Domain IOService
160  // so we close it here
161  IOServiceClose( m_root_port );
162 
163  // destroy the notification port allocated by IORegisterForSystemPower
164  IONotificationPortDestroy( m_notify_port_ref );
165 
166  // stop run loop
167  CFRunLoopStop(m_run_loop);
168 #endif
169 
170  m_thread.join();
171 }
Delivers sleep and wakeup notifications.
SleepWakeNotifier(std::function< void()> sleep_callback, std::function< void()> wakeup_callback)
Constructor.
#define HT_INFO(msg)
Definition: Logger.h:271
std::thread m_thread
Event notification polling thread.
~SleepWakeNotifier()
Destructor Does OS-specific deregistering of sleep/wakeup notification interest and then joins m_thre...
std::function< void()> m_callback_sleep
Registered sleep callback.
void thread_func()
Thread function for event notification polling thread (m_thread)
Logging routines and macros.
void handle_sleep()
Called by polling thread to deliver sleep notification Calls registered sleep callback m_callback_sle...
Compatibility Macros for C/C++.
std::function< void()> m_callback_wakeup
Registered wakeup callback.
Hypertable definitions
Declaration for SleepWakeNotifier.
void handle_wakeup()
Called by polling thread to deliver wakeup notification Calls registered wakeup callback m_callback_w...