CFNetworkSchedule.c [plain text]
#include "CFNetworkSchedule.h"
#include <CFNetwork/CFNetwork.h>
#include <SystemConfiguration/SystemConfiguration.h>
void
_CFTypeScheduleOnRunLoop(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
CFTypeID t = CFGetTypeID(obj);
CFTypeRef src = NULL;
void(*fn)(CFTypeRef, CFRunLoopRef, CFStringRef);
void(*fn2)(CFRunLoopRef, CFTypeRef, CFStringRef);
fn = NULL;
fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopAddSource;
if (t == CFRunLoopSourceGetTypeID()) {
src = CFRetain(obj);
}
else if (t == CFMachPortGetTypeID()) {
src = CFMachPortCreateRunLoopSource(CFGetAllocator(obj), (CFMachPortRef)obj, 0);
}
else if (t == CFSocketGetTypeID()) {
src = CFSocketCreateRunLoopSource(CFGetAllocator(obj), (CFSocketRef)obj, 0);
}
else if (t == CFReadStreamGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFReadStreamScheduleWithRunLoop;
}
else if (t == CFWriteStreamGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFWriteStreamScheduleWithRunLoop;
}
else if (t == CFHostGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFHostScheduleWithRunLoop;
}
else if (t == SCNetworkReachabilityGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkReachabilityScheduleWithRunLoop;
}
else if (t == CFRunLoopTimerGetTypeID()) {
src = CFRetain(obj);
fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopAddTimer;
}
else if (t == CFNetServiceGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceScheduleWithRunLoop;
}
else if (t == CFNetServiceBrowserGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceBrowserScheduleWithRunLoop;
}
else if (t == CFNetServiceMonitorGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceMonitorScheduleWithRunLoop;
}
else if (t == SCNetworkConnectionGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkConnectionScheduleWithRunLoop;
}
if (src) {
fn2(runLoop, src, runLoopMode);
CFRelease(src);
}
else if (fn) {
fn(obj, runLoop, runLoopMode);
}
}
void
_CFTypeUnscheduleFromRunLoop(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
CFTypeID t = CFGetTypeID(obj);
CFTypeRef src = NULL;
void(*fn)(CFTypeRef, CFRunLoopRef, CFStringRef);
void(*fn2)(CFRunLoopRef, CFTypeRef, CFStringRef);
fn = NULL;
fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopRemoveSource;
if (t == CFRunLoopSourceGetTypeID()) {
src = CFRetain(obj);
}
else if (t == CFMachPortGetTypeID()) {
src = CFMachPortCreateRunLoopSource(CFGetAllocator(obj), (CFMachPortRef)obj, 0);
}
else if (t == CFSocketGetTypeID()) {
src = CFSocketCreateRunLoopSource(CFGetAllocator(obj), (CFSocketRef)obj, 0);
}
else if (t == CFReadStreamGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFReadStreamUnscheduleFromRunLoop;
}
else if (t == CFWriteStreamGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFWriteStreamUnscheduleFromRunLoop;
}
else if (t == CFHostGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFHostUnscheduleFromRunLoop;
}
else if (t == SCNetworkReachabilityGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkReachabilityUnscheduleFromRunLoop;
}
else if (t == CFRunLoopTimerGetTypeID()) {
src = CFRetain(obj);
fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopRemoveTimer;
}
else if (t == CFNetServiceGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceUnscheduleFromRunLoop;
}
else if (t == CFNetServiceBrowserGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceBrowserUnscheduleFromRunLoop;
}
else if (t == CFNetServiceMonitorGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceMonitorUnscheduleFromRunLoop;
}
else if (t == SCNetworkConnectionGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkConnectionUnscheduleFromRunLoop;
}
if (src) {
fn2(runLoop, src, runLoopMode);
CFRelease(src);
}
else if (fn) {
fn(obj, runLoop, runLoopMode);
}
}
void
_CFTypeScheduleOnMultipleRunLoops(CFTypeRef obj, CFArrayRef schedules) {
CFTypeID t = CFGetTypeID(obj);
CFTypeRef src = NULL;
void(*fn)(CFTypeRef, CFRunLoopRef, CFStringRef);
void(*fn2)(CFRunLoopRef, CFTypeRef, CFStringRef);
fn = NULL;
fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopAddSource;
if (t == CFRunLoopSourceGetTypeID()) {
src = CFRetain(obj);
}
else if (t == CFRunLoopTimerGetTypeID()) {
src = CFRetain(obj);
fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopAddTimer;
}
else if (t == CFMachPortGetTypeID()) {
src = CFMachPortCreateRunLoopSource(CFGetAllocator(obj), (CFMachPortRef)obj, 0);
}
else if (t == CFSocketGetTypeID()) {
src = CFSocketCreateRunLoopSource(CFGetAllocator(obj), (CFSocketRef)obj, 0);
}
else if (t == CFReadStreamGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFReadStreamScheduleWithRunLoop;
}
else if (t == CFWriteStreamGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFWriteStreamScheduleWithRunLoop;
}
else if (t == CFHostGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFHostScheduleWithRunLoop;
}
else if (t == CFNetServiceGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceScheduleWithRunLoop;
}
else if (t == CFNetServiceBrowserGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceBrowserScheduleWithRunLoop;
}
else if (t == CFNetServiceMonitorGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceMonitorScheduleWithRunLoop;
}
else if (t == SCNetworkReachabilityGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkReachabilityScheduleWithRunLoop;
}
else if (t == SCNetworkConnectionGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkConnectionScheduleWithRunLoop;
}
if (src) {
CFIndex i, length = CFArrayGetCount(schedules);
for (i = 0; i < length; i += 2) {
fn2((CFRunLoopRef)CFArrayGetValueAtIndex(schedules, i),
src,
(CFStringRef)CFArrayGetValueAtIndex(schedules, i + 1));
}
CFRelease(src);
}
else if (fn) {
CFIndex i, length = CFArrayGetCount(schedules);
for (i = 0; i < length; i += 2) {
fn(obj,
(CFRunLoopRef)CFArrayGetValueAtIndex(schedules, i),
(CFStringRef)CFArrayGetValueAtIndex(schedules, i + 1));
}
}
}
void
_CFTypeUnscheduleFromMultipleRunLoops(CFTypeRef obj, CFArrayRef schedules) {
CFTypeID t = CFGetTypeID(obj);
CFTypeRef src = NULL;
void(*fn)(CFTypeRef, CFRunLoopRef, CFStringRef);
void(*fn2)(CFRunLoopRef, CFTypeRef, CFStringRef);
fn = NULL;
fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopRemoveSource;
if (t == CFRunLoopSourceGetTypeID()) {
src = CFRetain(obj);
}
else if (t == CFMachPortGetTypeID()) {
src = CFMachPortCreateRunLoopSource(CFGetAllocator(obj), (CFMachPortRef)obj, 0);
}
else if (t == CFSocketGetTypeID()) {
src = CFSocketCreateRunLoopSource(CFGetAllocator(obj), (CFSocketRef)obj, 0);
}
else if (t == CFReadStreamGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFReadStreamUnscheduleFromRunLoop;
}
else if (t == CFWriteStreamGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFWriteStreamUnscheduleFromRunLoop;
}
else if (t == CFHostGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFHostUnscheduleFromRunLoop;
}
else if (t == SCNetworkReachabilityGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkReachabilityUnscheduleFromRunLoop;
}
else if (t == CFRunLoopTimerGetTypeID()) {
src = CFRetain(obj);
fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopRemoveTimer;
}
else if (t == CFNetServiceGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceUnscheduleFromRunLoop;
}
else if (t == CFNetServiceBrowserGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceBrowserUnscheduleFromRunLoop;
}
else if (t == CFNetServiceMonitorGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceMonitorUnscheduleFromRunLoop;
}
else if (t == SCNetworkConnectionGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkConnectionUnscheduleFromRunLoop;
}
if (src) {
CFIndex i, length = CFArrayGetCount(schedules);
for (i = 0; i < length; i += 2) {
fn2((CFRunLoopRef)CFArrayGetValueAtIndex(schedules, i),
src,
(CFStringRef)CFArrayGetValueAtIndex(schedules, i + 1));
}
CFRelease(src);
}
else if (fn) {
CFIndex i, length = CFArrayGetCount(schedules);
for (i = 0; i < length; i += 2) {
fn(obj,
(CFRunLoopRef)CFArrayGetValueAtIndex(schedules, i),
(CFStringRef)CFArrayGetValueAtIndex(schedules, i + 1));
}
}
}
void
_CFTypeInvalidate(CFTypeRef obj) {
CFTypeID t = CFGetTypeID(obj);
if (t == CFRunLoopSourceGetTypeID()) {
CFRunLoopSourceInvalidate((CFRunLoopSourceRef)obj);
}
else if (t == CFMachPortGetTypeID()) {
CFMachPortInvalidate((CFMachPortRef)obj);
}
else if (t == CFSocketGetTypeID()) {
CFSocketInvalidate((CFSocketRef)obj);
}
else if (t == CFReadStreamGetTypeID()) {
CFReadStreamSetClient((CFReadStreamRef)obj, kCFStreamEventNone, NULL, NULL);
}
else if (t == CFWriteStreamGetTypeID()) {
CFWriteStreamSetClient((CFWriteStreamRef)obj, kCFStreamEventNone, NULL, NULL);
}
else if (t == CFHostGetTypeID()) {
CFHostSetClient((CFHostRef)obj, NULL, NULL);
}
else if (t == SCNetworkReachabilityGetTypeID()) {
SCNetworkReachabilitySetCallback((SCNetworkReachabilityRef)obj, NULL, NULL);
}
else if (t == CFRunLoopTimerGetTypeID()) {
CFRunLoopTimerInvalidate((CFRunLoopTimerRef)obj);
}
else if (t == CFNetServiceGetTypeID()) {
CFNetServiceSetClient((CFNetServiceRef)obj, NULL, NULL);
}
else if (t == CFNetServiceBrowserGetTypeID()) {
CFNetServiceBrowserInvalidate((CFNetServiceBrowserRef)obj);
}
else if (t == CFNetServiceMonitorGetTypeID()) {
CFNetServiceMonitorInvalidate((CFNetServiceMonitorRef)obj);
}
else if (t == SCNetworkReachabilityGetTypeID()) {
SCNetworkConnectionStop((SCNetworkConnectionRef)obj, FALSE);
}
}
Boolean
_SchedulesAddRunLoopAndMode(CFMutableArrayRef schedules, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
CFIndex count = CFArrayGetCount(schedules);
CFRange range = CFRangeMake(0, count);
while (range.length) {
CFIndex i = CFArrayGetFirstIndexOfValue(schedules, range, runLoop);
if (i == kCFNotFound)
break;
if (CFEqual(CFArrayGetValueAtIndex(schedules, i + 1), runLoopMode)) {
return FALSE;
}
range.location = i + 2;
range.length = count - range.location;
}
CFArrayAppendValue(schedules, runLoop);
CFArrayAppendValue(schedules, runLoopMode);
return TRUE;
}
Boolean
_SchedulesRemoveRunLoopAndMode(CFMutableArrayRef schedules, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
CFIndex count = CFArrayGetCount(schedules);
CFRange range = CFRangeMake(0, count);
while (range.length) {
CFIndex i = CFArrayGetFirstIndexOfValue(schedules, range, runLoop);
if (i == kCFNotFound)
break;
if (CFEqual(CFArrayGetValueAtIndex(schedules, i + 1), runLoopMode)) {
range.location = i;
range.length = 2;
CFArrayReplaceValues(schedules, range, NULL, 0);
return TRUE;
}
range.location = i + 2;
range.length = count - range.location;
}
return FALSE;
}
CFIndex
_SchedulesFind(CFArrayRef schedules, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
CFIndex count = CFArrayGetCount(schedules);
CFRange range = CFRangeMake(0, count);
while (range.length) {
CFIndex i = CFArrayGetFirstIndexOfValue(schedules, range, runLoop);
if (i == kCFNotFound)
break;
if (CFEqual(CFArrayGetValueAtIndex(schedules, i + 1), runLoopMode))
return i;
range.location = i + 2;
range.length = count - range.location;
}
return kCFNotFound;
}