static void __CFMessagePortDeallocate(CFTypeRef cf) { CFMessagePortRef ms = (CFMessagePortRef)cf; __CFMessagePortSetIsDeallocing(ms); CFMessagePortInvalidate(ms); // Delay cleanup of _replies until here so that invalidation during // SendRequest does not cause _replies to disappear out from under that function. if (NULL != ms->_replies) { CFRelease(ms->_replies); } if (NULL != ms->_name) { CFRelease(ms->_name); } if (NULL != ms->_port) { if (__CFMessagePortExtraMachRef(ms)) { mach_port_mod_refs(mach_task_self(), CFMachPortGetPort(ms->_port), MACH_PORT_RIGHT_SEND, -1); mach_port_mod_refs(mach_task_self(), CFMachPortGetPort(ms->_port), MACH_PORT_RIGHT_RECEIVE, -1); } CFMachPortInvalidate(ms->_port); CFRelease(ms->_port); } // A remote message port for a local message port in the same process will get the // same mach port, and the remote port will keep the mach port from being torn down, // thus keeping the remote port from getting any sort of death notification and // auto-invalidating; so we manually implement the 'auto-invalidation' here by // tickling each remote port to check its state after any message port is destroyed, // but most importantly after local message ports are destroyed. __CFLock(&__CFAllMessagePortsLock); CFMessagePortRef *remotePorts = NULL; CFIndex cnt = 0; if (NULL != __CFAllRemoteMessagePorts) { cnt = CFDictionaryGetCount(__CFAllRemoteMessagePorts); remotePorts = CFAllocatorAllocate(kCFAllocatorSystemDefault, cnt * sizeof(CFMessagePortRef), __kCFAllocatorGCScannedMemory); CFDictionaryGetKeysAndValues(__CFAllRemoteMessagePorts, NULL, (const void **)remotePorts); for (CFIndex idx = 0; idx < cnt; idx++) { CFRetain(remotePorts[idx]); } } __CFUnlock(&__CFAllMessagePortsLock); if (remotePorts) { for (CFIndex idx = 0; idx < cnt; idx++) { // as a side-effect, this will auto-invalidate the CFMessagePort if the CFMachPort is invalid CFMessagePortIsValid(remotePorts[idx]); CFRelease(remotePorts[idx]); } CFAllocatorDeallocate(kCFAllocatorSystemDefault, remotePorts); } }
static void __CFMessagePortDeallocate(CFTypeRef cf) { CFMessagePortRef ms = (CFMessagePortRef)cf; __CFMessagePortSetIsDeallocing(ms); CFMessagePortInvalidate(ms); // Delay cleanup of _replies until here so that invalidation during // SendRequest does not cause _replies to disappear out from under that function. if (NULL != ms->_replies) { CFRelease(ms->_replies); } if (NULL != ms->_name) { CFRelease(ms->_name); } if (NULL != ms->_port) { CFMachPortInvalidate(ms->_port); CFRelease(ms->_port); } }