1、CFRunLoopModeRef 什么时候创建的?
__CFRunLoopRun 源码, 去掉windows、disaptch_timer 支持
static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInterval seconds, Boolean stopAfterHandle, CFRunLoopModeRef previousMode) {uint64_t startTSR &#61; mach_absolute_time();/* 首先判断 CFRunLoopRef 是否停止&#xff0c;停止的话&#xff0c;重置停止状态并且返回停止状态 */if (__CFRunLoopIsStopped(rl)) {/* 是否设置了停止位 */__CFRunLoopUnsetStopped(rl);/* 重置停止位、并返回停止状态 */return kCFRunLoopRunStopped;} else if (rlm->_stopped) {/* 这个模式下是否停止了、并且重置模式停止状态 */rlm->_stopped &#61; false;/* 返回停止 */return kCFRunLoopRunStopped;}mach_port_name_t dispatchPort &#61; MACH_PORT_NULL; /* 主线程端口或者空 */Boolean libdispatchQSafe &#61; pthread_main_np() && ((HANDLE_DISPATCH_ON_BASE_INVOCATION_ONLY && NULL &#61;&#61; previousMode) || (!HANDLE_DISPATCH_ON_BASE_INVOCATION_ONLY && 0 &#61;&#61; _CFGetTSD(__CFTSDKeyIsInGCDMainQ)));if (libdispatchQSafe && (CFRunLoopGetMain() &#61;&#61; rl) && CFSetContainsValue(rl->_commonModes, rlm->_name)) dispatchPort &#61; _dispatch_get_main_queue_port_4CF(); /* libDispatch -> private.h *//* 定义一个 dispatch_source_t 为了CFRunLoopRunInMode 自定义时间时存在&#xff0c;为了做唤醒使用 */dispatch_source_t timeout_timer &#61; NULL;struct __timeout_context *timeout_context &#61; (struct __timeout_context *)malloc(sizeof(*timeout_context));if (seconds <&#61; 0.0) { // instant timeoutseconds &#61; 0.0;timeout_context->termTSR &#61; 0ULL;} else if (seconds <&#61; TIMER_INTERVAL_LIMIT/* TIMER_INTERVAL_LIMIT 504911232.0*/) {/* 尝试超时后唤醒&#xff0c;如果当前线程出于等待状态的情况下 */dispatch_queue_t queue &#61; pthread_main_np() ? __CFDispatchQueueGetGenericMatchingMain() : __CFDispatchQueueGetGenericBackground();/* 创建source */timeout_timer &#61; dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);dispatch_retain(timeout_timer);/* 写入source 的 上下文中 */timeout_context->ds &#61; timeout_timer;timeout_context->rl &#61; (CFRunLoopRef)CFRetain(rl);timeout_context->termTSR &#61; startTSR &#43; __CFTimeIntervalToTSR(seconds);/* 设置source的上下文 */dispatch_set_context(timeout_timer, timeout_context); // source gets ownership of context/* 设置时间事件的回调函数&#xff0c;调用了CFRunLoopWakeUp, 这个函数向等待端口发送了一个消息, 用来激活循环 */dispatch_source_set_event_handler_f(timeout_timer, __CFRunLoopTimeout);/* 设置时间事件的取消函数 */dispatch_source_set_cancel_handler_f(timeout_timer, __CFRunLoopTimeoutCancel);/* 计算触发的时间点(纳秒) */uint64_t ns_at &#61; (uint64_t)((__CFTSRToTimeInterval(startTSR) &#43; seconds) * 1000000000ULL);/* 设置source的timer, 仅仅延迟执行一次 */dispatch_source_set_timer(timeout_timer, dispatch_time(1, ns_at)/* start */, DISPATCH_TIME_FOREVER/* interval */, 1000ULL); /* 只执行一次 *//* 唤醒source */dispatch_resume(timeout_timer);} else { // infinite timeoutseconds &#61; 9999999999.0;timeout_context->termTSR &#61; UINT64_MAX;}Boolean didDispatchPortLastTime &#61; true;int32_t retVal &#61; 0;do {voucher_mach_msg_state_t voucherState &#61; VOUCHER_MACH_MSG_STATE_UNCHANGED;voucher_t voucherCopy &#61; NULL;/* 定义mach接收 msg 缓冲区 3k 大小 */uint8_t msg_buffer[3 * 1024]; /* 3K */mach_msg_header_t *msg &#61; NULL;mach_port_t livePort &#61; MACH_PORT_NULL;/* CFRunLoopModeRef->_portSet 实际上就是 mach_port_t -->>> __CFPort OR __CFPortSet */__CFPortSet waitSet &#61; rlm->_portSet; /* mac 下 就是 mach_port_t 等待端口集合 *//* 重置 CFRunLoopRef->_perRunData->ignoreWakeUps &#61; 0x57414B45; WAKUP 标识 */__CFRunLoopUnsetIgnoreWakeUps(rl);/* 回调 Before Timer && Source */if (rlm->_observerMask & kCFRunLoopBeforeTimers) __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeTimers);if (rlm->_observerMask & kCFRunLoopBeforeSources) __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeSources);/* 回调block, 只能回到一次block&#xff1f; */__CFRunLoopDoBlocks(rl, rlm);/* source0 是否handled(回调) */Boolean sourceHandledThisLoop &#61; __CFRunLoopDoSources0(rl, rlm, stopAfterHandle/* __CFRunLoopRun 参数 */); //source 0 必须signedif (sourceHandledThisLoop) {/* 回调了Source0 */__CFRunLoopDoBlocks(rl, rlm); //source 0}/* 确定端口集合接收消息是否设置永远超时&#xff0c;如果poll为真&#xff0c;则立即返回&#xff0c;否则无限等待直到有消息过来 */Boolean poll &#61; sourceHandledThisLoop || (0ULL &#61;&#61; timeout_context->termTSR); /* 从CFRunLoopRun 过来的话 timeout_context->termTSR 永远不等于0*/if (MACH_PORT_NULL !&#61; dispatchPort && !didDispatchPortLastTime) {/* 首次循环不执行&#xff0c;因为外部定义 didDispatchPortLastTime 为 true */msg &#61; (mach_msg_header_t *)msg_buffer;if (__CFRunLoopServiceMachPort(dispatchPort, &msg, sizeof(msg_buffer), &livePort, 0/*timeout &#61;&#61; 0*/, &voucherState, NULL)) {/* 主队列接收消息,接收消息成功则跳转到处理消息过程source1 */goto handle_msg;}}/* 执行到这里意味着 dispatchPort 没有成功接收到 mach message */didDispatchPortLastTime &#61; false; /* do while 循环外定义&#xff0c;初始化值 true *//* 没有回调并且timerTSR 大于 0 的情况下 并且 有等待掩码&#xff0c; poll 定义为 -> source0 处理了 或者 定义唤醒时间为0 */if (!poll && (rlm->_observerMask & kCFRunLoopBeforeWaiting)) __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeWaiting);/* 设置CFRunLoopRef 睡眠标志位。因为后面有进行一个 mach_msg 的等待操作 */__CFRunLoopSetSleeping(rl);__CFPortSetInsert(dispatchPort, waitSet); /* 将主端口 插入等待集合中 */ __CFRunLoopModeUnlock(rlm);__CFRunLoopUnlock(rl);CFAbsoluteTime sleepStart &#61; poll ? 0.0 : CFAbsoluteTimeGetCurrent();if (kCFUseCollectableAllocator) {memset(msg_buffer, 0, sizeof(msg_buffer));}msg &#61; (mach_msg_header_t *)msg_buffer;__CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), &livePort, poll ? 0 : TIMEOUT_INFINITY, &voucherState, &voucherCopy);__CFRunLoopLock(rl);__CFRunLoopModeLock(rlm);rl->_sleepTime &#43;&#61; (poll ? 0.0 : (CFAbsoluteTimeGetCurrent() - sleepStart));/* 从端口集合中移除 disaptchPort */__CFPortSetRemove(dispatchPort, waitSet); __CFRunLoopSetIgnoreWakeUps(rl);// user callouts now OK again __CFRunLoopUnsetSleeping(rl); //重置睡眠状态/* pool代表&#xff1a; 回调过 或者 触发时间为0&#xff0c; 根据掩码进行回调 */if (!poll && (rlm->_observerMask & kCFRunLoopAfterWaiting)) __CFRunLoopDoObservers(rl, rlm, kCFRunLoopAfterWaiting);/* 处理 mach 消息成功的标签*/handle_msg:;__CFRunLoopSetIgnoreWakeUps(rl);if (MACH_PORT_NULL &#61;&#61; livePort) {CFRUNLOOP_WAKEUP_FOR_NOTHING();} else if (livePort &#61;&#61; rl->_wakeUpPort) {CFRUNLOOP_WAKEUP_FOR_WAKEUP();} else if (rlm->_timerPort !&#61; MACH_PORT_NULL && livePort &#61;&#61; rlm->_timerPort) {CFRUNLOOP_WAKEUP_FOR_TIMER();if (!__CFRunLoopDoTimers(rl, rlm, mach_absolute_time())) {// Re-arm the next timer__CFArmNextTimerInMode(rlm, rl);}} else if (livePort &#61;&#61; dispatchPort) {CFRUNLOOP_WAKEUP_FOR_DISPATCH();__CFRunLoopModeUnlock(rlm);__CFRunLoopUnlock(rl);_CFSetTSD(__CFTSDKeyIsInGCDMainQ, (void *)6, NULL);__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(msg);_CFSetTSD(__CFTSDKeyIsInGCDMainQ, (void *)0, NULL);__CFRunLoopLock(rl);__CFRunLoopModeLock(rlm);sourceHandledThisLoop &#61; true;didDispatchPortLastTime &#61; true;} else {/* 接收端口不为空&#xff0c;并且没有满足 timer、主队列端口情况下&#xff0c;处理 source1 */CFRUNLOOP_WAKEUP_FOR_SOURCE();voucher_t previousVoucher &#61; _CFSetTSD(__CFTSDKeyMachMessageHasVoucher, (void *)voucherCopy, os_release);// Despite the name, this works for windows handles as wellCFRunLoopSourceRef rls &#61; __CFRunLoopModeFindSourceForMachPort(rl, rlm, livePort);if (rls) {mach_msg_header_t *reply &#61; NULL;/* source1 出现了 */sourceHandledThisLoop &#61; __CFRunLoopDoSource1(rl, rlm, rls, msg, msg->msgh_size, &reply) || sourceHandledThisLoop;if (NULL !&#61; reply) {/* 收到消息后&#xff0c;返回一个消息体&#xff0c;通知内核响应&#xff1f;&#xff1f;&#xff1f;&#xff1f; */(void)mach_msg(reply, MACH_SEND_MSG, reply->msgh_size, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL);CFAllocatorDeallocate(kCFAllocatorSystemDefault, reply);}}// Restore the previous voucher_CFSetTSD(__CFTSDKeyMachMessageHasVoucher, previousVoucher, os_release);} if (msg && msg !&#61; (mach_msg_header_t *)msg_buffer) free(msg); __CFRunLoopDoBlocks(rl, rlm);if (sourceHandledThisLoop && stopAfterHandle/* CFRunLoopRun ->false */) {retVal &#61; kCFRunLoopRunHandledSource;} else if (timeout_context->termTSR
} //__CFRunLoopRun