]> git.saurik.com Git - apple/cf.git/blobdiff - CFMachPort.c
CF-635.tar.gz
[apple/cf.git] / CFMachPort.c
index 5f9cbb5fd76cd1d37c65740ab929c3403429059c..4a60872b421bb02ed30fbcbf293ede720a25a544 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Apple Inc. All rights reserved.
+ * Copyright (c) 2011 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFMachPort.c
-       Copyright (c) 1998-2010, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -30,7 +30,6 @@
 #include <CoreFoundation/CFRunLoop.h>
 #include <CoreFoundation/CFArray.h>
 #include <dispatch/dispatch.h>
-#include <libkern/OSAtomic.h>
 #include <mach/mach.h>
 #include <dlfcn.h>
 #include "CFInternal.h"
@@ -225,7 +224,7 @@ static __CFPointerArray *__CFAllMachPorts = nil;
 static Boolean __CFMachPortCheck(mach_port_t port) {
     mach_port_type_t type = 0;
     kern_return_t ret = mach_port_type(mach_task_self(), port, &type);
-    return (KERN_SUCCESS != ret || (type & MACH_PORT_TYPE_DEAD_NAME)) ? false : true;
+    return (KERN_SUCCESS != ret || (0 == (type & MACH_PORT_TYPE_PORT_RIGHTS))) ? false : true;
 }
 
 static void __CFMachPortChecker(Boolean fromTimer) { // only call on __portQueue()
@@ -322,7 +321,7 @@ CFMachPortRef _CFMachPortCreateWithPort2(CFAllocatorRef allocator, mach_port_t p
 
     mach_port_type_t type = 0;
     kern_return_t ret = mach_port_type(mach_task_self(), port, &type);
-    if (KERN_SUCCESS != ret || (type & ~(MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_SEND_ONCE|MACH_PORT_TYPE_RECEIVE|MACH_PORT_TYPE_DNREQUEST))) {
+    if (KERN_SUCCESS != ret || (0 == (type & MACH_PORT_TYPE_PORT_RIGHTS))) {
         if (type & ~MACH_PORT_TYPE_DEAD_NAME) {
             CFLog(kCFLogLevelError, CFSTR("*** CFMachPortCreateWithPort(): bad Mach port parameter (0x%lx) or unsupported mysterious kind of Mach port (%d, %ld)"), (unsigned long)port, ret, (unsigned long)type);
         }
@@ -331,17 +330,16 @@ CFMachPortRef _CFMachPortCreateWithPort2(CFAllocatorRef allocator, mach_port_t p
 
     __block CFMachPortRef mp = NULL;
     dispatch_sync(__portQueue(), ^{
-            static Boolean portCheckerGoing = false;
-            if (!portCheckerGoing) {
+            static dispatch_source_t timerSource = NULL;
+            if (timerSource == NULL) {
                 uint64_t nanos = 63 * 1000 * 1000 * 1000ULL;
                 uint64_t leeway = 9 * 1000ULL;
-                dispatch_source_t timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, __portQueue());
+                timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, __portQueue());
                 dispatch_source_set_timer(timerSource, dispatch_time(DISPATCH_TIME_NOW, nanos), nanos, leeway);
                 dispatch_source_set_event_handler(timerSource, ^{
                     __CFMachPortChecker(true);
                 });
                 dispatch_resume(timerSource);
-                portCheckerGoing = true;
             }
 
 #if defined(AVOID_WEAK_COLLECTIONS)
@@ -535,11 +533,6 @@ Boolean CFMachPortIsValid(CFMachPortRef mp) {
     mach_port_type_t type = 0;
     kern_return_t ret = mach_port_type(mach_task_self(), mp->_port, &type);
     if (KERN_SUCCESS != ret || (type & ~(MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_SEND_ONCE|MACH_PORT_TYPE_RECEIVE|MACH_PORT_TYPE_DNREQUEST))) {
-        CFRetain(mp);
-        dispatch_async(dispatch_get_global_queue(0, 0), ^{
-           CFMachPortInvalidate(mp);
-           CFRelease(mp);
-        });
        return false;
     }
     return true;
@@ -583,20 +576,20 @@ static void *__CFMachPortPerform(void *msg, CFIndex size, CFAllocatorRef allocat
     CHECK_FOR_FORK_RET(NULL);
     CFMachPortRef mp = (CFMachPortRef)info;
     __block Boolean isValid = false;
+    __block void *context_info = NULL;
+    __block void (*context_release)(const void *) = NULL;
     dispatch_sync(__portQueue(), ^{
             isValid = __CFMachPortIsValid(mp);
+            if (!isValid) return;
+            if (mp->_context.retain) {
+                context_info = (void *)mp->_context.retain(mp->_context.info);
+                context_release = mp->_context.release;
+            } else {
+                context_info = mp->_context.info;
+            }
         });
     if (!isValid) return NULL;
 
-    void *context_info = NULL;
-    void (*context_release)(const void *) = NULL;
-    if (mp->_context.retain) {
-        context_info = (void *)mp->_context.retain(mp->_context.info);
-        context_release = mp->_context.release;
-    } else {
-        context_info = mp->_context.info;
-    }
-
     mp->_callout(mp, msg, size, context_info);
 
     if (context_release) {