#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
-#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <notify.h>
+#include <dispatch/dispatch.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFUserNotification.h>
CFUserNotificationRef gSleepNotification = NULL;
#endif // !kIOPMAcknowledgmentOptionSystemCapabilityRequirements
-pthread_t power_mgmt_thread;
time_t slept_at = 0;
time_t woke_at = 0;
time_t swept_at = 0;
static int sleeping = 0;
+int check_power_context; // dummy field for dispatch call
+extern void check_power_mgmt (void*);
+
#ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
#define WAKE_CAPS (kIOPMSystemPowerStateCapabilityCPU | kIOPMSystemPowerStateCapabilityNetwork)
static void
iosleep_capabilities_notifier(void *param, IOPMConnection connection, IOPMConnectionMessageToken token, IOPMSystemPowerStateCapabilities capabilities)
{
- plog(LLV_DEBUG, LOCATION, NULL,"received power-mgmt event: capabilities %X%s%s%s%s%s",
+ plog(ASL_LEVEL_DEBUG, "received power-mgmt event: capabilities %X%s%s%s%s%s",
capabilities,
capabilities & kIOPMSystemPowerStateCapabilityCPU ? " CPU" : "",
capabilities & kIOPMSystemPowerStateCapabilityVideo ? " Video" : "",
if ((capabilities & WAKE_CAPS) != WAKE_CAPS) {
if (!sleeping) {
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"received power-mgmt event: will sleep\n");
sleeping = 1;
slept_at = current_time();
} else {
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"ignored power-mgmt event: sleep(%x) while asleep\n", capabilities);
}
IOPMConnectionAcknowledgeEvent(connection, token );
} else if ((capabilities & WAKE_CAPS) == WAKE_CAPS) {
// allow processing of packets
if (sleeping) {
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"received power-mgmt event: will wake(%x)\n", capabilities);
sleeping = 0;
woke_at = current_time();
} else {
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"ignored power-mgmt event: wake(%x) while not asleep\n", capabilities);
}
IOPMConnectionAcknowledgeEvent(connection, token);
} else {
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"ignored power-mgmt event: capabilities(%x)\n", capabilities);
IOPMConnectionAcknowledgeEvent(connection, token);
}
+ dispatch_async_f(dispatch_get_main_queue(), &check_power_context, &check_power_mgmt);
}
#else
case kIOMessageSystemWillSleep:
sleeping = 1;
slept_at = current_time();
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"received power-mgmt event: will sleep\n");
IOAllowPowerChange(gIOPort, (long)messageArgument);
break;
break;
case kIOMessageSystemWillNotSleep:
/* someone refused an idle sleep */
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"received power-mgmt event: will not sleep\n");
sleeping = 0;
slept_at = 0;
break;
case kIOMessageSystemWillPowerOn:
if (sleeping) {
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"received power-mgmt event: will wake\n");
sleeping = 0;
} else {
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"received power-mgmt event: will power-on\n");
}
break;
case kIOMessageSystemHasPoweredOn:
woke_at = current_time();
if (slept_at) {
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"received power-mgmt event: has woken\n");
} else {
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"received power-mgmt event: has powered-on\n");
}
break;
default:
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"received power-mgmt event: %x\n", messageType);
break;
}
+ dispatch_async_f(dispatch_get_main_queue(), &check_power_context, &check_power_mgmt);
}
#endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
-void *
-power_mgmt_thread_func (void *arg)
+int
+init_power_mgmt (void)
{
#ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
IOReturn ret;
WAKE_CAPS,
&gPMConnection);
if (ret != kIOReturnSuccess) {
- plog(LLV_ERROR, LOCATION, NULL,"IOPMConnectionCreate failed (%d) power-mgmt thread\n", ret);
- return NULL;
+ plog(ASL_LEVEL_ERR, "IOPMConnectionCreate failed (%d) power-mgmt thread\n", ret);
+ return -1;
}
ret = IOPMConnectionSetNotification(gPMConnection, NULL, iosleep_capabilities_notifier);
if (ret != kIOReturnSuccess) {
- plog(LLV_ERROR, LOCATION, NULL,"IOPMConnectionCreate failed (%d) power-mgmt thread\n", ret);
- return NULL;
+ plog(ASL_LEVEL_ERR, "IOPMConnectionCreate failed (%d) power-mgmt thread\n", ret);
+ return -1;
}
- ret = IOPMConnectionScheduleWithRunLoop(gPMConnection, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
- if (ret != kIOReturnSuccess) {
- plog(LLV_ERROR, LOCATION, NULL,"IOPMConnectionCreate failed (%d) power-mgmt thread\n", ret);
- return NULL;
- }
+ IOPMConnectionSetDispatchQueue(gPMConnection, dispatch_get_main_queue());
+
#else
if ((gIOPort = IORegisterForSystemPower(0, ¬ify, iosleep_notifier, &iterator)) == MACH_PORT_NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"IORegisterForSystemPower failed for power-mgmt thread\n");
- return NULL;
+ return -1;
}
-
- CFRunLoopAddSource(CFRunLoopGetCurrent(),
- IONotificationPortGetRunLoopSource(notify),
- kCFRunLoopDefaultMode);
+
+ IONotificationPortSetDispatchQueue(notify, dispatch_get_main_queue());
+
#endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
- CFRunLoopRun();
- return NULL;
+ return 0;
}
-int
-init_power_mgmt (void)
+void
+cleanup_power_mgmt (void)
{
- int err;
-
- if ((err = pthread_create(&power_mgmt_thread, NULL, power_mgmt_thread_func, NULL))) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to create power-mgmt thread: %d\n", err);
- return -1;
- }
-
- return 0;
+#ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
+
+ IOPMConnectionSetDispatchQueue(gPMConnection, NULL);
+ IOPMConnectionRelease(gPMConnection);
+
+#else
+
+ IODeregisterForSystemPower(&iterator);
+ IONotificationPortDestroy(notify);
+
+#endif // kIOPMAcknowledgmentOptionSystemCapabilityRequirements
+
}
void
-check_power_mgmt (void)
+check_power_mgmt (void *context)
{
if (slept_at && woke_at) {
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"handling power-mgmt event: sleep-wake\n");
swept_at = current_time();
sweep_sleepwake();
slept_at = 0;
woke_at = 0;
} else if (woke_at) {
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"handling power-mgmt event: power-on\n");
woke_at = 0;
}