]> git.saurik.com Git - apple/cf.git/blobdiff - CFRunLoop.c
CF-476.10.tar.gz
[apple/cf.git] / CFRunLoop.c
diff --git a/CFRunLoop.c b/CFRunLoop.c
new file mode 100644 (file)
index 0000000..5eed260
--- /dev/null
@@ -0,0 +1,2934 @@
+/*
+ * Copyright (c) 2008 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*     CFRunLoop.c
+       Copyright 1998-2002, Apple, Inc. All rights reserved.
+       Responsibility: Christopher Kane
+*/
+
+#if (DEPLOYMENT_TARGET_MACOSX) || defined(__WIN32__)
+
+#include <CoreFoundation/CFRunLoop.h>
+#include <CoreFoundation/CFSet.h>
+#include <CoreFoundation/CFBag.h>
+#include "CFInternal.h"
+#include <math.h>
+#include <stdio.h>
+#include <limits.h>
+#if DEPLOYMENT_TARGET_MACOSX
+#include <mach/mach.h>
+#include <mach/clock_types.h>
+#include <mach/clock.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#else
+#if !defined(__MINGW32__) && !defined(__CYGWIN__)
+// With the MS headers, turning off Standard-C gets you macros for stat vs _stat.
+// Strictly speaking, this is supposed to control traditional vs ANSI C features.
+#undef __STDC__
+#endif
+#include <windows.h>
+#include <pthread.h>
+#include <process.h>
+#if !defined(__MINGW32__) && !defined(__CYGWIN__)
+#define __STDC__
+#endif
+#endif
+
+static int _LogCFRunLoop = 0;
+
+#if 0 || 0
+static pthread_t kNilPthreadT = { nil, nil };
+#define pthreadPointer(a) a.p
+#define lockCount(a) a.LockCount
+#else
+static pthread_t kNilPthreadT = (pthread_t)0;
+#define pthreadPointer(a) a
+#define lockCount(a) a
+#endif
+
+
+#if DEPLOYMENT_TARGET_MACOSX
+#include <sys/types.h>
+#include <sys/event.h>
+
+typedef struct {
+    CFIndex    version;
+    void *     info;
+    const void *(*retain)(const void *info);
+    void       (*release)(const void *info);
+    CFStringRef        (*copyDescription)(const void *info);
+    Boolean    (*equal)(const void *info1, const void *info2);
+    CFHashCode (*hash)(const void *info);
+    void       (*perform)(const struct kevent *kev, void *info);
+    struct kevent event;
+} CFRunLoopSourceContext2;
+
+// The bits in the flags field in the kevent structure are cleared except for EV_ONESHOT and EV_CLEAR.
+// Do not use the udata field of the kevent structure -- that field is smashed by CFRunLoop.
+// There is no way to EV_ENABLE or EV_DISABLE a kevent.
+// The "autoinvalidation" of EV_ONESHOT is not handled properly by CFRunLoop yet.
+// The "autoinvalidation" of EV_DELETE on the last close of a file descriptor is not handled properly by CFRunLoop yet.
+// There is no way to reset the state in a kevent (such as clearing the EV_EOF state for fifos).
+#endif
+
+extern bool CFDictionaryGetKeyIfPresent(CFDictionaryRef dict, const void *key, const void **actualkey);
+
+// In order to reuse most of the code across Mach and Windows v1 RunLoopSources, we define a
+// simple abstraction layer spanning Mach ports and Windows HANDLES
+#if DEPLOYMENT_TARGET_MACOSX
+
+typedef mach_port_t __CFPort;
+#define CFPORT_NULL MACH_PORT_NULL
+typedef mach_port_t __CFPortSet;
+
+static __CFPort __CFPortAllocate(void) {
+    __CFPort result;
+    kern_return_t ret;
+    ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &result);
+    if (KERN_SUCCESS == ret) {
+        ret = mach_port_insert_right(mach_task_self(), result, result, MACH_MSG_TYPE_MAKE_SEND);
+    }
+    if (KERN_SUCCESS == ret) {
+        mach_port_limits_t limits;
+        limits.mpl_qlimit = 1;
+        ret = mach_port_set_attributes(mach_task_self(), result, MACH_PORT_LIMITS_INFO, (mach_port_info_t)&limits, MACH_PORT_LIMITS_INFO_COUNT);
+    }
+    return (KERN_SUCCESS == ret) ? result : CFPORT_NULL;
+}
+
+CF_INLINE void __CFPortFree(__CFPort port) {
+    mach_port_destroy(mach_task_self(), port);
+}
+
+CF_INLINE __CFPortSet __CFPortSetAllocate(void) {
+    __CFPortSet result;
+    kern_return_t ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &result);
+    return (KERN_SUCCESS == ret) ? result : CFPORT_NULL;
+}
+
+CF_INLINE Boolean __CFPortSetInsert(__CFPort port, __CFPortSet portSet) {
+    kern_return_t ret = mach_port_insert_member(mach_task_self(), port, portSet);
+    return (KERN_SUCCESS == ret);
+}
+
+CF_INLINE Boolean __CFPortSetRemove(__CFPort port, __CFPortSet portSet) {
+    kern_return_t ret = mach_port_extract_member(mach_task_self(), port, portSet);
+    return (KERN_SUCCESS == ret);
+}
+
+CF_INLINE void __CFPortSetFree(__CFPortSet portSet) {
+    kern_return_t ret;
+    mach_port_name_array_t array;
+    mach_msg_type_number_t idx, number;
+
+    ret = mach_port_get_set_status(mach_task_self(), portSet, &array, &number);
+    if (KERN_SUCCESS == ret) {
+        for (idx = 0; idx < number; idx++) {
+            mach_port_extract_member(mach_task_self(), array[idx], portSet);
+        }
+        vm_deallocate(mach_task_self(), (vm_address_t)array, number * sizeof(mach_port_name_t));
+    }
+    mach_port_destroy(mach_task_self(), portSet);
+}
+
+#elif defined(__WIN32__)
+
+typedef HANDLE __CFPort;
+#define CFPORT_NULL NULL
+
+// A simple dynamic array of HANDLEs, which grows to a high-water mark
+typedef struct ___CFPortSet {
+    uint16_t   used;
+    uint16_t   size;
+    HANDLE     *handles;
+    CFSpinLock_t lock;         // insert and remove must be thread safe, like the Mach calls
+} *__CFPortSet;
+
+CF_INLINE __CFPort __CFPortAllocate(void) {
+    return CreateEvent(NULL, true, false, NULL);
+}
+
+CF_INLINE void __CFPortFree(__CFPort port) {
+    CloseHandle(port);
+}
+
+static __CFPortSet __CFPortSetAllocate(void) {
+    __CFPortSet result = CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(struct ___CFPortSet), 0);
+    result->used = 0;
+    result->size = 4;
+    result->handles = CFAllocatorAllocate(kCFAllocatorSystemDefault, result->size * sizeof(HANDLE), 0);
+    CF_SPINLOCK_INIT_FOR_STRUCTS(result->lock);
+    return result;
+}
+
+static void __CFPortSetFree(__CFPortSet portSet) {
+    CFAllocatorDeallocate(kCFAllocatorSystemDefault, portSet->handles);
+    CFAllocatorDeallocate(kCFAllocatorSystemDefault, portSet);
+}
+
+// Returns portBuf if ports fit in that space, else returns another ptr that must be freed
+static __CFPort *__CFPortSetGetPorts(__CFPortSet portSet, __CFPort *portBuf, uint32_t bufSize, uint32_t *portsUsed) {
+    __CFSpinLock(&(portSet->lock));
+    __CFPort *result = portBuf;
+    if (bufSize > portSet->used)
+        result = CFAllocatorAllocate(kCFAllocatorSystemDefault, portSet->used * sizeof(HANDLE), 0);
+    memmove(result, portSet->handles, portSet->used * sizeof(HANDLE));
+    *portsUsed = portSet->used;
+    __CFSpinUnlock(&(portSet->lock));
+    return result;
+}
+
+static Boolean __CFPortSetInsert(__CFPort port, __CFPortSet portSet) {
+    __CFSpinLock(&(portSet->lock));
+    if (portSet->used >= portSet->size) {
+        portSet->size += 4;
+        portSet->handles = CFAllocatorReallocate(kCFAllocatorSystemDefault, portSet->handles, portSet->size * sizeof(HANDLE), 0);
+    }
+    if (portSet->used >= MAXIMUM_WAIT_OBJECTS)
+        CFLog(kCFLogLevelWarning, CFSTR("*** More than MAXIMUM_WAIT_OBJECTS (%d) ports add to a port set.  The last ones will be ignored."), MAXIMUM_WAIT_OBJECTS);
+    portSet->handles[portSet->used++] = port;
+    __CFSpinUnlock(&(portSet->lock));
+    return true;
+}
+
+static Boolean __CFPortSetRemove(__CFPort port, __CFPortSet portSet) {
+    int i, j;
+    __CFSpinLock(&(portSet->lock));
+    for (i = 0; i < portSet->used; i++) {
+        if (portSet->handles[i] == port) {
+            for (j = i+1; j < portSet->used; j++) {
+                portSet->handles[j-1] = portSet->handles[j];
+            }
+            portSet->used--;
+            __CFSpinUnlock(&(portSet->lock));
+            return true;
+        }
+    }
+    __CFSpinUnlock(&(portSet->lock));
+    return false;
+}
+
+#endif
+
+#if DEPLOYMENT_TARGET_MACOSX
+extern mach_port_name_t mk_timer_create(void);
+extern kern_return_t mk_timer_destroy(mach_port_name_t name);
+extern kern_return_t mk_timer_arm(mach_port_name_t name, AbsoluteTime expire_time);
+extern kern_return_t mk_timer_cancel(mach_port_name_t name, AbsoluteTime *result_time);
+
+CF_INLINE AbsoluteTime __CFUInt64ToAbsoluteTime(int64_t x) {
+    AbsoluteTime a;
+    a.hi = x >> 32;
+    a.lo = x & (int64_t)0xFFFFFFFF;
+    return a;
+}
+
+static uint32_t __CFSendTrivialMachMessage(mach_port_t port, uint32_t msg_id, CFOptionFlags options, uint32_t timeout) {
+    kern_return_t result;
+    mach_msg_header_t header;
+    header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
+    header.msgh_size = sizeof(mach_msg_header_t);
+    header.msgh_remote_port = port;
+    header.msgh_local_port = MACH_PORT_NULL;
+    header.msgh_id = msg_id;
+    result = mach_msg(&header, MACH_SEND_MSG|options, header.msgh_size, 0, MACH_PORT_NULL, timeout, MACH_PORT_NULL);
+    if (result == MACH_SEND_TIMED_OUT) mach_msg_destroy(&header);
+    return result;
+}
+#endif
+
+/* unlock a run loop and modes before doing callouts/sleeping */
+/* never try to take the run loop lock with a mode locked */
+/* be very careful of common subexpression elimination and compacting code, particular across locks and unlocks! */
+/* run loop mode structures should never be deallocated, even if they become empty */
+
+static CFTypeID __kCFRunLoopModeTypeID = _kCFRuntimeNotATypeID;
+static CFTypeID __kCFRunLoopTypeID = _kCFRuntimeNotATypeID;
+static CFTypeID __kCFRunLoopSourceTypeID = _kCFRuntimeNotATypeID;
+static CFTypeID __kCFRunLoopObserverTypeID = _kCFRuntimeNotATypeID;
+static CFTypeID __kCFRunLoopTimerTypeID = _kCFRuntimeNotATypeID;
+
+typedef struct __CFRunLoopMode *CFRunLoopModeRef;
+
+struct __CFRunLoopMode {
+    CFRuntimeBase _base;
+    CFSpinLock_t _lock;        /* must have the run loop locked before locking this */
+    CFStringRef _name;
+    Boolean _stopped;
+    char _padding[3];
+    CFMutableSetRef _sources;
+    CFMutableSetRef _observers;
+    CFMutableSetRef _timers;
+    CFMutableArrayRef _submodes; // names of the submodes
+    __CFPortSet _portSet;
+#if DEPLOYMENT_TARGET_MACOSX
+    int _kq;
+#endif
+};
+
+static int64_t __CFRunLoopGetNextTimerFireTSR(CFRunLoopRef rl, CFRunLoopModeRef rlm);
+
+CF_INLINE void __CFRunLoopModeLock(CFRunLoopModeRef rlm) {
+    __CFSpinLock(&(rlm->_lock));
+}
+
+CF_INLINE void __CFRunLoopModeUnlock(CFRunLoopModeRef rlm) {
+    __CFSpinUnlock(&(rlm->_lock));
+}
+
+static Boolean __CFRunLoopModeEqual(CFTypeRef cf1, CFTypeRef cf2) {
+    CFRunLoopModeRef rlm1 = (CFRunLoopModeRef)cf1;
+    CFRunLoopModeRef rlm2 = (CFRunLoopModeRef)cf2;
+    return CFEqual(rlm1->_name, rlm2->_name);
+}
+
+static CFHashCode __CFRunLoopModeHash(CFTypeRef cf) {
+    CFRunLoopModeRef rlm = (CFRunLoopModeRef)cf;
+    return CFHash(rlm->_name);
+}
+
+static CFStringRef __CFRunLoopModeCopyDescription(CFTypeRef cf) {
+    CFRunLoopModeRef rlm = (CFRunLoopModeRef)cf;
+    CFMutableStringRef result;
+    result = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
+    CFStringAppendFormat(result, NULL, CFSTR("<CFRunLoopMode %p [%p]>{name = %@, locked = %s, "), rlm, CFGetAllocator(rlm), rlm->_name, lockCount(rlm->_lock) ? "true" : "false");
+    CFStringAppendFormat(result, NULL, CFSTR("port set = %p,"), rlm->_portSet);
+    CFStringAppendFormat(result, NULL, CFSTR("\n\tsources = %@,\n\tobservers == %@,\n\ttimers = %@\n},\n"), rlm->_sources, rlm->_observers, rlm->_timers);
+    return result;
+}
+
+static void __CFRunLoopModeDeallocate(CFTypeRef cf) {
+    CFRunLoopModeRef rlm = (CFRunLoopModeRef)cf;
+    if (NULL != rlm->_sources) CFRelease(rlm->_sources);
+    if (NULL != rlm->_observers) CFRelease(rlm->_observers);
+    if (NULL != rlm->_timers) CFRelease(rlm->_timers);
+    if (NULL != rlm->_submodes) CFRelease(rlm->_submodes);
+    CFRelease(rlm->_name);
+    __CFPortSetFree(rlm->_portSet);
+#if DEPLOYMENT_TARGET_MACOSX
+    if (-1 != rlm->_kq) close(rlm->_kq);
+#endif
+}
+
+struct __CFRunLoop {
+    CFRuntimeBase _base;
+    CFSpinLock_t _lock;                        /* locked for accessing mode list */
+    __CFPort _wakeUpPort;                      // used for CFRunLoopWakeUp 
+    volatile uint32_t *_stopped;
+    CFMutableSetRef _commonModes;
+    CFMutableSetRef _commonModeItems;
+    CFRunLoopModeRef _currentMode;
+    CFMutableSetRef _modes;
+    void *_counterpart;
+};
+
+/* Bit 0 of the base reserved bits is used for stopped state */
+/* Bit 1 of the base reserved bits is used for sleeping state */
+/* Bit 2 of the base reserved bits is used for deallocating state */
+
+CF_INLINE Boolean __CFRunLoopIsStopped(CFRunLoopRef rl) {
+    return (rl->_stopped && rl->_stopped[2]) ? true : false;
+}
+
+CF_INLINE void __CFRunLoopSetStopped(CFRunLoopRef rl) {
+    if (rl->_stopped) rl->_stopped[2] = 0x53544F50;    // 'STOP'
+}
+
+CF_INLINE void __CFRunLoopUnsetStopped(CFRunLoopRef rl) {
+    if (rl->_stopped) rl->_stopped[2] = 0x0;
+}
+
+CF_INLINE Boolean __CFRunLoopIsSleeping(CFRunLoopRef rl) {
+    return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)rl)->_cfinfo[CF_INFO_BITS], 1, 1);
+}
+
+CF_INLINE void __CFRunLoopSetSleeping(CFRunLoopRef rl) {
+    __CFBitfieldSetValue(((CFRuntimeBase *)rl)->_cfinfo[CF_INFO_BITS], 1, 1, 1);
+}
+
+CF_INLINE void __CFRunLoopUnsetSleeping(CFRunLoopRef rl) {
+    __CFBitfieldSetValue(((CFRuntimeBase *)rl)->_cfinfo[CF_INFO_BITS], 1, 1, 0);
+}
+
+CF_INLINE Boolean __CFRunLoopIsDeallocating(CFRunLoopRef rl) {
+    return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)rl)->_cfinfo[CF_INFO_BITS], 2, 2);
+}
+
+CF_INLINE void __CFRunLoopSetDeallocating(CFRunLoopRef rl) {
+    __CFBitfieldSetValue(((CFRuntimeBase *)rl)->_cfinfo[CF_INFO_BITS], 2, 2, 1);
+}
+
+CF_INLINE void __CFRunLoopLock(CFRunLoopRef rl) {
+    __CFSpinLock(&(((CFRunLoopRef)rl)->_lock));
+}
+
+CF_INLINE void __CFRunLoopUnlock(CFRunLoopRef rl) {
+    __CFSpinUnlock(&(((CFRunLoopRef)rl)->_lock));
+}
+
+static CFStringRef __CFRunLoopCopyDescription(CFTypeRef cf) {
+    CFRunLoopRef rl = (CFRunLoopRef)cf;
+    CFMutableStringRef result;
+    result = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
+    CFStringAppendFormat(result, NULL, CFSTR("<CFRunLoop %p [%p]>{locked = %s, wait port = 0x%x, stopped = %s,\ncurrent mode = %@,\n"), cf, CFGetAllocator(cf), lockCount(rl->_lock) ? "true" : "false", rl->_wakeUpPort, (rl->_stopped && (rl->_stopped[2] == 0x53544F50)) ? "true" : "false", rl->_currentMode ? rl->_currentMode->_name : CFSTR("(none)"));
+    CFStringAppendFormat(result, NULL, CFSTR("common modes = %@,\ncommon mode items = %@,\nmodes = %@}\n"), rl->_commonModes, rl->_commonModeItems, rl->_modes);
+    return result;
+}
+
+/* call with rl locked */
+static CFRunLoopModeRef __CFRunLoopFindMode(CFRunLoopRef rl, CFStringRef modeName, Boolean create) {
+    CHECK_FOR_FORK();
+    CFRunLoopModeRef rlm;
+    struct __CFRunLoopMode srlm;
+    srlm._base._cfisa = __CFISAForTypeID(__kCFRunLoopModeTypeID);
+    srlm._base._cfinfo[CF_INFO_BITS] = 0;
+    _CFRuntimeSetInstanceTypeID(&srlm, __kCFRunLoopModeTypeID);
+    srlm._name = modeName;
+    rlm = (CFRunLoopModeRef)CFSetGetValue(rl->_modes, &srlm);
+    if (NULL != rlm) {
+       __CFRunLoopModeLock(rlm);
+       return rlm;
+    }
+    if (!create) {
+       return NULL;
+    }
+    rlm = (CFRunLoopModeRef)_CFRuntimeCreateInstance(CFGetAllocator(rl), __kCFRunLoopModeTypeID, sizeof(struct __CFRunLoopMode) - sizeof(CFRuntimeBase), NULL);
+    if (NULL == rlm) {
+       return NULL;
+    }
+    CF_SPINLOCK_INIT_FOR_STRUCTS(rlm->_lock);
+    rlm->_name = CFStringCreateCopy(CFGetAllocator(rlm), modeName);
+    rlm->_stopped = false;
+    rlm->_sources = NULL;
+    rlm->_observers = NULL;
+    rlm->_timers = NULL;
+    rlm->_submodes = NULL;
+    rlm->_portSet = __CFPortSetAllocate();
+    if (CFPORT_NULL == rlm->_portSet) HALT;
+    if (!__CFPortSetInsert(rl->_wakeUpPort, rlm->_portSet)) HALT;
+#if DEPLOYMENT_TARGET_MACOSX
+    rlm->_kq = -1;
+#endif
+    CFSetAddValue(rl->_modes, rlm);
+    CFRelease(rlm);
+    __CFRunLoopModeLock(rlm);  /* return mode locked */
+    return rlm;
+}
+
+
+// expects rl and rlm locked
+static Boolean __CFRunLoopModeIsEmpty(CFRunLoopRef rl, CFRunLoopModeRef rlm) {
+    CHECK_FOR_FORK();
+    if (NULL == rlm) return true;
+    if (NULL != rlm->_sources && 0 < CFSetGetCount(rlm->_sources)) return false;
+    if (NULL != rlm->_timers && 0 < CFSetGetCount(rlm->_timers)) return false;
+    if (NULL != rlm->_submodes) {
+       CFIndex idx, cnt;
+       for (idx = 0, cnt = CFArrayGetCount(rlm->_submodes); idx < cnt; idx++) {
+           CFStringRef modeName = (CFStringRef)CFArrayGetValueAtIndex(rlm->_submodes, idx);
+           CFRunLoopModeRef subrlm;
+           Boolean subIsEmpty;
+           subrlm = __CFRunLoopFindMode(rl, modeName, false);
+           subIsEmpty = (NULL != subrlm) ? __CFRunLoopModeIsEmpty(rl, subrlm) : true;
+           if (NULL != subrlm) __CFRunLoopModeUnlock(subrlm);
+           if (!subIsEmpty) return false;
+       }
+    }
+    return true;
+}
+
+/* Bit 3 in the base reserved bits is used for invalid state in run loop objects */
+
+CF_INLINE Boolean __CFIsValid(const void *cf) {
+    return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 3, 3);
+}
+
+CF_INLINE void __CFSetValid(void *cf) {
+    __CFBitfieldSetValue(((CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 3, 3, 1);
+}
+
+CF_INLINE void __CFUnsetValid(void *cf) {
+    __CFBitfieldSetValue(((CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 3, 3, 0);
+}
+
+struct __CFRunLoopSource {
+    CFRuntimeBase _base;
+    uint32_t _bits;
+    CFSpinLock_t _lock;
+    CFIndex _order;                    /* immutable */
+    CFMutableBagRef _runLoops;
+    union {
+       CFRunLoopSourceContext version0;        /* immutable, except invalidation */
+        CFRunLoopSourceContext1 version1;      /* immutable, except invalidation */
+    } _context;
+};
+
+/* Bit 1 of the base reserved bits is used for signalled state */
+
+CF_INLINE Boolean __CFRunLoopSourceIsSignaled(CFRunLoopSourceRef rls) {
+    return (Boolean)__CFBitfieldGetValue(rls->_bits, 1, 1);
+}
+
+CF_INLINE void __CFRunLoopSourceSetSignaled(CFRunLoopSourceRef rls) {
+    __CFBitfieldSetValue(rls->_bits, 1, 1, 1);
+}
+
+CF_INLINE void __CFRunLoopSourceUnsetSignaled(CFRunLoopSourceRef rls) {
+    __CFBitfieldSetValue(rls->_bits, 1, 1, 0);
+}
+
+CF_INLINE void __CFRunLoopSourceLock(CFRunLoopSourceRef rls) {
+    __CFSpinLock(&(rls->_lock));
+}
+
+CF_INLINE void __CFRunLoopSourceUnlock(CFRunLoopSourceRef rls) {
+    __CFSpinUnlock(&(rls->_lock));
+}
+
+/* rlm is not locked */
+static void __CFRunLoopSourceSchedule(CFRunLoopSourceRef rls, CFRunLoopRef rl, CFRunLoopModeRef rlm) { /* DOES CALLOUT */
+    __CFRunLoopSourceLock(rls);
+    if (NULL == rls->_runLoops) {
+       rls->_runLoops = CFBagCreateMutable(CFGetAllocator(rls), 0, NULL);
+    }
+    CFBagAddValue(rls->_runLoops, rl);
+    __CFRunLoopSourceUnlock(rls);      // have to unlock before the callout -- cannot help clients with safety
+    if (0 == rls->_context.version0.version) {
+       if (NULL != rls->_context.version0.schedule) {
+           rls->_context.version0.schedule(rls->_context.version0.info, rl, rlm->_name);
+       }
+    } else if (1 == rls->_context.version0.version) {
+        __CFPort port = rls->_context.version1.getPort(rls->_context.version1.info);   /* CALLOUT */
+       if (CFPORT_NULL != port) {
+            __CFPortSetInsert(port, rlm->_portSet);
+       }
+    }
+}
+
+/* rlm is not locked */
+static void __CFRunLoopSourceCancel(CFRunLoopSourceRef rls, CFRunLoopRef rl, CFRunLoopModeRef rlm) {   /* DOES CALLOUT */
+    if (0 == rls->_context.version0.version) {
+       if (NULL != rls->_context.version0.cancel) {
+           rls->_context.version0.cancel(rls->_context.version0.info, rl, rlm->_name); /* CALLOUT */
+       }
+    } else if (1 == rls->_context.version0.version) {
+        __CFPort port = rls->_context.version1.getPort(rls->_context.version1.info);   /* CALLOUT */
+        if (CFPORT_NULL != port) {
+            __CFPortSetRemove(port, rlm->_portSet);
+       }
+    }
+    __CFRunLoopSourceLock(rls);
+    if (NULL != rls->_runLoops) {
+        CFBagRemoveValue(rls->_runLoops, rl);
+    }
+    __CFRunLoopSourceUnlock(rls);
+}
+
+struct __CFRunLoopObserver {
+    CFRuntimeBase _base;
+    CFSpinLock_t _lock;
+    CFRunLoopRef _runLoop;
+    CFIndex _rlCount;
+    CFOptionFlags _activities;         /* immutable */
+    CFIndex _order;                    /* immutable */
+    CFRunLoopObserverCallBack _callout;        /* immutable */
+    CFRunLoopObserverContext _context; /* immutable, except invalidation */
+};
+
+/* Bit 0 of the base reserved bits is used for firing state */
+/* Bit 1 of the base reserved bits is used for repeats state */
+
+CF_INLINE Boolean __CFRunLoopObserverIsFiring(CFRunLoopObserverRef rlo) {
+    return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)rlo)->_cfinfo[CF_INFO_BITS], 0, 0);
+}
+
+CF_INLINE void __CFRunLoopObserverSetFiring(CFRunLoopObserverRef rlo) {
+    __CFBitfieldSetValue(((CFRuntimeBase *)rlo)->_cfinfo[CF_INFO_BITS], 0, 0, 1);
+}
+
+CF_INLINE void __CFRunLoopObserverUnsetFiring(CFRunLoopObserverRef rlo) {
+    __CFBitfieldSetValue(((CFRuntimeBase *)rlo)->_cfinfo[CF_INFO_BITS], 0, 0, 0);
+}
+
+CF_INLINE Boolean __CFRunLoopObserverRepeats(CFRunLoopObserverRef rlo) {
+    return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)rlo)->_cfinfo[CF_INFO_BITS], 1, 1);
+}
+
+CF_INLINE void __CFRunLoopObserverSetRepeats(CFRunLoopObserverRef rlo) {
+    __CFBitfieldSetValue(((CFRuntimeBase *)rlo)->_cfinfo[CF_INFO_BITS], 1, 1, 1);
+}
+
+CF_INLINE void __CFRunLoopObserverUnsetRepeats(CFRunLoopObserverRef rlo) {
+    __CFBitfieldSetValue(((CFRuntimeBase *)rlo)->_cfinfo[CF_INFO_BITS], 1, 1, 0);
+}
+
+CF_INLINE void __CFRunLoopObserverLock(CFRunLoopObserverRef rlo) {
+    __CFSpinLock(&(rlo->_lock));
+}
+
+CF_INLINE void __CFRunLoopObserverUnlock(CFRunLoopObserverRef rlo) {
+    __CFSpinUnlock(&(rlo->_lock));
+}
+
+static void __CFRunLoopObserverSchedule(CFRunLoopObserverRef rlo, CFRunLoopRef rl, CFRunLoopModeRef rlm) {
+    __CFRunLoopObserverLock(rlo);
+    if (0 == rlo->_rlCount) {
+       rlo->_runLoop = rl;
+    }
+    rlo->_rlCount++;
+    __CFRunLoopObserverUnlock(rlo);
+}
+
+static void __CFRunLoopObserverCancel(CFRunLoopObserverRef rlo, CFRunLoopRef rl, CFRunLoopModeRef rlm) {
+    __CFRunLoopObserverLock(rlo);
+    rlo->_rlCount--;
+    if (0 == rlo->_rlCount) {
+       rlo->_runLoop = NULL;
+    }
+    __CFRunLoopObserverUnlock(rlo);
+}
+
+struct __CFRunLoopTimer {
+    CFRuntimeBase _base;
+    CFSpinLock_t _lock;
+    CFRunLoopRef _runLoop;
+    CFIndex _rlCount;
+#if DEPLOYMENT_TARGET_MACOSX
+    mach_port_name_t _port;
+#endif
+    CFIndex _order;                    /* immutable */
+    int64_t _fireTSR;                  /* TSR units */
+    int64_t _intervalTSR;              /* immutable; 0 means non-repeating; TSR units */
+    CFRunLoopTimerCallBack _callout;   /* immutable */
+    CFRunLoopTimerContext _context;    /* immutable, except invalidation */
+};
+
+/* Bit 0 of the base reserved bits is used for firing state */
+/* Bit 1 of the base reserved bits is used for fired-during-callout state */
+
+CF_INLINE Boolean __CFRunLoopTimerIsFiring(CFRunLoopTimerRef rlt) {
+    return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)rlt)->_cfinfo[CF_INFO_BITS], 0, 0);
+}
+
+CF_INLINE void __CFRunLoopTimerSetFiring(CFRunLoopTimerRef rlt) {
+    __CFBitfieldSetValue(((CFRuntimeBase *)rlt)->_cfinfo[CF_INFO_BITS], 0, 0, 1);
+}
+
+CF_INLINE void __CFRunLoopTimerUnsetFiring(CFRunLoopTimerRef rlt) {
+    __CFBitfieldSetValue(((CFRuntimeBase *)rlt)->_cfinfo[CF_INFO_BITS], 0, 0, 0);
+}
+
+CF_INLINE Boolean __CFRunLoopTimerDidFire(CFRunLoopTimerRef rlt) {
+    return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)rlt)->_cfinfo[CF_INFO_BITS], 1, 1);
+}
+
+CF_INLINE void __CFRunLoopTimerSetDidFire(CFRunLoopTimerRef rlt) {
+    __CFBitfieldSetValue(((CFRuntimeBase *)rlt)->_cfinfo[CF_INFO_BITS], 1, 1, 1);
+}
+
+CF_INLINE void __CFRunLoopTimerUnsetDidFire(CFRunLoopTimerRef rlt) {
+    __CFBitfieldSetValue(((CFRuntimeBase *)rlt)->_cfinfo[CF_INFO_BITS], 1, 1, 0);
+}
+
+CF_INLINE void __CFRunLoopTimerLock(CFRunLoopTimerRef rlt) {
+    __CFSpinLock(&(rlt->_lock));
+}
+
+CF_INLINE void __CFRunLoopTimerUnlock(CFRunLoopTimerRef rlt) {
+    __CFSpinUnlock(&(rlt->_lock));
+}
+
+static CFSpinLock_t __CFRLTFireTSRLock = CFSpinLockInit;
+
+CF_INLINE void __CFRunLoopTimerFireTSRLock(void) {
+    __CFSpinLock(&__CFRLTFireTSRLock);
+}
+
+CF_INLINE void __CFRunLoopTimerFireTSRUnlock(void) {
+    __CFSpinUnlock(&__CFRLTFireTSRLock);
+}
+
+#if DEPLOYMENT_TARGET_MACOSX
+static CFMutableDictionaryRef __CFRLTPortMap = NULL;
+static CFSpinLock_t __CFRLTPortMapLock = CFSpinLockInit;
+
+CF_INLINE void __CFRunLoopTimerPortMapLock(void) {
+    __CFSpinLock(&__CFRLTPortMapLock);
+}
+
+CF_INLINE void __CFRunLoopTimerPortMapUnlock(void) {
+    __CFSpinUnlock(&__CFRLTPortMapLock);
+}
+#endif
+
+static void __CFRunLoopTimerSchedule(CFRunLoopTimerRef rlt, CFRunLoopRef rl, CFRunLoopModeRef rlm) {
+#if DEPLOYMENT_TARGET_MACOSX
+    __CFRunLoopTimerLock(rlt);
+    if (0 == rlt->_rlCount) {
+       rlt->_runLoop = rl;
+       if (MACH_PORT_NULL == rlt->_port) {
+           rlt->_port = mk_timer_create();
+       }
+       __CFRunLoopTimerPortMapLock();
+       if (NULL == __CFRLTPortMap) {
+           __CFRLTPortMap = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, NULL);
+       }
+       CFDictionarySetValue(__CFRLTPortMap, (void *)(uintptr_t)rlt->_port, rlt);
+       __CFRunLoopTimerPortMapUnlock();
+    }
+    rlt->_rlCount++;
+    mach_port_insert_member(mach_task_self(), rlt->_port, rlm->_portSet);
+    mk_timer_arm(rlt->_port, __CFUInt64ToAbsoluteTime(rlt->_fireTSR));
+    __CFRunLoopTimerUnlock(rlt);
+#endif
+}
+
+static void __CFRunLoopTimerCancel(CFRunLoopTimerRef rlt, CFRunLoopRef rl, CFRunLoopModeRef rlm) {
+#if DEPLOYMENT_TARGET_MACOSX
+    __CFRunLoopTimerLock(rlt);
+    __CFPortSetRemove(rlt->_port, rlm->_portSet);
+    rlt->_rlCount--;
+    if (0 == rlt->_rlCount) {
+       __CFRunLoopTimerPortMapLock();
+       if (NULL != __CFRLTPortMap) {
+           CFDictionaryRemoveValue(__CFRLTPortMap, (void *)(uintptr_t)rlt->_port);
+       }
+       __CFRunLoopTimerPortMapUnlock();
+       rlt->_runLoop = NULL;
+       mk_timer_cancel(rlt->_port, NULL);
+    }
+    __CFRunLoopTimerUnlock(rlt);
+#endif
+}
+
+// Caller must hold the Timer lock for safety
+static void __CFRunLoopTimerRescheduleWithAllModes(CFRunLoopTimerRef rlt, CFRunLoopRef rl) {
+#if DEPLOYMENT_TARGET_MACOSX
+    mk_timer_arm(rlt->_port, __CFUInt64ToAbsoluteTime(rlt->_fireTSR));
+#endif
+}
+
+/* CFRunLoop */
+
+CONST_STRING_DECL(kCFRunLoopDefaultMode, "kCFRunLoopDefaultMode")
+CONST_STRING_DECL(kCFRunLoopCommonModes, "kCFRunLoopCommonModes")
+
+struct _findsource {
+    __CFPort port;
+    CFRunLoopSourceRef result;
+};
+
+static void __CFRunLoopFindSource(const void *value, void *ctx) {
+    CFRunLoopSourceRef rls = (CFRunLoopSourceRef)value;
+    struct _findsource *context = (struct _findsource *)ctx;
+    __CFPort port;
+    if (NULL != context->result) return;
+    if (1 != rls->_context.version0.version) return;
+    __CFRunLoopSourceLock(rls);
+    port = rls->_context.version1.getPort(rls->_context.version1.info);
+    if (port == context->port) {
+       context->result = rls;
+    }
+    __CFRunLoopSourceUnlock(rls);
+}
+
+// call with rl and rlm locked
+static CFRunLoopSourceRef __CFRunLoopModeFindSourceForMachPort(CFRunLoopRef rl, CFRunLoopModeRef rlm, __CFPort port) { /* DOES CALLOUT */
+    CHECK_FOR_FORK();
+    struct _findsource context = {port, NULL};
+    if (NULL != rlm->_sources) {
+       CFSetApplyFunction(rlm->_sources, (__CFRunLoopFindSource), &context);
+    }
+    if (NULL == context.result && NULL != rlm->_submodes) {
+       CFIndex idx, cnt;
+       for (idx = 0, cnt = CFArrayGetCount(rlm->_submodes); idx < cnt; idx++) {
+           CFRunLoopSourceRef source = NULL;
+           CFStringRef modeName = (CFStringRef)CFArrayGetValueAtIndex(rlm->_submodes, idx);
+           CFRunLoopModeRef subrlm;
+            subrlm = __CFRunLoopFindMode(rl, modeName, false);
+           if (NULL != subrlm) {
+               source = __CFRunLoopModeFindSourceForMachPort(rl, subrlm, port);
+               __CFRunLoopModeUnlock(subrlm);
+           }
+           if (NULL != source) {
+               context.result = source;
+               break;
+           }
+       }
+    }
+    return context.result;
+}
+
+#if DEPLOYMENT_TARGET_MACOSX
+// call with rl and rlm locked
+static CFRunLoopTimerRef __CFRunLoopModeFindTimerForMachPort(CFRunLoopModeRef rlm, __CFPort port) {
+    CHECK_FOR_FORK();
+    CFRunLoopTimerRef result = NULL;
+    __CFRunLoopTimerPortMapLock();
+    if (NULL != __CFRLTPortMap) {
+       result = (CFRunLoopTimerRef)CFDictionaryGetValue(__CFRLTPortMap, (void *)(uintptr_t)port);
+    }
+    __CFRunLoopTimerPortMapUnlock();
+    return result;
+}
+#endif
+
+static void __CFRunLoopDeallocateSources(const void *value, void *context) {
+    CFRunLoopModeRef rlm = (CFRunLoopModeRef)value;
+    CFRunLoopRef rl = (CFRunLoopRef)context;
+    CFIndex idx, cnt;
+    const void **list, *buffer[256];
+    if (NULL == rlm->_sources) return;
+    cnt = CFSetGetCount(rlm->_sources);
+    list = (cnt <= 256) ? buffer : CFAllocatorAllocate(kCFAllocatorSystemDefault, cnt * sizeof(void *), 0);
+    CFSetGetValues(rlm->_sources, list);
+    for (idx = 0; idx < cnt; idx++) {
+       CFRetain(list[idx]);
+    }
+    CFSetRemoveAllValues(rlm->_sources);
+    for (idx = 0; idx < cnt; idx++) {
+       __CFRunLoopSourceCancel((CFRunLoopSourceRef)list[idx], rl, rlm);
+       CFRelease(list[idx]);
+    }
+    if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
+}
+
+static void __CFRunLoopDeallocateObservers(const void *value, void *context) {
+    CFRunLoopModeRef rlm = (CFRunLoopModeRef)value;
+    CFRunLoopRef rl = (CFRunLoopRef)context;
+    CFIndex idx, cnt;
+    const void **list, *buffer[256];
+    if (NULL == rlm->_observers) return;
+    cnt = CFSetGetCount(rlm->_observers);
+    list = (cnt <= 256) ? buffer : CFAllocatorAllocate(kCFAllocatorSystemDefault, cnt * sizeof(void *), 0);
+    CFSetGetValues(rlm->_observers, list);
+    for (idx = 0; idx < cnt; idx++) {
+       CFRetain(list[idx]);
+    }
+    CFSetRemoveAllValues(rlm->_observers);
+    for (idx = 0; idx < cnt; idx++) {
+       __CFRunLoopObserverCancel((CFRunLoopObserverRef)list[idx], rl, rlm);
+       CFRelease(list[idx]);
+    }
+    if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
+}
+
+static void __CFRunLoopDeallocateTimers(const void *value, void *context) {
+    CFRunLoopModeRef rlm = (CFRunLoopModeRef)value;
+    CFRunLoopRef rl = (CFRunLoopRef)context;
+    CFIndex idx, cnt;
+    const void **list, *buffer[256];
+    if (NULL == rlm->_timers) return;
+    cnt = CFSetGetCount(rlm->_timers);
+    list = (cnt <= 256) ? buffer : CFAllocatorAllocate(kCFAllocatorSystemDefault, cnt * sizeof(void *), 0);
+    CFSetGetValues(rlm->_timers, list);
+    for (idx = 0; idx < cnt; idx++) {
+       CFRetain(list[idx]);
+    }
+    CFSetRemoveAllValues(rlm->_timers);
+    for (idx = 0; idx < cnt; idx++) {
+       __CFRunLoopTimerCancel((CFRunLoopTimerRef)list[idx], rl, rlm);
+       CFRelease(list[idx]);
+    }
+    if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
+}
+
+static void __CFRunLoopDeallocate(CFTypeRef cf) {
+    CFRunLoopRef rl = (CFRunLoopRef)cf;
+    /* We try to keep the run loop in a valid state as long as possible,
+       since sources may have non-retained references to the run loop.
+       Another reason is that we don't want to lock the run loop for
+       callback reasons, if we can get away without that.  We start by
+       eliminating the sources, since they are the most likely to call
+       back into the run loop during their "cancellation". Common mode
+       items will be removed from the mode indirectly by the following
+       three lines. */
+    __CFRunLoopSetDeallocating(rl);
+    if (NULL != rl->_modes) {
+       CFSetApplyFunction(rl->_modes, (__CFRunLoopDeallocateSources), rl);
+       CFSetApplyFunction(rl->_modes, (__CFRunLoopDeallocateObservers), rl);
+       CFSetApplyFunction(rl->_modes, (__CFRunLoopDeallocateTimers), rl);
+    }
+    __CFRunLoopLock(rl);
+    if (NULL != rl->_commonModeItems) {
+       CFRelease(rl->_commonModeItems);
+    }
+    if (NULL != rl->_commonModes) {
+       CFRelease(rl->_commonModes);
+    }
+    if (NULL != rl->_modes) {
+       CFRelease(rl->_modes);
+    }
+    __CFPortFree(rl->_wakeUpPort);
+    rl->_wakeUpPort = CFPORT_NULL;
+    __CFRunLoopUnlock(rl);
+}
+
+static const CFRuntimeClass __CFRunLoopModeClass = {
+    0,
+    "CFRunLoopMode",
+    NULL,      // init
+    NULL,      // copy
+    __CFRunLoopModeDeallocate,
+    __CFRunLoopModeEqual,
+    __CFRunLoopModeHash,
+    NULL,      // 
+    __CFRunLoopModeCopyDescription
+};
+
+static const CFRuntimeClass __CFRunLoopClass = {
+    0,
+    "CFRunLoop",
+    NULL,      // init
+    NULL,      // copy
+    __CFRunLoopDeallocate,
+    NULL,
+    NULL,
+    NULL,      // 
+    __CFRunLoopCopyDescription
+};
+
+__private_extern__ void __CFRunLoopInitialize(void) {
+    __kCFRunLoopTypeID = _CFRuntimeRegisterClass(&__CFRunLoopClass);
+    __kCFRunLoopModeTypeID = _CFRuntimeRegisterClass(&__CFRunLoopModeClass);
+}
+CFTypeID CFRunLoopGetTypeID(void) {
+    return __kCFRunLoopTypeID;
+}
+
+static CFRunLoopRef __CFRunLoopCreate(void) {
+    CFRunLoopRef loop = NULL;
+    CFRunLoopModeRef rlm;
+    uint32_t size = sizeof(struct __CFRunLoop) - sizeof(CFRuntimeBase);
+    loop = (CFRunLoopRef)_CFRuntimeCreateInstance(kCFAllocatorSystemDefault, __kCFRunLoopTypeID, size, NULL);
+    if (NULL == loop) {
+       return NULL;
+    }
+    loop->_stopped = NULL;
+    CF_SPINLOCK_INIT_FOR_STRUCTS(loop->_lock);
+    loop->_wakeUpPort = __CFPortAllocate();
+    if (CFPORT_NULL == loop->_wakeUpPort) HALT;
+    loop->_commonModes = CFSetCreateMutable(CFGetAllocator(loop), 0, &kCFTypeSetCallBacks);
+    CFSetAddValue(loop->_commonModes, kCFRunLoopDefaultMode);
+    loop->_commonModeItems = NULL;
+    loop->_currentMode = NULL;
+    loop->_modes = CFSetCreateMutable(CFGetAllocator(loop), 0, &kCFTypeSetCallBacks);
+    _CFSetSetCapacity(loop->_modes, 10);
+    loop->_counterpart = NULL;
+    rlm = __CFRunLoopFindMode(loop, kCFRunLoopDefaultMode, true);
+    if (NULL != rlm) __CFRunLoopModeUnlock(rlm);
+    return loop;
+}
+
+static CFMutableDictionaryRef runLoops = NULL;
+static char setMainLoop = 0;
+static CFSpinLock_t loopsLock = CFSpinLockInit;
+
+// If this is called on a non-main thread, and the main thread pthread_t is passed in,
+// and this has not yet beed called on the main thread (since the last fork(), this will
+// produce a different run loop that will probably be tossed away eventually, than the
+// main thread run loop. There's nothing much we can do about that, without a call to
+// fetch the main thread's pthread_t from the pthreads subsystem.
+
+// t==0 is a synonym for "main thread" that always works
+__private_extern__ CFRunLoopRef _CFRunLoop0(pthread_t t) {
+    CFRunLoopRef loop = NULL;
+    __CFSpinLock(&loopsLock);
+    if (!runLoops) {
+        __CFSpinUnlock(&loopsLock);
+       CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, NULL);
+       CFRunLoopRef mainLoop = __CFRunLoopCreate();
+       CFDictionarySetValue(dict, 0, mainLoop);
+       if (!OSAtomicCompareAndSwapPtrBarrier(NULL, dict, (void * volatile *)&runLoops)) {
+           CFRelease(dict);
+           CFRelease(mainLoop);
+       }
+        __CFSpinLock(&loopsLock);
+    }
+    if (pthread_main_np() && pthread_equal(t, pthread_self())) {
+       t = kNilPthreadT;
+    }
+    loop = (CFRunLoopRef)CFDictionaryGetValue(runLoops, pthreadPointer(t));
+    if (!loop) {
+        __CFSpinUnlock(&loopsLock);
+       CFRunLoopRef newLoop = __CFRunLoopCreate();
+       __CFGetThreadSpecificData();    // just cause the thread finalizer to be called as a side effect
+        __CFSpinLock(&loopsLock);
+       loop = (CFRunLoopRef)CFDictionaryGetValue(runLoops, pthreadPointer(t));
+       if (loop) {
+           CFRelease(newLoop);
+       } else {
+           CFDictionarySetValue(runLoops, pthreadPointer(t), newLoop);
+           loop = newLoop;
+       }
+    }
+    if (!setMainLoop && pthread_main_np()) {
+       if (pthread_equal(t, kNilPthreadT)) {
+           CFDictionarySetValue(runLoops, pthreadPointer(pthread_self()), loop);
+       } else {
+           CFRunLoopRef mainLoop = (CFRunLoopRef)CFDictionaryGetValue(runLoops, pthreadPointer(kNilPthreadT));
+           CFDictionarySetValue(runLoops, pthreadPointer(pthread_self()), mainLoop);
+       }
+        setMainLoop = 1;
+    }
+    __CFSpinUnlock(&loopsLock);
+    return loop;
+}
+
+__private_extern__ void _CFRunLoop1(void) {
+    __CFSpinLock(&loopsLock);
+    if (runLoops) {
+       pthread_t t = pthread_self();
+       CFRunLoopRef currentLoop = (CFRunLoopRef)CFDictionaryGetValue(runLoops, pthreadPointer(t));
+       CFRunLoopRef mainLoop = (CFRunLoopRef)CFDictionaryGetValue(runLoops, pthreadPointer(kNilPthreadT));
+       if (currentLoop && mainLoop != currentLoop) {
+           CFDictionaryRemoveValue(runLoops, pthreadPointer(t));
+           CFRelease(currentLoop);
+       }
+    }
+    __CFSpinUnlock(&loopsLock);
+}
+
+CFRunLoopRef CFRunLoopGetMain(void) {
+    CHECK_FOR_FORK();
+    return _CFRunLoop0(kNilPthreadT);
+}
+
+CFRunLoopRef CFRunLoopGetCurrent(void) {
+    CHECK_FOR_FORK();
+    return _CFRunLoop0(pthread_self());
+}
+
+void _CFRunLoopSetCurrent(CFRunLoopRef rl) {
+    __CFSpinLock(&loopsLock);
+    CFRunLoopRef currentLoop = runLoops ? (CFRunLoopRef)CFDictionaryGetValue(runLoops, pthreadPointer(pthread_self())) : NULL;
+    if (rl != currentLoop) {
+       // intentionally leak currentLoop so we don't kill any ports in the child
+       // if (currentLoop) CFRelease(currentLoop);
+       if (rl) {
+           if (!runLoops) {
+               runLoops = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, NULL);
+               CFRunLoopRef mainLoop = __CFRunLoopCreate();
+               CFDictionarySetValue(runLoops, pthreadPointer(kNilPthreadT), mainLoop);
+           }
+           CFRetain(rl);
+           CFDictionarySetValue(runLoops, pthreadPointer(pthread_self()), rl);
+       } else {
+           CFDictionaryRemoveValue(runLoops, pthreadPointer(pthread_self()));
+       }
+    }
+    __CFSpinUnlock(&loopsLock);
+}
+
+CFStringRef CFRunLoopCopyCurrentMode(CFRunLoopRef rl) {
+    CHECK_FOR_FORK();
+    CFStringRef result = NULL;
+    __CFRunLoopLock(rl);
+    if (NULL != rl->_currentMode) {
+       result = CFRetain(rl->_currentMode->_name);
+    }
+    __CFRunLoopUnlock(rl);
+    return result;
+}
+
+static void __CFRunLoopGetModeName(const void *value, void *context) {
+    CFRunLoopModeRef rlm = (CFRunLoopModeRef)value;
+    CFMutableArrayRef array = (CFMutableArrayRef)context;
+    CFArrayAppendValue(array, rlm->_name);
+}
+
+CFArrayRef CFRunLoopCopyAllModes(CFRunLoopRef rl) {
+    CHECK_FOR_FORK();
+    CFMutableArrayRef array;
+    __CFRunLoopLock(rl);
+    array = CFArrayCreateMutable(kCFAllocatorSystemDefault, CFSetGetCount(rl->_modes), &kCFTypeArrayCallBacks);
+    CFSetApplyFunction(rl->_modes, (__CFRunLoopGetModeName), array);
+    __CFRunLoopUnlock(rl);
+    return array;
+}
+
+static void __CFRunLoopAddItemsToCommonMode(const void *value, void *ctx) {
+    CFTypeRef item = (CFTypeRef)value;
+    CFRunLoopRef rl = (CFRunLoopRef)(((CFTypeRef *)ctx)[0]);
+    CFStringRef modeName = (CFStringRef)(((CFTypeRef *)ctx)[1]);
+    if (CFGetTypeID(item) == __kCFRunLoopSourceTypeID) {
+       CFRunLoopAddSource(rl, (CFRunLoopSourceRef)item, modeName);
+    } else if (CFGetTypeID(item) == __kCFRunLoopObserverTypeID) {
+       CFRunLoopAddObserver(rl, (CFRunLoopObserverRef)item, modeName);
+    } else if (CFGetTypeID(item) == __kCFRunLoopTimerTypeID) {
+       CFRunLoopAddTimer(rl, (CFRunLoopTimerRef)item, modeName);
+    }
+}
+
+static void __CFRunLoopAddItemToCommonModes(const void *value, void *ctx) {
+    CFStringRef modeName = (CFStringRef)value;
+    CFRunLoopRef rl = (CFRunLoopRef)(((CFTypeRef *)ctx)[0]);
+    CFTypeRef item = (CFTypeRef)(((CFTypeRef *)ctx)[1]);
+    if (CFGetTypeID(item) == __kCFRunLoopSourceTypeID) {
+       CFRunLoopAddSource(rl, (CFRunLoopSourceRef)item, modeName);
+    } else if (CFGetTypeID(item) == __kCFRunLoopObserverTypeID) {
+       CFRunLoopAddObserver(rl, (CFRunLoopObserverRef)item, modeName);
+    } else if (CFGetTypeID(item) == __kCFRunLoopTimerTypeID) {
+       CFRunLoopAddTimer(rl, (CFRunLoopTimerRef)item, modeName);
+    }
+}
+
+static void __CFRunLoopRemoveItemFromCommonModes(const void *value, void *ctx) {
+    CFStringRef modeName = (CFStringRef)value;
+    CFRunLoopRef rl = (CFRunLoopRef)(((CFTypeRef *)ctx)[0]);
+    CFTypeRef item = (CFTypeRef)(((CFTypeRef *)ctx)[1]);
+    if (CFGetTypeID(item) == __kCFRunLoopSourceTypeID) {
+       CFRunLoopRemoveSource(rl, (CFRunLoopSourceRef)item, modeName);
+    } else if (CFGetTypeID(item) == __kCFRunLoopObserverTypeID) {
+       CFRunLoopRemoveObserver(rl, (CFRunLoopObserverRef)item, modeName);
+    } else if (CFGetTypeID(item) == __kCFRunLoopTimerTypeID) {
+       CFRunLoopRemoveTimer(rl, (CFRunLoopTimerRef)item, modeName);
+    }
+}
+
+Boolean _CFRunLoop01(CFRunLoopRef rl, CFStringRef modeName) {
+    __CFRunLoopLock(rl);
+    Boolean present = CFSetContainsValue(rl->_commonModes, modeName);
+    __CFRunLoopUnlock(rl);
+    return present; 
+}
+
+void *_CFRunLoop02(CFRunLoopRef rl) {
+    return rl->_counterpart;
+}
+
+void _CFRunLoop03(CFRunLoopRef rl, void *ns) {
+    rl->_counterpart = ns;
+}
+
+void CFRunLoopAddCommonMode(CFRunLoopRef rl, CFStringRef modeName) {
+    CHECK_FOR_FORK();
+    if (__CFRunLoopIsDeallocating(rl)) return;
+    __CFRunLoopLock(rl);
+    if (!CFSetContainsValue(rl->_commonModes, modeName)) {
+       CFSetRef set = rl->_commonModeItems ? CFSetCreateCopy(kCFAllocatorSystemDefault, rl->_commonModeItems) : NULL;
+       CFSetAddValue(rl->_commonModes, modeName);
+       __CFRunLoopUnlock(rl);
+       if (NULL != set) {
+           CFTypeRef context[2] = {rl, modeName};
+           /* add all common-modes items to new mode */
+           CFSetApplyFunction(set, (__CFRunLoopAddItemsToCommonMode), (void *)context);
+           CFRelease(set);
+       }
+    } else {
+       __CFRunLoopUnlock(rl);
+    }
+}
+
+static CFComparisonResult __CFRunLoopObserverQSortComparator(const void *val1, const void *val2, void *context) {
+    CFRunLoopObserverRef o1 = *((CFRunLoopObserverRef *)val1);
+    CFRunLoopObserverRef o2 = *((CFRunLoopObserverRef *)val2);
+    if (!o1) {
+       return (!o2) ? kCFCompareEqualTo : kCFCompareLessThan;
+    }
+    if (!o2) {
+       return kCFCompareGreaterThan;
+    }
+    if (o1->_order < o2->_order) return kCFCompareLessThan;
+    if (o2->_order < o1->_order) return kCFCompareGreaterThan;
+    return kCFCompareEqualTo;
+}
+
+
+/* rl is unlocked, rlm is locked on entrance and exit */
+/* ALERT: this should collect all the candidate observers from the top level
+ * and all submodes, recursively, THEN start calling them, in order to obey
+ * the ordering parameter. */
+static void __CFRunLoopDoObservers(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopActivity activity) {        /* DOES CALLOUT */
+    CHECK_FOR_FORK();
+    CFIndex idx, cnt;
+    CFArrayRef submodes;
+
+    /* Fire the observers */
+    submodes = (NULL != rlm->_submodes && 0 < CFArrayGetCount(rlm->_submodes)) ? CFArrayCreateCopy(kCFAllocatorSystemDefault, rlm->_submodes) : NULL;
+    if (NULL != rlm->_observers) {
+       cnt = CFSetGetCount(rlm->_observers);
+       if (0 < cnt) {
+           CFRunLoopObserverRef buffer[(cnt <= 1024) ? cnt : 1];
+           CFRunLoopObserverRef *collectedObservers = (cnt <= 1024) ? buffer : CFAllocatorAllocate(kCFAllocatorSystemDefault, cnt * sizeof(CFRunLoopObserverRef), 0);
+           CFSetGetValues(rlm->_observers, (const void **)collectedObservers);
+           for (idx = 0; idx < cnt; idx++) {
+               CFRunLoopObserverRef rlo = collectedObservers[idx];
+               if (0 != (rlo->_activities & activity) && __CFIsValid(rlo) && !__CFRunLoopObserverIsFiring(rlo)) {
+                   CFRetain(rlo);
+               } else {
+                   /* We're not interested in this one - set it to NULL so we don't process it later */
+                   collectedObservers[idx] = NULL;
+               }
+           }
+           __CFRunLoopModeUnlock(rlm);
+           CFQSortArray(collectedObservers, cnt, sizeof(CFRunLoopObserverRef), __CFRunLoopObserverQSortComparator, NULL);
+           for (idx = 0; idx < cnt; idx++) {
+               CFRunLoopObserverRef rlo = collectedObservers[idx];
+               if (rlo) {
+                   __CFRunLoopObserverLock(rlo);
+                   if (__CFIsValid(rlo)) {
+                       __CFRunLoopObserverUnlock(rlo);
+                       __CFRunLoopObserverSetFiring(rlo);
+                       rlo->_callout(rlo, activity, rlo->_context.info);       /* CALLOUT */
+                       __CFRunLoopObserverUnsetFiring(rlo);
+                       if (!__CFRunLoopObserverRepeats(rlo)) {
+                           CFRunLoopObserverInvalidate(rlo);
+                       }
+                   } else {
+                       __CFRunLoopObserverUnlock(rlo);
+                   }
+                   CFRelease(rlo);
+               }
+           }
+           __CFRunLoopModeLock(rlm);
+           if (collectedObservers != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, collectedObservers);
+       }
+    }
+    if (NULL != submodes) {
+       __CFRunLoopModeUnlock(rlm);
+       for (idx = 0, cnt = CFArrayGetCount(submodes); idx < cnt; idx++) {
+           CFStringRef modeName = (CFStringRef)CFArrayGetValueAtIndex(submodes, idx);
+           CFRunLoopModeRef subrlm;
+            __CFRunLoopLock(rl);
+            subrlm = __CFRunLoopFindMode(rl, modeName, false);
+           __CFRunLoopUnlock(rl);
+           if (NULL != subrlm) {
+               __CFRunLoopDoObservers(rl, subrlm, activity);
+               __CFRunLoopModeUnlock(subrlm);
+           }
+       }
+       CFRelease(submodes);
+        __CFRunLoopModeLock(rlm);
+    }
+}
+
+static CFComparisonResult __CFRunLoopSourceComparator(const void *val1, const void *val2, void *context) {
+    CFRunLoopSourceRef o1 = (CFRunLoopSourceRef)val1;
+    CFRunLoopSourceRef o2 = (CFRunLoopSourceRef)val2;
+    if (o1->_order < o2->_order) return kCFCompareLessThan;
+    if (o2->_order < o1->_order) return kCFCompareGreaterThan;
+    return kCFCompareEqualTo;
+}
+
+static void __CFRunLoopCollectSources0(const void *value, void *context) {
+    CFRunLoopSourceRef rls = (CFRunLoopSourceRef)value;
+    CFTypeRef *sources = (CFTypeRef *)context;
+    if (0 == rls->_context.version0.version && __CFIsValid(rls) && __CFRunLoopSourceIsSignaled(rls)) {
+       if (NULL == *sources) {
+           *sources = CFRetain(rls);
+       } else if (CFGetTypeID(*sources) == __kCFRunLoopSourceTypeID) {
+           CFTypeRef oldrls = *sources;
+           *sources = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
+           CFArrayAppendValue((CFMutableArrayRef)*sources, oldrls);
+           CFArrayAppendValue((CFMutableArrayRef)*sources, rls);
+           CFRelease(oldrls);
+       } else {
+           CFArrayAppendValue((CFMutableArrayRef)*sources, rls);
+       }
+    }
+}
+
+/* rl is unlocked, rlm is locked on entrance and exit */
+static Boolean __CFRunLoopDoSources0(CFRunLoopRef rl, CFRunLoopModeRef rlm, Boolean stopAfterHandle) { /* DOES CALLOUT */
+    CHECK_FOR_FORK();
+    CFTypeRef sources = NULL;
+    Boolean sourceHandled = false;
+    CFIndex idx, cnt;
+
+    __CFRunLoopModeUnlock(rlm); // locks have to be taken in order
+    __CFRunLoopLock(rl);
+    __CFRunLoopModeLock(rlm);
+    /* Fire the version 0 sources */
+    if (NULL != rlm->_sources && 0 < CFSetGetCount(rlm->_sources)) {
+       CFSetApplyFunction(rlm->_sources, (__CFRunLoopCollectSources0), &sources);
+    }
+    for (idx = 0, cnt = (NULL != rlm->_submodes) ? CFArrayGetCount(rlm->_submodes) : 0; idx < cnt; idx++) {
+       CFStringRef modeName = (CFStringRef)CFArrayGetValueAtIndex(rlm->_submodes, idx);
+       CFRunLoopModeRef subrlm;
+       subrlm = __CFRunLoopFindMode(rl, modeName, false);
+       if (NULL != subrlm) {
+           if (NULL != subrlm->_sources && 0 < CFSetGetCount(subrlm->_sources)) {
+               CFSetApplyFunction(subrlm->_sources, (__CFRunLoopCollectSources0), &sources);
+           }
+           __CFRunLoopModeUnlock(subrlm);
+       }
+    }
+    __CFRunLoopUnlock(rl);
+    if (NULL != sources) {
+       // sources is either a single (retained) CFRunLoopSourceRef or an array of (retained) CFRunLoopSourceRef
+       __CFRunLoopModeUnlock(rlm);
+       if (CFGetTypeID(sources) == __kCFRunLoopSourceTypeID) {
+           CFRunLoopSourceRef rls = (CFRunLoopSourceRef)sources;
+           __CFRunLoopSourceLock(rls);
+           __CFRunLoopSourceUnsetSignaled(rls);
+           if (__CFIsValid(rls)) {
+               __CFRunLoopSourceUnlock(rls);
+               if (NULL != rls->_context.version0.perform) {
+                   rls->_context.version0.perform(rls->_context.version0.info); /* CALLOUT */
+                   CHECK_FOR_FORK();
+               }
+               sourceHandled = true;
+           } else {
+               __CFRunLoopSourceUnlock(rls);
+           }
+       } else {
+           cnt = CFArrayGetCount(sources);
+           CFArraySortValues((CFMutableArrayRef)sources, CFRangeMake(0, cnt), (__CFRunLoopSourceComparator), NULL);
+           for (idx = 0; idx < cnt; idx++) {
+               CFRunLoopSourceRef rls = (CFRunLoopSourceRef)CFArrayGetValueAtIndex(sources, idx);
+               __CFRunLoopSourceLock(rls);
+               __CFRunLoopSourceUnsetSignaled(rls);
+               if (__CFIsValid(rls)) {
+                   __CFRunLoopSourceUnlock(rls);
+                   if (NULL != rls->_context.version0.perform) {
+                       rls->_context.version0.perform(rls->_context.version0.info); /* CALLOUT */
+                       CHECK_FOR_FORK();
+                   }
+                   sourceHandled = true;
+               } else {
+                   __CFRunLoopSourceUnlock(rls);
+               }
+               if (stopAfterHandle && sourceHandled) {
+                   break;
+               }
+           }
+       }
+       CFRelease(sources);
+       __CFRunLoopModeLock(rlm);
+    }
+    return sourceHandled;
+}
+
+// msg, size and reply are unused on Windows
+static Boolean __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopSourceRef rls
+#if DEPLOYMENT_TARGET_MACOSX
+                                    , mach_msg_header_t *msg, CFIndex size, mach_msg_header_t **reply
+#endif
+                                    ) {        /* DOES CALLOUT */
+    CHECK_FOR_FORK();
+    Boolean sourceHandled = false;
+
+    /* Fire a version 1 source */
+    CFRetain(rls);
+    __CFRunLoopModeUnlock(rlm);
+    __CFRunLoopSourceLock(rls);
+    if (__CFIsValid(rls)) {
+       __CFRunLoopSourceUnsetSignaled(rls);
+       __CFRunLoopSourceUnlock(rls);
+       if (NULL != rls->_context.version1.perform) {
+#if DEPLOYMENT_TARGET_MACOSX
+           *reply = rls->_context.version1.perform(msg, size, kCFAllocatorSystemDefault, rls->_context.version1.info); /* CALLOUT */
+           CHECK_FOR_FORK();
+#else
+            if (_LogCFRunLoop) { CFLog(kCFLogLevelDebug, CFSTR("%p (%s) __CFRunLoopDoSource1 performing rls %p"), CFRunLoopGetCurrent(), *_CFGetProgname(), rls); }
+            rls->_context.version1.perform(rls->_context.version1.info); /* CALLOUT */
+           CHECK_FOR_FORK();
+#endif
+       } else {
+        if (_LogCFRunLoop) { CFLog(kCFLogLevelDebug, CFSTR("%p (%s) __CFRunLoopDoSource1 perform is NULL"), CFRunLoopGetCurrent(), *_CFGetProgname()); }
+    }
+       sourceHandled = true;
+    } else {
+        if (_LogCFRunLoop) { CFLog(kCFLogLevelDebug, CFSTR("%p (%s) __CFRunLoopDoSource1 rls %p is invalid"), CFRunLoopGetCurrent(), *_CFGetProgname(), rls); }
+       __CFRunLoopSourceUnlock(rls);
+    }
+    CFRelease(rls);
+    __CFRunLoopModeLock(rlm);
+    return sourceHandled;
+}
+
+static Boolean __CFRunLoopDoTimer(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopTimerRef rlt) {      /* DOES CALLOUT */
+    Boolean timerHandled = false;
+    int64_t oldFireTSR = 0;
+
+    /* Fire a timer */
+    CFRetain(rlt);
+    __CFRunLoopModeUnlock(rlm);
+    __CFRunLoopTimerLock(rlt);
+    if (__CFIsValid(rlt) && !__CFRunLoopTimerIsFiring(rlt)) {
+       __CFRunLoopTimerUnsetDidFire(rlt);
+       __CFRunLoopTimerSetFiring(rlt);
+       __CFRunLoopTimerUnlock(rlt);
+       __CFRunLoopTimerFireTSRLock();
+       oldFireTSR = rlt->_fireTSR;
+       __CFRunLoopTimerFireTSRUnlock();
+       rlt->_callout(rlt, rlt->_context.info); /* CALLOUT */
+       CHECK_FOR_FORK();
+       __CFRunLoopTimerUnsetFiring(rlt);
+       timerHandled = true;
+    } else {
+       // If the timer fires while it is firing in a higher activiation,
+       // it is not allowed to fire, but we have to remember that fact.
+       // Later, if the timer's fire date is being handled manually, we
+       // need to re-arm the kernel timer, since it has possibly already
+       // fired (this firing which is being skipped, say) and the timer
+       // will permanently stop if we completely drop this firing.
+       if (__CFRunLoopTimerIsFiring(rlt)) __CFRunLoopTimerSetDidFire(rlt);
+       __CFRunLoopTimerUnlock(rlt);
+    }
+    if (__CFIsValid(rlt) && timerHandled) {
+       if (0 == rlt->_intervalTSR) {
+           CFRunLoopTimerInvalidate(rlt);      /* DOES CALLOUT */
+       } else {
+           /* This is just a little bit tricky: we want to support calling
+            * CFRunLoopTimerSetNextFireDate() from within the callout and
+            * honor that new time here if it is a later date, otherwise
+            * it is completely ignored. */
+           int64_t currentFireTSR;
+           __CFRunLoopTimerFireTSRLock();
+           currentFireTSR = rlt->_fireTSR;
+           if (oldFireTSR < currentFireTSR) {
+               /* Next fire TSR was set, and set to a date after the previous
+                * fire date, so we honor it. */
+               if (__CFRunLoopTimerDidFire(rlt)) {
+                   __CFRunLoopTimerRescheduleWithAllModes(rlt, rl);
+                   __CFRunLoopTimerUnsetDidFire(rlt);
+               }
+           } else {
+               if ((uint64_t)LLONG_MAX <= (uint64_t)oldFireTSR + (uint64_t)rlt->_intervalTSR) {
+                   currentFireTSR = LLONG_MAX;
+               } else {
+                   int64_t currentTSR = (int64_t)__CFReadTSR();
+                   currentFireTSR = oldFireTSR;
+                   while (currentFireTSR <= currentTSR) {
+                       currentFireTSR += rlt->_intervalTSR;
+                   }
+               }
+               rlt->_fireTSR = currentFireTSR;
+               __CFRunLoopTimerRescheduleWithAllModes(rlt, rl);
+           }
+           __CFRunLoopTimerFireTSRUnlock();
+       }
+    }
+    CFRelease(rlt);
+    __CFRunLoopModeLock(rlm);
+    return timerHandled;
+}
+
+CF_EXPORT Boolean _CFRunLoopFinished(CFRunLoopRef rl, CFStringRef modeName) {
+    CHECK_FOR_FORK();
+    CFRunLoopModeRef rlm;
+    Boolean result = false;
+    __CFRunLoopLock(rl);
+    rlm = __CFRunLoopFindMode(rl, modeName, false);
+    if (NULL == rlm || __CFRunLoopModeIsEmpty(rl, rlm)) {
+       result = true;
+    }
+    __CFRunLoopUnlock(rl);
+    if (rlm) __CFRunLoopModeUnlock(rlm);
+    return result;
+}
+
+// rl is locked, rlm is locked on entry and exit
+static void __CFRunLoopModeAddPortsToPortSet(CFRunLoopRef rl, CFRunLoopModeRef rlm, __CFPortSet portSet) {
+    CFIndex idx, cnt;
+    const void **list, *buffer[256];
+
+    // Timers and version 1 sources go into the portSet currently
+    if (NULL != rlm->_sources) {
+       cnt = CFSetGetCount(rlm->_sources);
+       list = (cnt <= 256) ? buffer : CFAllocatorAllocate(kCFAllocatorSystemDefault, cnt * sizeof(void *), 0);
+       CFSetGetValues(rlm->_sources, list);
+       for (idx = 0; idx < cnt; idx++) {
+           CFRunLoopSourceRef rls = (CFRunLoopSourceRef)list[idx];
+           if (1 == rls->_context.version0.version) {
+               __CFPort port = rls->_context.version1.getPort(rls->_context.version1.info);    /* CALLOUT */
+               if (CFPORT_NULL != port) {
+                   __CFPortSetInsert(port, portSet);
+               }
+           }
+       }
+       if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
+    }
+#if DEPLOYMENT_TARGET_MACOSX
+    if (NULL != rlm->_timers) {
+       cnt = CFSetGetCount(rlm->_timers);
+       list = (cnt <= 256) ? buffer : CFAllocatorAllocate(kCFAllocatorSystemDefault, cnt * sizeof(void *), 0);
+       CFSetGetValues(rlm->_timers, list);
+       for (idx = 0; idx < cnt; idx++) {
+           CFRunLoopTimerRef rlt = (CFRunLoopTimerRef)list[idx];
+           if (MACH_PORT_NULL != rlt->_port) {
+               mach_port_insert_member(mach_task_self(), rlt->_port, portSet);
+           }
+       }
+       if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
+    }
+#endif
+    // iterate over submodes
+    for (idx = 0, cnt = NULL != rlm->_submodes ? CFArrayGetCount(rlm->_submodes) : 0; idx < cnt; idx++) {
+       CFStringRef modeName = (CFStringRef)CFArrayGetValueAtIndex(rlm->_submodes, idx);
+       CFRunLoopModeRef subrlm;
+       subrlm = __CFRunLoopFindMode(rl, modeName, false);
+       if (NULL != subrlm) {
+           __CFRunLoopModeAddPortsToPortSet(rl, subrlm, portSet);
+           __CFRunLoopModeUnlock(subrlm);
+       }
+    }
+}
+
+static __CFPortSet _LastMainWaitSet = 0;
+
+// return NO if we're the main runloop and there are no messages waiting on the port set
+int _CFRunLoopInputsReady(void) {
+    CHECK_FOR_FORK();
+    // XXX_PCB:  the following 2 lines aren't safe to call during GC, because another
+    // thread may have entered CFRunLoopGetMain(), which grabs a spink lock, and then
+    // is suspended by the GC. We can check for the main thread more directly
+    // by calling pthread_main_np().
+    // CFRunLoopRef current = CFRunLoopGetMain()
+    // if (current != CFRunLoopGetMain()) return true;
+#if DEPLOYMENT_TARGET_MACOSX
+    if (!pthread_main_np()) return true;
+
+    // XXX_PCB:  can't be any messages waiting if the wait set is NULL.
+    if (_LastMainWaitSet == MACH_PORT_NULL) return false;
+    // prepare a message header with no space for any data, nor a trailer
+    mach_msg_header_t msg;
+    msg.msgh_size = sizeof(msg);    // just the header, ma'am
+    // need the waitset, actually XXX
+    msg.msgh_local_port = _LastMainWaitSet;
+    msg.msgh_remote_port = MACH_PORT_NULL;
+    msg.msgh_id = 0;
+    
+    kern_return_t ret = mach_msg(&msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT | MACH_RCV_LARGE, 0, msg.msgh_size, _LastMainWaitSet, 0, MACH_PORT_NULL);
+    
+    return (MACH_RCV_TOO_LARGE == ret);
+#endif
+    return true;
+}
+
+#if 0
+static void print_msg_scan_header(void) {
+    printf("======== ======== ======== ========\n");
+    printf("description\tport\tport type\t\treferences\n");
+}
+
+static void print_one_port_info(const char *desc, mach_port_t port, mach_msg_type_name_t type) {
+    mach_port_urefs_t refs;
+    kern_return_t ret = mach_port_get_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND, &refs);
+    if (ret != KERN_SUCCESS) refs = 0;
+    const char *type_name = "???";
+    switch (type) {
+    case MACH_MSG_TYPE_MOVE_SEND: type_name = "MACH_MSG_TYPE_MOVE_SEND"; break;
+    case MACH_MSG_TYPE_MOVE_SEND_ONCE: type_name = "MACH_MSG_TYPE_MOVE_SEND_ONCE"; break;
+    case MACH_MSG_TYPE_MOVE_RECEIVE: type_name = "MACH_MSG_TYPE_MOVE_RECEIVE"; break;
+    case MACH_MSG_TYPE_MAKE_SEND: type_name = "MACH_MSG_TYPE_MAKE_SEND"; break;
+    case MACH_MSG_TYPE_MAKE_SEND_ONCE: type_name = "MACH_MSG_TYPE_MAKE_SEND_ONCE"; break;
+    }
+    printf("%s\t%p\t%-20s\t%u\n", desc, port, type_name, refs);
+}
+
+static void mach_msg_scan(mach_msg_header_t *msg, int clean) {
+    Boolean printed_header = false;
+    /*
+     * The msgh_local_port field doesn't hold a port right.
+     * The receive operation consumes the destination port right.
+     */
+    if (MACH_PORT_NULL != msg->msgh_remote_port) {
+       if (! printed_header) print_msg_scan_header();
+       printed_header = true;
+       print_one_port_info("msg->msgh_remote_port", msg->msgh_remote_port, MACH_MSGH_BITS_REMOTE(msg->msgh_bits));
+    }
+    if (msg->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
+       mach_msg_body_t *body = (mach_msg_body_t *) (msg + 1);
+       mach_msg_descriptor_t *saddr = (mach_msg_descriptor_t *) ((mach_msg_base_t *) msg + 1);
+       mach_msg_descriptor_t *eaddr =  saddr + body->msgh_descriptor_count;
+       for  ( ; saddr < eaddr; saddr++) {
+           switch (saddr->type.type) {
+           case MACH_MSG_PORT_DESCRIPTOR:;
+               mach_msg_port_descriptor_t *dsc = &saddr->port;
+               if (! printed_header) print_msg_scan_header();
+               printed_header = true;
+               print_one_port_info("port in body", dsc->name, dsc->disposition);
+//             if (clean) mach_port_deallocate(mach_task_self(), dsc->name);
+               break;
+           case MACH_MSG_OOL_PORTS_DESCRIPTOR:;
+                   mach_msg_ool_ports_descriptor_t *dsc2 = &saddr->ool_ports;
+                   mach_port_t *ports = (mach_port_t *) dsc2->address;
+                   for (mach_msg_type_number_t j = 0; j < dsc2->count; j++, ports++)  {
+                       if (! printed_header) print_msg_scan_header();
+                       printed_header = true;
+                       print_one_port_info("port in OOL ports", *ports, dsc2->disposition);
+                   }
+                   break;
+           }
+       }
+    }
+}
+#endif
+
+/* rl is unlocked, rlm locked on entrance and exit */
+static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInterval seconds, Boolean stopAfterHandle, Boolean waitIfEmpty) {  /* DOES CALLOUT */
+    int64_t termTSR;
+#if DEPLOYMENT_TARGET_MACOSX
+    mach_port_name_t timeoutPort = MACH_PORT_NULL;
+    Boolean timeoutPortAdded = false;
+#endif
+    Boolean poll = false;
+    Boolean firstPass = true;
+
+    if (__CFRunLoopIsStopped(rl)) {
+       return kCFRunLoopRunStopped;
+    } else if (rlm->_stopped) {
+       rlm->_stopped = false;
+       return kCFRunLoopRunStopped;
+    }
+    if (seconds <= 0.0) {
+       termTSR = 0;
+    } else if (3.1556952e+9 < seconds) {
+       termTSR = LLONG_MAX;
+    } else {
+       termTSR = (int64_t)__CFReadTSR() + __CFTimeIntervalToTSR(seconds);
+#if DEPLOYMENT_TARGET_MACOSX
+       timeoutPort = mk_timer_create();
+       mk_timer_arm(timeoutPort, __CFUInt64ToAbsoluteTime(termTSR));
+#endif
+    }
+    if (seconds <= 0.0) {
+       poll = true;
+    }
+    if (rl == _CFRunLoop0(kNilPthreadT)) _LastMainWaitSet = CFPORT_NULL;
+    for (;;) {
+        __CFPortSet waitSet = CFPORT_NULL;
+        waitSet = CFPORT_NULL;
+        Boolean destroyWaitSet = false;
+        CFRunLoopSourceRef rls;
+#if DEPLOYMENT_TARGET_MACOSX
+       mach_msg_header_t *msg;
+       kern_return_t ret;
+        uint8_t buffer[1024 + 80] = {0};       // large enough for 1k of inline payload; must be zeroed for GC
+#else
+        CFArrayRef timersToCall = NULL;
+#endif
+       int32_t returnValue = 0;
+       Boolean sourceHandledThisLoop = false;
+
+       __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeTimers);
+       __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeSources);
+
+       sourceHandledThisLoop = __CFRunLoopDoSources0(rl, rlm, stopAfterHandle);
+
+       if (sourceHandledThisLoop) {
+           poll = true;
+       }
+
+       if (!poll) {
+           __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeWaiting);
+           __CFRunLoopSetSleeping(rl);
+       }
+       if (NULL != rlm->_submodes) {
+           // !!! what do we do if this doesn't succeed?
+            waitSet = __CFPortSetAllocate();
+            if (CFPORT_NULL == waitSet) HALT;
+           __CFRunLoopModeUnlock(rlm);
+           __CFRunLoopLock(rl);
+           __CFRunLoopModeLock(rlm);
+           __CFRunLoopModeAddPortsToPortSet(rl, rlm, waitSet);
+           __CFRunLoopUnlock(rl);
+#if DEPLOYMENT_TARGET_MACOSX
+            if (CFPORT_NULL != timeoutPort) {
+               __CFPortSetInsert(timeoutPort, waitSet);
+           }
+#endif
+            destroyWaitSet = true;
+       } else {
+           waitSet = rlm->_portSet;
+#if DEPLOYMENT_TARGET_MACOSX
+           if (!timeoutPortAdded && CFPORT_NULL != timeoutPort) {
+               __CFPortSetInsert(timeoutPort, waitSet);
+               timeoutPortAdded = true;
+           }
+#endif
+       }
+       if (rl == _CFRunLoop0(kNilPthreadT)) _LastMainWaitSet = waitSet;
+       __CFRunLoopModeUnlock(rlm);
+
+#if DEPLOYMENT_TARGET_MACOSX
+        msg = (mach_msg_header_t *)buffer;
+       msg->msgh_size = sizeof(buffer);
+
+       /* In that sleep of death what nightmares may come ... */
+       try_receive:
+       msg->msgh_bits = 0;
+       msg->msgh_local_port = waitSet;
+       msg->msgh_remote_port = MACH_PORT_NULL;
+       msg->msgh_id = 0;
+       ret = mach_msg(msg, MACH_RCV_MSG|MACH_RCV_LARGE|(poll ? MACH_RCV_TIMEOUT : 0)|MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT), 0, msg->msgh_size, waitSet, 0, MACH_PORT_NULL);
+       if (MACH_RCV_TOO_LARGE == ret) {
+           uint32_t newSize = round_msg(msg->msgh_size) + sizeof(mach_msg_audit_trailer_t);
+           if (msg == (mach_msg_header_t *)buffer) msg = NULL;
+           msg = CFAllocatorReallocate(kCFAllocatorSystemDefault, msg, newSize, 0);
+           msg->msgh_size = newSize;
+           goto try_receive;
+       } else if (MACH_RCV_TIMED_OUT == ret) {
+           // timeout, for poll
+           if (msg != (mach_msg_header_t *)buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, msg);
+           msg = NULL;
+       } else if (MACH_MSG_SUCCESS != ret) {
+           HALT;
+       }
+#elif defined(__WIN32__)
+        DWORD waitResult = WAIT_TIMEOUT;
+        HANDLE handleBuf[MAXIMUM_WAIT_OBJECTS];
+        HANDLE *handles;
+        uint32_t handleCount;
+        Boolean freeHandles;
+        if (destroyWaitSet) {
+            // wait set is a local, no one else could modify it, no need to copy handles
+            handles = waitSet->handles;
+            handleCount = waitSet->used;
+            freeHandles = FALSE;
+        } else {
+            // copy out the handles to be safe from other threads at work
+            handles = __CFPortSetGetPorts(waitSet, handleBuf, MAXIMUM_WAIT_OBJECTS, &handleCount);
+            freeHandles = (handles != handleBuf);
+        }
+        // should msgQMask be an OR'ing of this and all submodes' masks?
+       if (0 == GetQueueStatus(rlm->_msgQMask)) {
+            DWORD timeout;
+            if (poll)
+                timeout = 0;
+            else {
+                __CFRunLoopModeLock(rlm);
+                int64_t nextStop = __CFRunLoopGetNextTimerFireTSR(rl, rlm);
+                if (nextStop <= 0)
+                    nextStop = termTSR;
+                else if (nextStop > termTSR)
+                    nextStop = termTSR;
+                // else the next stop is dictated by the next timer
+                int64_t timeoutTSR = nextStop - __CFReadTSR();
+                if (timeoutTSR < 0)
+                    timeout = 0;
+                else {
+                    CFTimeInterval timeoutCF = __CFTSRToTimeInterval(timeoutTSR) * 1000;
+                    if (timeoutCF > MAXDWORD)
+                        timeout = INFINITE;
+                    else
+                        timeout = timeoutCF;
+                }
+            }
+        if (_LogCFRunLoop) { CFLog(kCFLogLevelDebug, CFSTR("%p (%s)- about to wait for %d objects, wakeupport is %p"), CFRunLoopGetCurrent(), *_CFGetProgname(), handleCount, rl->_wakeUpPort); }
+        if (_LogCFRunLoop) { CFLog(kCFLogLevelDebug, CFSTR("All RLM sources = %@"), rlm->_sources); }
+        waitResult = MsgWaitForMultipleObjects(__CFMin(handleCount, MAXIMUM_WAIT_OBJECTS), handles, false, timeout, rlm->_msgQMask);
+        if (_LogCFRunLoop) { CFLog(kCFLogLevelDebug, CFSTR("%p (%s)- waitResult was %d"), CFRunLoopGetCurrent(), *_CFGetProgname(), waitResult); }
+       }
+       ResetEvent(rl->_wakeUpPort);
+#endif
+       if (destroyWaitSet) {
+            __CFPortSetFree(waitSet);
+           if (rl == _CFRunLoop0(kNilPthreadT)) _LastMainWaitSet = 0;
+       }
+       __CFRunLoopLock(rl);
+       __CFRunLoopModeLock(rlm);
+       __CFRunLoopUnlock(rl);
+       if (!poll) {
+           __CFRunLoopUnsetSleeping(rl);
+           __CFRunLoopDoObservers(rl, rlm, kCFRunLoopAfterWaiting);
+       }
+       poll = false;
+       __CFRunLoopModeUnlock(rlm);
+       __CFRunLoopLock(rl);
+       __CFRunLoopModeLock(rlm);
+
+        __CFPort livePort = CFPORT_NULL;
+#if DEPLOYMENT_TARGET_MACOSX
+       if (NULL != msg) {
+            livePort = msg->msgh_local_port;
+        }
+#elif defined(__WIN32__)
+        CFAssert2(waitResult != WAIT_FAILED, __kCFLogAssertion, "%s(): error %d from MsgWaitForMultipleObjects", __PRETTY_FUNCTION__, GetLastError());
+        if (waitResult == WAIT_TIMEOUT) {
+            // do nothing, just return to caller
+        } else if (waitResult >= WAIT_OBJECT_0 && waitResult < WAIT_OBJECT_0+handleCount) {
+            // a handle was signalled
+            livePort = handles[waitResult-WAIT_OBJECT_0];
+            if (_LogCFRunLoop) { CFLog(kCFLogLevelDebug, CFSTR("%p (%s)- Resetting event %p"), CFRunLoopGetCurrent(), *_CFGetProgname(), livePort); }
+        } else if (waitResult == WAIT_OBJECT_0+handleCount) {
+            // windows message received - the CFWindowsMessageQueue will pick this up when
+            // the v0 RunLoopSources get their chance
+        } else if (waitResult >= WAIT_ABANDONED_0 && waitResult < WAIT_ABANDONED_0+handleCount) {
+            // an "abandoned mutex object"
+            livePort = handles[waitResult-WAIT_ABANDONED_0];
+        } else {
+            CFAssert2(waitResult == WAIT_FAILED, __kCFLogAssertion, "%s(): unexpected result from MsgWaitForMultipleObjects: %d", __PRETTY_FUNCTION__, waitResult);
+        }
+        if (freeHandles)
+            CFAllocatorDeallocate(kCFAllocatorSystemDefault, handles);
+        timersToCall = __CFRunLoopTimersToFire(rl, rlm);
+#endif
+
+       if (CFPORT_NULL == livePort) {
+           __CFRunLoopUnlock(rl);
+       } else if (livePort == rl->_wakeUpPort) {
+           // wakeup
+               if (_LogCFRunLoop) { CFLog(kCFLogLevelDebug, CFSTR("wakeupPort was signalled")); }        
+           __CFRunLoopUnlock(rl);
+       }
+#if DEPLOYMENT_TARGET_MACOSX
+       else if (livePort == timeoutPort) {
+           returnValue = kCFRunLoopRunTimedOut;
+           __CFRunLoopUnlock(rl);
+       } else if (NULL != (rls = __CFRunLoopModeFindSourceForMachPort(rl, rlm, livePort))) {
+           mach_msg_header_t *reply = NULL;
+           __CFRunLoopUnlock(rl);
+//             mach_msg_scan(msg, 0);
+           if (__CFRunLoopDoSource1(rl, rlm, rls, msg, msg->msgh_size, &reply)) {
+               sourceHandledThisLoop = true;
+           }
+//             mach_msg_scan(msg, 1);
+           if (NULL != reply) {
+               ret = mach_msg(reply, MACH_SEND_MSG, reply->msgh_size, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL);
+//#warning CF: what should be done with the return value?
+               CFAllocatorDeallocate(kCFAllocatorSystemDefault, reply);
+           }
+       } else {
+           CFRunLoopTimerRef rlt;
+           rlt = __CFRunLoopModeFindTimerForMachPort(rlm, livePort);
+           __CFRunLoopUnlock(rl);
+           if (NULL != rlt) {
+               __CFRunLoopDoTimer(rl, rlm, rlt);
+           }
+       }
+       if (msg != (mach_msg_header_t *)buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, msg);
+#else
+       else if (NULL != (rls = __CFRunLoopModeFindSourceForMachPort(rl, rlm, livePort))) {
+           __CFRunLoopUnlock(rl);
+               if (_LogCFRunLoop) { CFLog(kCFLogLevelDebug, CFSTR("Source %@ was signalled"), rls); }
+           if (__CFRunLoopDoSource1(rl, rlm, rls)) {
+               sourceHandledThisLoop = true;
+           }
+       }
+#endif
+
+       __CFRunLoopModeUnlock(rlm);     // locks must be taken in order
+       __CFRunLoopLock(rl);
+       __CFRunLoopModeLock(rlm);
+       if (sourceHandledThisLoop && stopAfterHandle) {
+           returnValue = kCFRunLoopRunHandledSource;
+        // If we're about to timeout, but we just did a zero-timeout poll that only found our own
+        // internal wakeup signal on the first look at the portset, we'll go around the loop one
+        // more time, so as not to starve a v1 source that was just added along with a runloop wakeup.
+        } else if (0 != returnValue || (uint64_t)termTSR <= __CFReadTSR()) {
+           returnValue = kCFRunLoopRunTimedOut;
+       } else if (__CFRunLoopIsStopped(rl)) {
+           returnValue = kCFRunLoopRunStopped;
+       } else if (rlm->_stopped) {
+           rlm->_stopped = false;
+           returnValue = kCFRunLoopRunStopped;
+       } else if (!waitIfEmpty && __CFRunLoopModeIsEmpty(rl, rlm)) {
+           returnValue = kCFRunLoopRunFinished;
+       }
+       __CFRunLoopUnlock(rl);
+       if (0 != returnValue) {
+#if DEPLOYMENT_TARGET_MACOSX
+           if (MACH_PORT_NULL != timeoutPort) {
+               if (!destroyWaitSet) __CFPortSetRemove(timeoutPort, waitSet);
+               mk_timer_destroy(timeoutPort);
+           }
+#endif
+           return returnValue;
+       }
+        firstPass = false;
+    }
+}
+
+SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterval seconds, Boolean returnAfterSourceHandled) {     /* DOES CALLOUT */
+    CHECK_FOR_FORK();
+    if (__CFRunLoopIsDeallocating(rl)) return kCFRunLoopRunFinished;
+    __CFRunLoopLock(rl);
+    CFRunLoopModeRef currentMode = __CFRunLoopFindMode(rl, modeName, false);
+    if (NULL == currentMode || __CFRunLoopModeIsEmpty(rl, currentMode)) {
+       if (currentMode) __CFRunLoopModeUnlock(currentMode);
+       __CFRunLoopUnlock(rl);
+       return kCFRunLoopRunFinished;
+    }
+    uint32_t *previousStopped = (uint32_t *)rl->_stopped;
+    rl->_stopped = CFAllocatorAllocate(kCFAllocatorSystemDefault, 4 * sizeof(uint32_t), 0);
+    rl->_stopped[0] = 0x4346524C;
+    rl->_stopped[1] = 0x4346524C; // 'CFRL'
+    rl->_stopped[2] = 0x00000000; // here the value is stored
+    rl->_stopped[3] = 0x4346524C;
+    CFRunLoopModeRef previousMode = rl->_currentMode;
+    rl->_currentMode = currentMode;
+    __CFRunLoopUnlock(rl);
+    int32_t result;
+    __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopEntry);
+    result = __CFRunLoopRun(rl, currentMode, seconds, returnAfterSourceHandled, false);
+    __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit);
+    __CFRunLoopModeUnlock(currentMode);
+    __CFRunLoopLock(rl);
+    CFAllocatorDeallocate(kCFAllocatorSystemDefault, (uint32_t *)rl->_stopped);
+    rl->_stopped = previousStopped;
+    rl->_currentMode = previousMode;
+    __CFRunLoopUnlock(rl);
+    return result;
+}
+
+void CFRunLoopRun(void) {      /* DOES CALLOUT */
+    int32_t result;
+    do {
+        result = CFRunLoopRunSpecific(CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 1.0e10, false);
+        CHECK_FOR_FORK();
+    } while (kCFRunLoopRunStopped != result && kCFRunLoopRunFinished != result);
+}
+
+SInt32 CFRunLoopRunInMode(CFStringRef modeName, CFTimeInterval seconds, Boolean returnAfterSourceHandled) {     /* DOES CALLOUT */
+    CHECK_FOR_FORK();
+    return CFRunLoopRunSpecific(CFRunLoopGetCurrent(), modeName, seconds, returnAfterSourceHandled);
+}
+
+static void __CFRunLoopFindMinTimer(const void *value, void *ctx) {
+    CFRunLoopTimerRef rlt = (CFRunLoopTimerRef)value;
+    if (__CFIsValid(rlt)) {
+        CFRunLoopTimerRef *result = ctx;
+        if (NULL == *result || rlt->_fireTSR < (*result)->_fireTSR) {
+            *result = rlt;
+        }
+    }
+}
+
+static int64_t __CFRunLoopGetNextTimerFireTSR(CFRunLoopRef rl, CFRunLoopModeRef rlm) {
+    CFRunLoopTimerRef result = NULL;
+    int64_t fireTime = 0;
+    if (rlm) {
+       if (NULL != rlm->_timers && 0 < CFSetGetCount(rlm->_timers)) {
+           __CFRunLoopTimerFireTSRLock();
+           CFSetApplyFunction(rlm->_timers, (__CFRunLoopFindMinTimer), &result);
+            if (result)
+                fireTime = result->_fireTSR;
+           __CFRunLoopTimerFireTSRUnlock();
+       }
+        if (NULL != rlm->_submodes) {
+            CFIndex idx, cnt;
+            for (idx = 0, cnt = CFArrayGetCount(rlm->_submodes); idx < cnt; idx++) {
+                CFStringRef modeName = (CFStringRef)CFArrayGetValueAtIndex(rlm->_submodes, idx);
+                CFRunLoopModeRef subrlm;
+                subrlm = __CFRunLoopFindMode(rl, modeName, false);
+                if (NULL != subrlm) {
+                    int64_t newFireTime = __CFRunLoopGetNextTimerFireTSR(rl, subrlm);
+                    __CFRunLoopModeUnlock(subrlm);
+                    if (fireTime == 0 || (newFireTime != 0 && newFireTime < fireTime))
+                        fireTime = newFireTime;
+                }
+            }
+        }
+        __CFRunLoopModeUnlock(rlm);
+    }
+    return fireTime;
+}
+
+CFAbsoluteTime CFRunLoopGetNextTimerFireDate(CFRunLoopRef rl, CFStringRef modeName) {
+    CHECK_FOR_FORK();
+    CFRunLoopModeRef rlm;
+    int64_t fireTSR;
+    __CFRunLoopLock(rl);
+    rlm = __CFRunLoopFindMode(rl, modeName, false);
+    __CFRunLoopUnlock(rl);
+    fireTSR = __CFRunLoopGetNextTimerFireTSR(rl, rlm);
+    int64_t now2 = (int64_t)mach_absolute_time();
+    CFAbsoluteTime now1 = CFAbsoluteTimeGetCurrent();
+    return (0 == fireTSR) ? 0.0 : (now1 + __CFTSRToTimeInterval(fireTSR - now2));
+}
+
+Boolean CFRunLoopIsWaiting(CFRunLoopRef rl) {
+    CHECK_FOR_FORK();
+    return __CFRunLoopIsSleeping(rl);
+}
+
+void CFRunLoopWakeUp(CFRunLoopRef rl) {
+    CHECK_FOR_FORK();
+#if DEPLOYMENT_TARGET_MACOSX
+    kern_return_t ret;
+    /* We unconditionally try to send the message, since we don't want
+     * to lose a wakeup, but the send may fail if there is already a
+     * wakeup pending, since the queue length is 1. */
+    ret = __CFSendTrivialMachMessage(rl->_wakeUpPort, 0, MACH_SEND_TIMEOUT, 0);
+    if (ret != MACH_MSG_SUCCESS && ret != MACH_SEND_TIMED_OUT) {
+       HALT;
+    }
+#else
+    SetEvent(rl->_wakeUpPort);
+#endif
+}
+
+void CFRunLoopStop(CFRunLoopRef rl) {
+    CHECK_FOR_FORK();
+    __CFRunLoopLock(rl);
+    __CFRunLoopSetStopped(rl);
+    __CFRunLoopUnlock(rl);
+    CFRunLoopWakeUp(rl);
+}
+
+CF_EXPORT void _CFRunLoopStopMode(CFRunLoopRef rl, CFStringRef modeName) {
+    CHECK_FOR_FORK();
+    CFRunLoopModeRef rlm;
+    __CFRunLoopLock(rl);
+    rlm = __CFRunLoopFindMode(rl, modeName, true);
+    __CFRunLoopUnlock(rl);
+    if (NULL != rlm) {
+       rlm->_stopped = true;
+       __CFRunLoopModeUnlock(rlm);
+    }
+    CFRunLoopWakeUp(rl);
+}
+
+CF_EXPORT Boolean _CFRunLoopModeContainsMode(CFRunLoopRef rl, CFStringRef modeName, CFStringRef candidateContainedName) {
+    CHECK_FOR_FORK();
+    CFRunLoopModeRef rlm;
+    if (modeName == kCFRunLoopCommonModes || candidateContainedName == kCFRunLoopCommonModes) {
+       return false;
+    } else if (CFEqual(modeName, candidateContainedName)) {
+       return true;
+    }
+    __CFRunLoopLock(rl);
+    rlm = __CFRunLoopFindMode(rl, modeName, true);
+    __CFRunLoopUnlock(rl);
+    if (NULL != rlm) {
+       CFArrayRef submodes;
+       if (NULL == rlm->_submodes) {
+           __CFRunLoopModeUnlock(rlm);
+           return false;
+       }
+       if (CFArrayContainsValue(rlm->_submodes, CFRangeMake(0, CFArrayGetCount(rlm->_submodes)), candidateContainedName)) {
+           __CFRunLoopModeUnlock(rlm);
+           return true;
+       }
+       submodes = (NULL != rlm->_submodes && 0 < CFArrayGetCount(rlm->_submodes)) ? CFArrayCreateCopy(kCFAllocatorSystemDefault, rlm->_submodes) : NULL;
+       __CFRunLoopModeUnlock(rlm);
+       if (NULL != submodes) {
+           CFIndex idx, cnt;
+           for (idx = 0, cnt = CFArrayGetCount(submodes); idx < cnt; idx++) {
+               CFStringRef subname = (CFStringRef)CFArrayGetValueAtIndex(submodes, idx);
+               if (_CFRunLoopModeContainsMode(rl, subname, candidateContainedName)) {
+                   CFRelease(submodes);
+                   return true;
+               }
+           }
+           CFRelease(submodes);
+       }
+    }
+    return false;
+}
+
+CF_EXPORT void _CFRunLoopAddModeToMode(CFRunLoopRef rl, CFStringRef modeName, CFStringRef toModeName) {
+    CHECK_FOR_FORK();
+    CFRunLoopModeRef rlm;
+    if (__CFRunLoopIsDeallocating(rl)) return;
+    // should really do a recursive check here, to make sure that a cycle isn't
+    // introduced; of course, if that happens, you aren't going to get very far.
+    if (modeName == kCFRunLoopCommonModes || toModeName == kCFRunLoopCommonModes || CFEqual(modeName, toModeName)) {
+       return;
+    } else {
+       __CFRunLoopLock(rl);
+       rlm = __CFRunLoopFindMode(rl, toModeName, true);
+       __CFRunLoopUnlock(rl);
+       if (NULL != rlm) {
+           if (NULL == rlm->_submodes) {
+               rlm->_submodes = CFArrayCreateMutable(CFGetAllocator(rlm), 0, &kCFTypeArrayCallBacks);
+           }
+           if (!CFArrayContainsValue(rlm->_submodes, CFRangeMake(0, CFArrayGetCount(rlm->_submodes)), modeName)) {
+               CFArrayAppendValue(rlm->_submodes, modeName);
+           }
+           __CFRunLoopModeUnlock(rlm);
+       }
+    }
+}
+
+CF_EXPORT void _CFRunLoopRemoveModeFromMode(CFRunLoopRef rl, CFStringRef modeName, CFStringRef fromModeName) {
+    CHECK_FOR_FORK();
+    CFRunLoopModeRef rlm;
+    // should really do a recursive check here, to make sure that a cycle isn't
+    // introduced; of course, if that happens, you aren't going to get very far.
+    if (modeName == kCFRunLoopCommonModes || fromModeName == kCFRunLoopCommonModes || CFEqual(modeName, fromModeName)) {
+       return;
+    } else {
+       __CFRunLoopLock(rl);
+       rlm = __CFRunLoopFindMode(rl, fromModeName, true);
+       __CFRunLoopUnlock(rl);
+       if (NULL != rlm) {
+           if (NULL != rlm->_submodes) {
+               CFIndex idx, cnt = CFArrayGetCount(rlm->_submodes);
+               idx = CFArrayGetFirstIndexOfValue(rlm->_submodes, CFRangeMake(0, cnt), modeName);
+               if (0 <= idx) CFArrayRemoveValueAtIndex(rlm->_submodes, idx);
+           }
+           __CFRunLoopModeUnlock(rlm);
+       }
+    }
+}
+
+Boolean CFRunLoopContainsSource(CFRunLoopRef rl, CFRunLoopSourceRef rls, CFStringRef modeName) {
+    CHECK_FOR_FORK();
+    CFRunLoopModeRef rlm;
+    Boolean hasValue = false;
+    __CFRunLoopLock(rl);
+    if (modeName == kCFRunLoopCommonModes) {
+       if (NULL != rl->_commonModeItems) {
+           hasValue = CFSetContainsValue(rl->_commonModeItems, rls);
+       }
+       __CFRunLoopUnlock(rl);
+    } else {
+       rlm = __CFRunLoopFindMode(rl, modeName, false);
+       __CFRunLoopUnlock(rl);
+       if (NULL != rlm && NULL != rlm->_sources) {
+           hasValue = CFSetContainsValue(rlm->_sources, rls);
+           __CFRunLoopModeUnlock(rlm);
+       } else if (NULL != rlm) {
+           __CFRunLoopModeUnlock(rlm);
+       }
+    }
+    return hasValue;
+}
+
+void CFRunLoopAddSource(CFRunLoopRef rl, CFRunLoopSourceRef rls, CFStringRef modeName) {       /* DOES CALLOUT */
+    CHECK_FOR_FORK();
+    CFRunLoopModeRef rlm;
+    if (__CFRunLoopIsDeallocating(rl)) return;
+    if (!__CFIsValid(rls)) return;
+    __CFRunLoopLock(rl);
+    if (modeName == kCFRunLoopCommonModes) {
+       CFSetRef set = rl->_commonModes ? CFSetCreateCopy(kCFAllocatorSystemDefault, rl->_commonModes) : NULL;
+       if (NULL == rl->_commonModeItems) {
+           rl->_commonModeItems = CFSetCreateMutable(CFGetAllocator(rl), 0, &kCFTypeSetCallBacks);
+           _CFSetSetCapacity(rl->_commonModeItems, 20);
+       }
+       CFSetAddValue(rl->_commonModeItems, rls);
+       __CFRunLoopUnlock(rl);
+       if (NULL != set) {
+           CFTypeRef context[2] = {rl, rls};
+           /* add new item to all common-modes */
+           CFSetApplyFunction(set, (__CFRunLoopAddItemToCommonModes), (void *)context);
+           CFRelease(set);
+       }
+    } else {
+       rlm = __CFRunLoopFindMode(rl, modeName, true);
+       __CFRunLoopUnlock(rl);
+       if (NULL != rlm && NULL == rlm->_sources) {
+           rlm->_sources = CFSetCreateMutable(CFGetAllocator(rlm), 0, &kCFTypeSetCallBacks);
+           _CFSetSetCapacity(rlm->_sources, 10);
+       }
+       if (NULL != rlm && !CFSetContainsValue(rlm->_sources, rls)) {
+           CFSetAddValue(rlm->_sources, rls);
+           __CFRunLoopModeUnlock(rlm);
+           __CFRunLoopSourceSchedule(rls, rl, rlm);    /* DOES CALLOUT */
+       } else if (NULL != rlm) {
+           __CFRunLoopModeUnlock(rlm);
+       }
+    }
+}
+
+void CFRunLoopRemoveSource(CFRunLoopRef rl, CFRunLoopSourceRef rls, CFStringRef modeName) {    /* DOES CALLOUT */
+    CHECK_FOR_FORK();
+    CFRunLoopModeRef rlm;
+    __CFRunLoopLock(rl);
+    if (modeName == kCFRunLoopCommonModes) {
+       if (NULL != rl->_commonModeItems && CFSetContainsValue(rl->_commonModeItems, rls)) {
+           CFSetRef set = rl->_commonModes ? CFSetCreateCopy(kCFAllocatorSystemDefault, rl->_commonModes) : NULL;
+           CFSetRemoveValue(rl->_commonModeItems, rls);
+           __CFRunLoopUnlock(rl);
+           if (NULL != set) {
+               CFTypeRef context[2] = {rl, rls};
+               /* remove new item from all common-modes */
+               CFSetApplyFunction(set, (__CFRunLoopRemoveItemFromCommonModes), (void *)context);
+               CFRelease(set);
+           }
+       } else {
+           __CFRunLoopUnlock(rl);
+       }
+    } else {
+       rlm = __CFRunLoopFindMode(rl, modeName, false);
+       __CFRunLoopUnlock(rl);
+       if (NULL != rlm && NULL != rlm->_sources && CFSetContainsValue(rlm->_sources, rls)) {
+           CFRetain(rls);
+           CFSetRemoveValue(rlm->_sources, rls);
+           __CFRunLoopModeUnlock(rlm);
+           __CFRunLoopSourceCancel(rls, rl, rlm);      /* DOES CALLOUT */
+           CFRelease(rls);
+       } else if (NULL != rlm) {
+           __CFRunLoopModeUnlock(rlm);
+       }
+    }
+}
+
+Boolean CFRunLoopContainsObserver(CFRunLoopRef rl, CFRunLoopObserverRef rlo, CFStringRef modeName) {
+    CHECK_FOR_FORK();
+    CFRunLoopModeRef rlm;
+    Boolean hasValue = false;
+    __CFRunLoopLock(rl);
+    if (modeName == kCFRunLoopCommonModes) {
+       if (NULL != rl->_commonModeItems) {
+           hasValue = CFSetContainsValue(rl->_commonModeItems, rlo);
+       }
+       __CFRunLoopUnlock(rl);
+    } else {
+       rlm = __CFRunLoopFindMode(rl, modeName, false);
+       __CFRunLoopUnlock(rl);
+       if (NULL != rlm && NULL != rlm->_observers) {
+           hasValue = CFSetContainsValue(rlm->_observers, rlo);
+           __CFRunLoopModeUnlock(rlm);
+       } else if (NULL != rlm) {
+           __CFRunLoopModeUnlock(rlm);
+       }
+    }
+    return hasValue;
+}
+
+void CFRunLoopAddObserver(CFRunLoopRef rl, CFRunLoopObserverRef rlo, CFStringRef modeName) {
+    CHECK_FOR_FORK();
+    CFRunLoopModeRef rlm;
+    if (__CFRunLoopIsDeallocating(rl)) return;
+    if (!__CFIsValid(rlo) || (NULL != rlo->_runLoop && rlo->_runLoop != rl)) return;
+    __CFRunLoopLock(rl);
+    if (modeName == kCFRunLoopCommonModes) {
+       CFSetRef set = rl->_commonModes ? CFSetCreateCopy(kCFAllocatorSystemDefault, rl->_commonModes) : NULL;
+       if (NULL == rl->_commonModeItems) {
+           rl->_commonModeItems = CFSetCreateMutable(CFGetAllocator(rl), 0, &kCFTypeSetCallBacks);
+       }
+       CFSetAddValue(rl->_commonModeItems, rlo);
+       __CFRunLoopUnlock(rl);
+       if (NULL != set) {
+           CFTypeRef context[2] = {rl, rlo};
+           /* add new item to all common-modes */
+           CFSetApplyFunction(set, (__CFRunLoopAddItemToCommonModes), (void *)context);
+           CFRelease(set);
+       }
+    } else {
+       rlm = __CFRunLoopFindMode(rl, modeName, true);
+       __CFRunLoopUnlock(rl);
+       if (NULL != rlm && NULL == rlm->_observers) {
+           rlm->_observers = CFSetCreateMutable(CFGetAllocator(rlm), 0, &kCFTypeSetCallBacks);
+       }
+       if (NULL != rlm && !CFSetContainsValue(rlm->_observers, rlo)) {
+           CFSetAddValue(rlm->_observers, rlo);
+           __CFRunLoopModeUnlock(rlm);
+           __CFRunLoopObserverSchedule(rlo, rl, rlm);
+       } else if (NULL != rlm) {
+           __CFRunLoopModeUnlock(rlm);
+       }
+    }
+}
+
+void CFRunLoopRemoveObserver(CFRunLoopRef rl, CFRunLoopObserverRef rlo, CFStringRef modeName) {
+    CHECK_FOR_FORK();
+    CFRunLoopModeRef rlm;
+    __CFRunLoopLock(rl);
+    if (modeName == kCFRunLoopCommonModes) {
+       if (NULL != rl->_commonModeItems && CFSetContainsValue(rl->_commonModeItems, rlo)) {
+           CFSetRef set = rl->_commonModes ? CFSetCreateCopy(kCFAllocatorSystemDefault, rl->_commonModes) : NULL;
+           CFSetRemoveValue(rl->_commonModeItems, rlo);
+           __CFRunLoopUnlock(rl);
+           if (NULL != set) {
+               CFTypeRef context[2] = {rl, rlo};
+               /* remove new item from all common-modes */
+               CFSetApplyFunction(set, (__CFRunLoopRemoveItemFromCommonModes), (void *)context);
+               CFRelease(set);
+           }
+       } else {
+           __CFRunLoopUnlock(rl);
+       }
+    } else {
+       rlm = __CFRunLoopFindMode(rl, modeName, false);
+       __CFRunLoopUnlock(rl);
+       if (NULL != rlm && NULL != rlm->_observers && CFSetContainsValue(rlm->_observers, rlo)) {
+           CFRetain(rlo);
+           CFSetRemoveValue(rlm->_observers, rlo);
+           __CFRunLoopModeUnlock(rlm);
+           __CFRunLoopObserverCancel(rlo, rl, rlm);
+           CFRelease(rlo);
+       } else if (NULL != rlm) {
+           __CFRunLoopModeUnlock(rlm);
+       }
+    }
+}
+
+Boolean CFRunLoopContainsTimer(CFRunLoopRef rl, CFRunLoopTimerRef rlt, CFStringRef modeName) {
+    CHECK_FOR_FORK();
+    CFRunLoopModeRef rlm;
+    Boolean hasValue = false;
+    __CFRunLoopLock(rl);
+    if (modeName == kCFRunLoopCommonModes) {
+       if (NULL != rl->_commonModeItems) {
+           hasValue = CFSetContainsValue(rl->_commonModeItems, rlt);
+       }
+       __CFRunLoopUnlock(rl);
+    } else {
+       rlm = __CFRunLoopFindMode(rl, modeName, false);
+       __CFRunLoopUnlock(rl);
+       if (NULL != rlm && NULL != rlm->_timers) {
+           hasValue = CFSetContainsValue(rlm->_timers, rlt);
+           __CFRunLoopModeUnlock(rlm);
+       } else if (NULL != rlm) {
+           __CFRunLoopModeUnlock(rlm);
+       }
+    }
+    return hasValue;
+}
+
+void CFRunLoopAddTimer(CFRunLoopRef rl, CFRunLoopTimerRef rlt, CFStringRef modeName) {
+    CHECK_FOR_FORK();
+    CFRunLoopModeRef rlm;
+    if (__CFRunLoopIsDeallocating(rl)) return;
+    if (!__CFIsValid(rlt) || (NULL != rlt->_runLoop && rlt->_runLoop != rl)) return;
+    __CFRunLoopLock(rl);
+    if (modeName == kCFRunLoopCommonModes) {
+       CFSetRef set = rl->_commonModes ? CFSetCreateCopy(kCFAllocatorSystemDefault, rl->_commonModes) : NULL;
+       if (NULL == rl->_commonModeItems) {
+           rl->_commonModeItems = CFSetCreateMutable(CFGetAllocator(rl), 0, &kCFTypeSetCallBacks);
+       }
+       CFSetAddValue(rl->_commonModeItems, rlt);
+       __CFRunLoopUnlock(rl);
+       if (NULL != set) {
+           CFTypeRef context[2] = {rl, rlt};
+           /* add new item to all common-modes */
+           CFSetApplyFunction(set, (__CFRunLoopAddItemToCommonModes), (void *)context);
+           CFRelease(set);
+       }
+    } else {
+       rlm = __CFRunLoopFindMode(rl, modeName, true);
+       __CFRunLoopUnlock(rl);
+       if (NULL != rlm && NULL == rlm->_timers) {
+           rlm->_timers = CFSetCreateMutable(CFGetAllocator(rlm), 0, &kCFTypeSetCallBacks);
+       }
+       if (NULL != rlm && !CFSetContainsValue(rlm->_timers, rlt)) {
+           CFSetAddValue(rlm->_timers, rlt);
+           __CFRunLoopModeUnlock(rlm);
+           __CFRunLoopTimerSchedule(rlt, rl, rlm);
+       } else if (NULL != rlm) {
+           __CFRunLoopModeUnlock(rlm);
+       }
+    }
+}
+
+void CFRunLoopRemoveTimer(CFRunLoopRef rl, CFRunLoopTimerRef rlt, CFStringRef modeName) {
+    CHECK_FOR_FORK();
+    CFRunLoopModeRef rlm;
+    __CFRunLoopLock(rl);
+    if (modeName == kCFRunLoopCommonModes) {
+       if (NULL != rl->_commonModeItems && CFSetContainsValue(rl->_commonModeItems, rlt)) {
+           CFSetRef set = rl->_commonModes ? CFSetCreateCopy(kCFAllocatorSystemDefault, rl->_commonModes) : NULL;
+           CFSetRemoveValue(rl->_commonModeItems, rlt);
+           __CFRunLoopUnlock(rl);
+           if (NULL != set) {
+               CFTypeRef context[2] = {rl, rlt};
+               /* remove new item from all common-modes */
+               CFSetApplyFunction(set, (__CFRunLoopRemoveItemFromCommonModes), (void *)context);
+               CFRelease(set);
+           }
+       } else {
+           __CFRunLoopUnlock(rl);
+       }
+    } else {
+       rlm = __CFRunLoopFindMode(rl, modeName, false);
+       __CFRunLoopUnlock(rl);
+       if (NULL != rlm && NULL != rlm->_timers && CFSetContainsValue(rlm->_timers, rlt)) {
+           CFRetain(rlt);
+           CFSetRemoveValue(rlm->_timers, rlt);
+           __CFRunLoopModeUnlock(rlm);
+           __CFRunLoopTimerCancel(rlt, rl, rlm);
+           CFRelease(rlt);
+       } else if (NULL != rlm) {
+           __CFRunLoopModeUnlock(rlm);
+       }
+    }
+}
+
+
+/* CFRunLoopSource */
+
+static Boolean __CFRunLoopSourceEqual(CFTypeRef cf1, CFTypeRef cf2) {  /* DOES CALLOUT */
+    CFRunLoopSourceRef rls1 = (CFRunLoopSourceRef)cf1;
+    CFRunLoopSourceRef rls2 = (CFRunLoopSourceRef)cf2;
+    if (rls1 == rls2) return true;
+    if (rls1->_order != rls2->_order) return false;
+    if (rls1->_context.version0.version != rls2->_context.version0.version) return false;
+    if (rls1->_context.version0.hash != rls2->_context.version0.hash) return false;
+    if (rls1->_context.version0.equal != rls2->_context.version0.equal) return false;
+    if (0 == rls1->_context.version0.version && rls1->_context.version0.perform != rls2->_context.version0.perform) return false;
+    if (1 == rls1->_context.version0.version && rls1->_context.version1.perform != rls2->_context.version1.perform) return false;
+    if (rls1->_context.version0.equal)
+       return rls1->_context.version0.equal(rls1->_context.version0.info, rls2->_context.version0.info);
+    return (rls1->_context.version0.info == rls2->_context.version0.info);
+}
+
+static CFHashCode __CFRunLoopSourceHash(CFTypeRef cf) {        /* DOES CALLOUT */
+    CFRunLoopSourceRef rls = (CFRunLoopSourceRef)cf;
+    if (rls->_context.version0.hash)
+       return rls->_context.version0.hash(rls->_context.version0.info);
+    return (CFHashCode)rls->_context.version0.info;
+}
+
+static CFStringRef __CFRunLoopSourceCopyDescription(CFTypeRef cf) {    /* DOES CALLOUT */
+    CFRunLoopSourceRef rls = (CFRunLoopSourceRef)cf;
+    CFStringRef result;
+    CFStringRef contextDesc = NULL;
+    if (NULL != rls->_context.version0.copyDescription) {
+       contextDesc = rls->_context.version0.copyDescription(rls->_context.version0.info);
+    }
+    if (NULL == contextDesc) {
+       void *addr = rls->_context.version0.version == 0 ? (void *)rls->_context.version0.perform : (rls->_context.version0.version == 1 ? (void *)rls->_context.version1.perform : NULL);
+#if DEPLOYMENT_TARGET_MACOSX
+       Dl_info info;
+       const char *name = (dladdr(addr, &info) && info.dli_saddr == addr && info.dli_sname) ? info.dli_sname : "???";
+       contextDesc = CFStringCreateWithFormat(CFGetAllocator(rls), NULL, CFSTR("<CFRunLoopSource context>{version = %ld, info = %p, callout = %s (%p)}"), rls->_context.version0.version, rls->_context.version0.info, name, addr);
+#else
+#error Unknown or unspecified DEPLOYMENT_TARGET
+#endif
+    }
+result = CFStringCreateWithFormat(CFGetAllocator(rls), NULL, CFSTR("<CFRunLoopSource %p [%p]>{locked = %s, signalled = %s, valid = %s, order = %d, context = %@}"), cf, CFGetAllocator(rls), lockCount(rls->_lock) ? "Yes" : "No", __CFRunLoopSourceIsSignaled(rls) ? "Yes" : "No", __CFIsValid(rls) ? "Yes" : "No", rls->_order, contextDesc);
+    CFRelease(contextDesc);
+    return result;
+}
+
+static void __CFRunLoopSourceDeallocate(CFTypeRef cf) {        /* DOES CALLOUT */
+    CFRunLoopSourceRef rls = (CFRunLoopSourceRef)cf;
+    CFRunLoopSourceInvalidate(rls);
+    if (rls->_context.version0.release) {
+       rls->_context.version0.release(rls->_context.version0.info);
+    }
+}
+
+static const CFRuntimeClass __CFRunLoopSourceClass = {
+    _kCFRuntimeScannedObject,
+    "CFRunLoopSource",
+    NULL,      // init
+    NULL,      // copy
+    __CFRunLoopSourceDeallocate,
+    __CFRunLoopSourceEqual,
+    __CFRunLoopSourceHash,
+    NULL,      // 
+    __CFRunLoopSourceCopyDescription
+};
+
+__private_extern__ void __CFRunLoopSourceInitialize(void) {
+    __kCFRunLoopSourceTypeID = _CFRuntimeRegisterClass(&__CFRunLoopSourceClass);
+}
+
+CFTypeID CFRunLoopSourceGetTypeID(void) {
+    return __kCFRunLoopSourceTypeID;
+}
+
+CFRunLoopSourceRef CFRunLoopSourceCreate(CFAllocatorRef allocator, CFIndex order, CFRunLoopSourceContext *context) {
+    CHECK_FOR_FORK();
+    CFRunLoopSourceRef memory;
+    uint32_t size;
+    if (NULL == context) HALT;
+    size = sizeof(struct __CFRunLoopSource) - sizeof(CFRuntimeBase);
+    memory = (CFRunLoopSourceRef)_CFRuntimeCreateInstance(allocator, __kCFRunLoopSourceTypeID, size, NULL);
+    if (NULL == memory) {
+       return NULL;
+    }
+    __CFSetValid(memory);
+    __CFRunLoopSourceUnsetSignaled(memory);
+    CF_SPINLOCK_INIT_FOR_STRUCTS(memory->_lock);
+    memory->_bits = 0;
+    memory->_order = order;
+    memory->_runLoops = NULL;
+    size = 0;
+    switch (context->version) {
+    case 0:
+       size = sizeof(CFRunLoopSourceContext);
+       break;
+    case 1:
+       size = sizeof(CFRunLoopSourceContext1);
+       break;
+#if DEPLOYMENT_TARGET_MACOSX
+    case 2:
+       size = sizeof(CFRunLoopSourceContext2);
+       break;
+#endif
+    }
+    CF_WRITE_BARRIER_MEMMOVE(&memory->_context, context, size);
+    if (context->retain) {
+       memory->_context.version0.info = (void *)context->retain(context->info);
+    }
+    return memory;
+}
+
+CFIndex CFRunLoopSourceGetOrder(CFRunLoopSourceRef rls) {
+    CHECK_FOR_FORK();
+    __CFGenericValidateType(rls, __kCFRunLoopSourceTypeID);
+    return rls->_order;
+}
+
+static void __CFRunLoopSourceRemoveFromRunLoop(const void *value, void *context) {
+    CFRunLoopRef rl = (CFRunLoopRef)value;
+    CFTypeRef *params = context;
+    CFRunLoopSourceRef rls = (CFRunLoopSourceRef)params[0];
+    CFArrayRef array;
+    CFIndex idx;
+    if (rl == params[1]) return;
+    array = CFRunLoopCopyAllModes(rl);
+    for (idx = CFArrayGetCount(array); idx--;) {
+       CFStringRef modeName = CFArrayGetValueAtIndex(array, idx);
+       CFRunLoopRemoveSource(rl, rls, modeName);
+    }
+    CFRunLoopRemoveSource(rl, rls, kCFRunLoopCommonModes);
+    CFRelease(array);
+    params[1] = rl;
+}
+
+void CFRunLoopSourceInvalidate(CFRunLoopSourceRef rls) {
+    CHECK_FOR_FORK();
+    __CFGenericValidateType(rls, __kCFRunLoopSourceTypeID);
+    CFRetain(rls);
+    __CFRunLoopSourceLock(rls);
+    if (__CFIsValid(rls)) {
+       __CFUnsetValid(rls);
+        __CFRunLoopSourceUnsetSignaled(rls);
+       if (NULL != rls->_runLoops) {
+           CFTypeRef params[2] = {rls, NULL};
+           CFBagRef bag = CFBagCreateCopy(kCFAllocatorSystemDefault, rls->_runLoops);
+           CFRelease(rls->_runLoops);
+           rls->_runLoops = NULL;
+           __CFRunLoopSourceUnlock(rls);
+           CFBagApplyFunction(bag, (__CFRunLoopSourceRemoveFromRunLoop), params);
+           CFRelease(bag);
+       } else {
+           __CFRunLoopSourceUnlock(rls);
+       }
+       /* for hashing- and equality-use purposes, can't actually release the context here */
+    } else {
+       __CFRunLoopSourceUnlock(rls);
+    }
+    CFRelease(rls);
+}
+
+Boolean CFRunLoopSourceIsValid(CFRunLoopSourceRef rls) {
+    CHECK_FOR_FORK();
+    __CFGenericValidateType(rls, __kCFRunLoopSourceTypeID);
+    return __CFIsValid(rls);
+}
+
+void CFRunLoopSourceGetContext(CFRunLoopSourceRef rls, CFRunLoopSourceContext *context) {
+    CHECK_FOR_FORK();
+    __CFGenericValidateType(rls, __kCFRunLoopSourceTypeID);
+    CFAssert1(0 == context->version || 1 == context->version, __kCFLogAssertion, "%s(): context version not initialized to 0 or 1", __PRETTY_FUNCTION__);
+    CFIndex size = 0;
+    switch (context->version) {
+    case 0:
+       size = sizeof(CFRunLoopSourceContext);
+       break;
+    case 1:
+       size = sizeof(CFRunLoopSourceContext1);
+       break;
+#if DEPLOYMENT_TARGET_MACOSX
+    case 2:
+       size = sizeof(CFRunLoopSourceContext2);
+       break;
+#endif
+    }
+    memmove(context, &rls->_context, size);
+}
+
+void CFRunLoopSourceSignal(CFRunLoopSourceRef rls) {
+    CHECK_FOR_FORK();
+    __CFRunLoopSourceLock(rls);
+    if (__CFIsValid(rls)) {
+       __CFRunLoopSourceSetSignaled(rls);
+    }
+    __CFRunLoopSourceUnlock(rls);
+}
+
+Boolean CFRunLoopSourceIsSignalled(CFRunLoopSourceRef rls) {
+    CHECK_FOR_FORK();
+    __CFRunLoopSourceLock(rls);
+    Boolean ret = __CFRunLoopSourceIsSignaled(rls) ? true : false;
+    __CFRunLoopSourceUnlock(rls);
+    return ret;
+}
+
+/* CFRunLoopObserver */
+
+static CFStringRef __CFRunLoopObserverCopyDescription(CFTypeRef cf) {  /* DOES CALLOUT */
+    CFRunLoopObserverRef rlo = (CFRunLoopObserverRef)cf;
+    CFStringRef result;
+    CFStringRef contextDesc = NULL;
+    if (NULL != rlo->_context.copyDescription) {
+       contextDesc = rlo->_context.copyDescription(rlo->_context.info);
+    }
+    if (!contextDesc) {
+       contextDesc = CFStringCreateWithFormat(CFGetAllocator(rlo), NULL, CFSTR("<CFRunLoopObserver context %p>"), rlo->_context.info);
+    }
+#if DEPLOYMENT_TARGET_MACOSX
+    void *addr = rlo->_callout;
+    Dl_info info;
+    const char *name = (dladdr(addr, &info) && info.dli_saddr == addr && info.dli_sname) ? info.dli_sname : "???";
+    result = CFStringCreateWithFormat(CFGetAllocator(rlo), NULL, CFSTR("<CFRunLoopObserver %p [%p]>{locked = %s, valid = %s, activities = 0x%x, repeats = %s, order = %d, callout = %s (%p), context = %@}"), cf, CFGetAllocator(rlo), lockCount(rlo->_lock) ? "Yes" : "No", __CFIsValid(rlo) ? "Yes" : "No", rlo->_activities, __CFRunLoopObserverRepeats(rlo) ? "Yes" : "No", rlo->_order, name, addr, contextDesc);
+#else
+#error Unknown or unspecified DEPLOYMENT_TARGET
+#endif
+    CFRelease(contextDesc);
+    return result;
+}
+
+static void __CFRunLoopObserverDeallocate(CFTypeRef cf) {      /* DOES CALLOUT */
+    CFRunLoopObserverRef rlo = (CFRunLoopObserverRef)cf;
+    CFRunLoopObserverInvalidate(rlo);
+}
+
+static const CFRuntimeClass __CFRunLoopObserverClass = {
+    0,
+    "CFRunLoopObserver",
+    NULL,      // init
+    NULL,      // copy
+    __CFRunLoopObserverDeallocate,
+    NULL,
+    NULL,
+    NULL,      // 
+    __CFRunLoopObserverCopyDescription
+};
+
+__private_extern__ void __CFRunLoopObserverInitialize(void) {
+    __kCFRunLoopObserverTypeID = _CFRuntimeRegisterClass(&__CFRunLoopObserverClass);
+}
+
+CFTypeID CFRunLoopObserverGetTypeID(void) {
+    return __kCFRunLoopObserverTypeID;
+}
+
+CFRunLoopObserverRef CFRunLoopObserverCreate(CFAllocatorRef allocator, CFOptionFlags activities, Boolean repeats, CFIndex order, CFRunLoopObserverCallBack callout, CFRunLoopObserverContext *context) {
+    CHECK_FOR_FORK();
+    CFRunLoopObserverRef memory;
+    UInt32 size;
+    size = sizeof(struct __CFRunLoopObserver) - sizeof(CFRuntimeBase);
+    memory = (CFRunLoopObserverRef)_CFRuntimeCreateInstance(allocator, __kCFRunLoopObserverTypeID, size, NULL);
+    if (NULL == memory) {
+       return NULL;
+    }
+    __CFSetValid(memory);
+    __CFRunLoopObserverUnsetFiring(memory);
+    if (repeats) {
+       __CFRunLoopObserverSetRepeats(memory);
+    } else {
+       __CFRunLoopObserverUnsetRepeats(memory);
+    }
+    CF_SPINLOCK_INIT_FOR_STRUCTS(memory->_lock);
+    memory->_runLoop = NULL;
+    memory->_rlCount = 0;
+    memory->_activities = activities;
+    memory->_order = order;
+    memory->_callout = callout;
+    if (context) {
+       if (context->retain) {
+           memory->_context.info = (void *)context->retain(context->info);
+       } else {
+           memory->_context.info = context->info;
+       }
+       memory->_context.retain = context->retain;
+       memory->_context.release = context->release;
+       memory->_context.copyDescription = context->copyDescription;
+    } else {
+       memory->_context.info = 0;
+       memory->_context.retain = 0;
+       memory->_context.release = 0;
+       memory->_context.copyDescription = 0;
+    }
+    return memory;
+}
+
+CFOptionFlags CFRunLoopObserverGetActivities(CFRunLoopObserverRef rlo) {
+    CHECK_FOR_FORK();
+    __CFGenericValidateType(rlo, __kCFRunLoopObserverTypeID);
+    return rlo->_activities;
+}
+
+CFIndex CFRunLoopObserverGetOrder(CFRunLoopObserverRef rlo) {
+    CHECK_FOR_FORK();
+    __CFGenericValidateType(rlo, __kCFRunLoopObserverTypeID);
+    return rlo->_order;
+}
+
+Boolean CFRunLoopObserverDoesRepeat(CFRunLoopObserverRef rlo) {
+    CHECK_FOR_FORK();
+    __CFGenericValidateType(rlo, __kCFRunLoopObserverTypeID);
+    return __CFRunLoopObserverRepeats(rlo);
+}
+
+void CFRunLoopObserverInvalidate(CFRunLoopObserverRef rlo) {   /* DOES CALLOUT */
+    CHECK_FOR_FORK();
+    __CFGenericValidateType(rlo, __kCFRunLoopObserverTypeID);
+    CFRetain(rlo);
+    __CFRunLoopObserverLock(rlo);
+    if (__CFIsValid(rlo)) {
+       CFRunLoopRef rl = rlo->_runLoop;
+       __CFUnsetValid(rlo);
+       __CFRunLoopObserverUnlock(rlo);
+       if (NULL != rl) {
+           CFArrayRef array;
+           CFIndex idx;
+           array = CFRunLoopCopyAllModes(rl);
+           for (idx = CFArrayGetCount(array); idx--;) {
+               CFStringRef modeName = CFArrayGetValueAtIndex(array, idx);
+               CFRunLoopRemoveObserver(rl, rlo, modeName);
+           }
+           CFRunLoopRemoveObserver(rl, rlo, kCFRunLoopCommonModes);
+           CFRelease(array);
+       }
+       if (rlo->_context.release)
+           rlo->_context.release(rlo->_context.info);  /* CALLOUT */
+       rlo->_context.info = NULL;
+    } else {
+       __CFRunLoopObserverUnlock(rlo);
+    }
+    CFRelease(rlo);
+}
+
+Boolean CFRunLoopObserverIsValid(CFRunLoopObserverRef rlo) {
+    CHECK_FOR_FORK();
+    return __CFIsValid(rlo);
+}
+
+void CFRunLoopObserverGetContext(CFRunLoopObserverRef rlo, CFRunLoopObserverContext *context) {
+    CHECK_FOR_FORK();
+    __CFGenericValidateType(rlo, __kCFRunLoopObserverTypeID);
+    CFAssert1(0 == context->version, __kCFLogAssertion, "%s(): context version not initialized to 0", __PRETTY_FUNCTION__);
+    *context = rlo->_context;
+}
+
+/* CFRunLoopTimer */
+
+static CFStringRef __CFRunLoopTimerCopyDescription(CFTypeRef cf) {     /* DOES CALLOUT */
+    CFRunLoopTimerRef rlt = (CFRunLoopTimerRef)cf;
+    CFStringRef result;
+    CFStringRef contextDesc = NULL;
+    int64_t fireTime;
+    __CFRunLoopTimerFireTSRLock();
+    fireTime = rlt->_fireTSR;
+    __CFRunLoopTimerFireTSRUnlock();
+    if (NULL != rlt->_context.copyDescription) {
+       contextDesc = rlt->_context.copyDescription(rlt->_context.info);
+    }
+    if (NULL == contextDesc) {
+       contextDesc = CFStringCreateWithFormat(CFGetAllocator(rlt), NULL, CFSTR("<CFRunLoopTimer context %p>"), rlt->_context.info);
+    }
+    int64_t now2 = (int64_t)mach_absolute_time();
+    CFAbsoluteTime now1 = CFAbsoluteTimeGetCurrent();
+#if DEPLOYMENT_TARGET_MACOSX
+    void *addr = rlt->_callout;
+    Dl_info info;
+    const char *name = (dladdr(addr, &info) && info.dli_saddr == addr && info.dli_sname) ? info.dli_sname : "???";
+    result = CFStringCreateWithFormat(CFGetAllocator(rlt), NULL, CFSTR("<CFRunLoopTimer %p [%p]>{locked = %s, valid = %s, interval = %0.09g, next fire date = %0.09g, order = %d, callout = %s (%p), context = %@}"), cf, CFGetAllocator(rlt), lockCount(rlt->_lock) ? "Yes" : "No", __CFIsValid(rlt) ? "Yes" : "No", __CFTSRToTimeInterval(rlt->_intervalTSR), now1 + __CFTSRToTimeInterval(fireTime - now2), rlt->_order, name, addr, contextDesc);
+#else
+#error Unknown or unspecified DEPLOYMENT_TARGET
+#endif
+    CFRelease(contextDesc);
+    return result;
+}
+
+static void __CFRunLoopTimerDeallocate(CFTypeRef cf) { /* DOES CALLOUT */
+    CFRunLoopTimerRef rlt = (CFRunLoopTimerRef)cf;
+    CFRunLoopTimerInvalidate(rlt);     /* DOES CALLOUT */
+}
+
+static const CFRuntimeClass __CFRunLoopTimerClass = {
+    0,
+    "CFRunLoopTimer",
+    NULL,      // init
+    NULL,      // copy
+    __CFRunLoopTimerDeallocate,
+    NULL,      // equal
+    NULL,
+    NULL,      // 
+    __CFRunLoopTimerCopyDescription
+};
+
+__private_extern__ void __CFRunLoopTimerInitialize(void) {
+    __kCFRunLoopTimerTypeID = _CFRuntimeRegisterClass(&__CFRunLoopTimerClass);
+}
+
+CFTypeID CFRunLoopTimerGetTypeID(void) {
+    return __kCFRunLoopTimerTypeID;
+}
+
+CFRunLoopTimerRef CFRunLoopTimerCreate(CFAllocatorRef allocator, CFAbsoluteTime fireDate, CFTimeInterval interval, CFOptionFlags flags, CFIndex order, CFRunLoopTimerCallBack callout, CFRunLoopTimerContext *context) {
+    CHECK_FOR_FORK();
+    CFRunLoopTimerRef memory;
+    UInt32 size;
+    size = sizeof(struct __CFRunLoopTimer) - sizeof(CFRuntimeBase);
+    memory = (CFRunLoopTimerRef)_CFRuntimeCreateInstance(allocator, __kCFRunLoopTimerTypeID, size, NULL);
+    if (NULL == memory) {
+       return NULL;
+    }
+    __CFSetValid(memory);
+    __CFRunLoopTimerUnsetFiring(memory);
+    __CFRunLoopTimerUnsetDidFire(memory);
+    CF_SPINLOCK_INIT_FOR_STRUCTS(memory->_lock);
+    memory->_runLoop = NULL;
+    memory->_rlCount = 0;
+#if DEPLOYMENT_TARGET_MACOSX
+    memory->_port = MACH_PORT_NULL;
+#endif
+    memory->_order = order;
+    int64_t now2 = (int64_t)mach_absolute_time();
+    CFAbsoluteTime now1 = CFAbsoluteTimeGetCurrent();
+    if (3.1556952e+9 < fireDate) fireDate = 3.1556952e+9;
+    if (fireDate < now1) {
+       memory->_fireTSR = now2;
+    } else if (now1 + __CFTSRToTimeInterval(LLONG_MAX) < fireDate) {
+       memory->_fireTSR = LLONG_MAX;
+    } else {
+       memory->_fireTSR = now2 + __CFTimeIntervalToTSR(fireDate - now1);
+    }
+    if (3.1556952e+9 < interval) interval = 3.1556952e+9;
+    if (interval <= 0.0) {
+       memory->_intervalTSR = 0;
+    } else if (__CFTSRToTimeInterval(LLONG_MAX) < interval) {
+       memory->_intervalTSR = LLONG_MAX;
+    } else {
+       memory->_intervalTSR = __CFTimeIntervalToTSR(interval);
+    }
+    memory->_callout = callout;
+    if (NULL != context) {
+       if (context->retain) {
+           memory->_context.info = (void *)context->retain(context->info);
+       } else {
+           memory->_context.info = context->info;
+       }
+       memory->_context.retain = context->retain;
+       memory->_context.release = context->release;
+       memory->_context.copyDescription = context->copyDescription;
+    } else {
+       memory->_context.info = 0;
+       memory->_context.retain = 0;
+       memory->_context.release = 0;
+       memory->_context.copyDescription = 0;
+    }
+    return memory;
+}
+
+CFAbsoluteTime CFRunLoopTimerGetNextFireDate(CFRunLoopTimerRef rlt) {
+    CHECK_FOR_FORK();
+    int64_t fireTime, result = 0;
+    CF_OBJC_FUNCDISPATCH0(__kCFRunLoopTimerTypeID, CFAbsoluteTime, rlt, "_cffireTime");
+    __CFGenericValidateType(rlt, __kCFRunLoopTimerTypeID);
+    __CFRunLoopTimerFireTSRLock();
+    fireTime = rlt->_fireTSR;
+    __CFRunLoopTimerFireTSRUnlock();
+    __CFRunLoopTimerLock(rlt);
+    if (__CFIsValid(rlt)) {
+       result = fireTime;
+    }
+    __CFRunLoopTimerUnlock(rlt);
+    int64_t now2 = (int64_t)mach_absolute_time();
+    CFAbsoluteTime now1 = CFAbsoluteTimeGetCurrent();
+    return (0 == result) ? 0.0 : now1 + __CFTSRToTimeInterval(result - now2);
+}
+
+void CFRunLoopTimerSetNextFireDate(CFRunLoopTimerRef rlt, CFAbsoluteTime fireDate) {
+    CHECK_FOR_FORK();
+    __CFRunLoopTimerFireTSRLock();
+    int64_t now2 = (int64_t)mach_absolute_time();
+    CFAbsoluteTime now1 = CFAbsoluteTimeGetCurrent();
+    if (3.1556952e+9 < fireDate) fireDate = 3.1556952e+9;
+    if (fireDate < now1) {
+       rlt->_fireTSR = now2;
+    } else if (now1 + __CFTSRToTimeInterval(LLONG_MAX) < fireDate) {
+       rlt->_fireTSR = LLONG_MAX;
+    } else {
+       rlt->_fireTSR = now2 + __CFTimeIntervalToTSR(fireDate - now1);
+    }
+    if (rlt->_runLoop != NULL) {
+       __CFRunLoopTimerRescheduleWithAllModes(rlt, rlt->_runLoop);
+    }
+    __CFRunLoopTimerFireTSRUnlock();
+}
+
+CFTimeInterval CFRunLoopTimerGetInterval(CFRunLoopTimerRef rlt) {
+    CHECK_FOR_FORK();
+    CF_OBJC_FUNCDISPATCH0(__kCFRunLoopTimerTypeID, CFTimeInterval, rlt, "timeInterval");
+    __CFGenericValidateType(rlt, __kCFRunLoopTimerTypeID);
+    return __CFTSRToTimeInterval(rlt->_intervalTSR);
+}
+
+Boolean CFRunLoopTimerDoesRepeat(CFRunLoopTimerRef rlt) {
+    CHECK_FOR_FORK();
+    __CFGenericValidateType(rlt, __kCFRunLoopTimerTypeID);
+    return (0 != rlt->_intervalTSR);
+}
+
+CFIndex CFRunLoopTimerGetOrder(CFRunLoopTimerRef rlt) {
+    CHECK_FOR_FORK();
+    CF_OBJC_FUNCDISPATCH0(__kCFRunLoopTimerTypeID, CFIndex, rlt, "order");
+    __CFGenericValidateType(rlt, __kCFRunLoopTimerTypeID);
+    return rlt->_order;
+}
+
+void CFRunLoopTimerInvalidate(CFRunLoopTimerRef rlt) { /* DOES CALLOUT */
+    CHECK_FOR_FORK();
+    CF_OBJC_FUNCDISPATCH0(__kCFRunLoopTimerTypeID, void, rlt, "invalidate");
+    __CFGenericValidateType(rlt, __kCFRunLoopTimerTypeID);
+    CFRetain(rlt);
+    __CFRunLoopTimerLock(rlt);
+    if (__CFIsValid(rlt)) {
+       CFRunLoopRef rl = rlt->_runLoop;
+       void *info = rlt->_context.info;
+       __CFUnsetValid(rlt);
+#if DEPLOYMENT_TARGET_MACOSX
+       __CFRunLoopTimerPortMapLock();
+       if (NULL != __CFRLTPortMap) {
+           CFDictionaryRemoveValue(__CFRLTPortMap, (void *)(uintptr_t)rlt->_port);
+       }
+       __CFRunLoopTimerPortMapUnlock();
+       mk_timer_destroy(rlt->_port);
+       rlt->_port = MACH_PORT_NULL;
+#endif
+       rlt->_context.info = NULL;
+       __CFRunLoopTimerUnlock(rlt);
+       if (NULL != rl) {
+           CFArrayRef array;
+           CFIndex idx;
+           array = CFRunLoopCopyAllModes(rl);
+           for (idx = CFArrayGetCount(array); idx--;) {
+               CFStringRef modeName = CFArrayGetValueAtIndex(array, idx);
+               CFRunLoopRemoveTimer(rl, rlt, modeName);
+           }
+           CFRunLoopRemoveTimer(rl, rlt, kCFRunLoopCommonModes);
+           CFRelease(array);
+       }
+       if (NULL != rlt->_context.release) {
+           rlt->_context.release(info);        /* CALLOUT */
+       }
+    } else {
+       __CFRunLoopTimerUnlock(rlt);
+    }
+    CFRelease(rlt);
+}
+
+Boolean CFRunLoopTimerIsValid(CFRunLoopTimerRef rlt) {
+    CHECK_FOR_FORK();
+    CF_OBJC_FUNCDISPATCH0(__kCFRunLoopTimerTypeID, Boolean, rlt, "isValid");
+    __CFGenericValidateType(rlt, __kCFRunLoopTimerTypeID);
+    return __CFIsValid(rlt);
+}
+
+void CFRunLoopTimerGetContext(CFRunLoopTimerRef rlt, CFRunLoopTimerContext *context) {
+    CHECK_FOR_FORK();
+    __CFGenericValidateType(rlt, __kCFRunLoopTimerTypeID);
+    CFAssert1(0 == context->version, __kCFLogAssertion, "%s(): context version not initialized to 0", __PRETTY_FUNCTION__);
+    *context = rlt->_context;
+}
+
+#endif
+