]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_utilities/lib/powerwatch.cpp
Security-55471.14.8.tar.gz
[apple/security.git] / libsecurity_utilities / lib / powerwatch.cpp
index f1ab95249917aa1eb0d8560352921d2b95fcb956..9c197af2b19487c6f3be3729ac3fe24a8af6f011 100644 (file)
@@ -103,37 +103,48 @@ IOPowerWatcher::setupDarkWake()
     
     mInDarkWake = false;
 
     
     mInDarkWake = false;
 
-    mIOPMqueue = dispatch_queue_create("com.apple.security.IOPowerWatcher", NULL);
-    if (mIOPMqueue == NULL)
-       return;
-
     ret = ::IOPMConnectionCreate(CFSTR("IOPowerWatcher"),
                                 kIOPMSystemPowerStateCapabilityDisk 
                                 | kIOPMSystemPowerStateCapabilityNetwork
                                 | kIOPMSystemPowerStateCapabilityAudio 
                                 | kIOPMSystemPowerStateCapabilityVideo,
                                 &mIOPMconn);
     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()
 {
 }
 
 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()
 {
 }
 
 IOPowerWatcher::~IOPowerWatcher()
 {
+       // Make sure to wait until the asynchronous method
+       // finishes, to avoid <rdar://problem/14355434>
+       if (mDarkWakeGroup) {
+               ::dispatch_group_wait(mDarkWakeGroup, DISPATCH_TIME_FOREVER);
+               ::dispatch_release(mDarkWakeGroup);
+       }
        if (mKernelPort)
                ::IODeregisterForSystemPower(&mHandle);
 
        if (mKernelPort)
                ::IODeregisterForSystemPower(&mHandle);