X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b1ab9ed8d0e0f1c3b66d7daa8fd5564444c56195..e3d3b979fd185d8303f28a937baa53a187fb8c7d:/libsecurity_utilities/lib/powerwatch.cpp?ds=inline diff --git a/libsecurity_utilities/lib/powerwatch.cpp b/libsecurity_utilities/lib/powerwatch.cpp index f1ab9524..9c197af2 100644 --- a/libsecurity_utilities/lib/powerwatch.cpp +++ b/libsecurity_utilities/lib/powerwatch.cpp @@ -103,37 +103,48 @@ IOPowerWatcher::setupDarkWake() mInDarkWake = false; - mIOPMqueue = dispatch_queue_create("com.apple.security.IOPowerWatcher", NULL); - if (mIOPMqueue == NULL) - return; - ret = ::IOPMConnectionCreate(CFSTR("IOPowerWatcher"), kIOPMSystemPowerStateCapabilityDisk | kIOPMSystemPowerStateCapabilityNetwork | kIOPMSystemPowerStateCapabilityAudio | kIOPMSystemPowerStateCapabilityVideo, &mIOPMconn); - if (ret != kIOReturnSuccess) - return; - - ret = ::IOPMConnectionSetNotification(mIOPMconn, this, - (IOPMEventHandlerType)iopmcallback); - if (ret != kIOReturnSuccess) - return; - - ::IOPMConnectionSetDispatchQueue(mIOPMconn, mIOPMqueue); + if (ret == kIOReturnSuccess) { + ret = ::IOPMConnectionSetNotification(mIOPMconn, this, + (IOPMEventHandlerType)iopmcallback); + if (ret == kIOReturnSuccess) { + ::IOPMConnectionSetDispatchQueue(mIOPMconn, mIOPMqueue); + } + } + + dispatch_group_leave(mDarkWakeGroup); } IOPowerWatcher::IOPowerWatcher() { - if (!(mKernelPort = ::IORegisterForSystemPower(this, &mPortRef, ioCallback, &mHandle))) - UnixError::throwMe(EINVAL); // no clue - - setupDarkWake(); + if (!(mKernelPort = ::IORegisterForSystemPower(this, &mPortRef, ioCallback, &mHandle))) + UnixError::throwMe(EINVAL); // no clue + + mIOPMqueue = dispatch_queue_create("com.apple.security.IOPowerWatcher", NULL); + if (mIOPMqueue == NULL) + return; + + // Running in background since this will wait for the power + // management in configd and we are not willing to block on + // that, power events will come in when they do. + mDarkWakeGroup = dispatch_group_create(); + dispatch_group_enter(mDarkWakeGroup); + dispatch_async(mIOPMqueue, ^ { setupDarkWake(); }); } IOPowerWatcher::~IOPowerWatcher() { + // Make sure to wait until the asynchronous method + // finishes, to avoid + if (mDarkWakeGroup) { + ::dispatch_group_wait(mDarkWakeGroup, DISPATCH_TIME_FOREVER); + ::dispatch_release(mDarkWakeGroup); + } if (mKernelPort) ::IODeregisterForSystemPower(&mHandle);