SC_MachMessagePort::~SC_MachMessagePort() { if (mServerPort) { CFMessagePortInvalidate(mServerPort); CFRelease(mServerPort); } if (mReplyPort) { CFMessagePortInvalidate(mReplyPort); CFRelease(mReplyPort); } }
Boolean CFMessagePortIsValid(CFMessagePortRef ms) { __CFGenericValidateType(ms, __kCFMessagePortTypeID); if (!__CFMessagePortIsValid(ms)) return false; if (NULL != ms->_port && !CFMachPortIsValid(ms->_port)) { CFMessagePortInvalidate(ms); return false; } if (NULL != ms->_replyPort && !CFMachPortIsValid(ms->_replyPort)) { CFMessagePortInvalidate(ms); return false; } if (NULL != ms->_source && !CFRunLoopSourceIsValid(ms->_source)) { CFMessagePortInvalidate(ms); return false; } return true; }
CACFLocalMessagePort::~CACFLocalMessagePort() { if(mRunLoopSource != NULL) { CFRelease(mRunLoopSource); } if(mMessagePort != NULL) { CFMessagePortInvalidate(mMessagePort); CFRelease(mMessagePort); } }
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); } }
extern void GPDuplexClient_Release(GPDuplexClientRef client) { if (client != NULL) { CFLog(4, CFSTR("release client = %@"), client->clientPort); if (--(client->refcount) != 0) return; if (client->serverPort != NULL) CFRelease(client->serverPort); if (client->clientPort != NULL) { CFMessagePortInvalidate(client->clientPort); if (client->clientSource != NULL) CFRelease(client->clientSource); CFRelease(client->clientPort); } CFRelease(client->observers); free(client); } }
static void __CFMessagePortInvalidationCallBack(CFMachPortRef port, void *info) { // info has been setup as the CFMessagePort owning the CFMachPort CFMessagePortInvalidate(info); }