Created
November 9, 2021 08:32
-
-
Save kikohz/eebe97f8e142f1c2c31e27eb16db6802 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInterval seconds, Boolean stopAfterHandle, CFRunLoopModeRef previousMode) { | |
//通知Observer:即将处理Timers事件 | |
__CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeTimers); | |
//通知Observer:即将处理Sources事件 | |
__CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeSources); | |
//处理Blocks | |
__CFRunLoopDoBlocks(rl, rlm); | |
//处理Sources0 通过处理结果来判断是否需要再次执行Blocks | |
Boolean sourceHandledThisLoop = __CFRunLoopDoSources0(rl, rlm, stopAfterHandle); | |
if (sourceHandledThisLoop) { | |
__CFRunLoopDoBlocks(rl, rlm); | |
} | |
//判断Sources1(MachPort为Sources1),如果有事件,直接跳转到handle_msg | |
if (__CFRunLoopServiceMachPort(dispatchPort, &msg, sizeof(msg_buffer), 0)) { | |
goto handle_msg; | |
} | |
//通知Observer:即将进入休眠 | |
__CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeWaiting); | |
//开始休眠,等待其他消息唤醒 | |
__CFRunLoopSetSleeping(rl); | |
__CFPortSetInsert(dispatchPort, waitSet); | |
__CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), poll ? 0 : TIMEOUT_INFINITY); | |
//醒来了 | |
__CFPortSetRemove(dispatchPort, waitSet); | |
__CFRunLoopUnsetSleeping(rl); | |
//通知Observer:已经唤醒 | |
__CFRunLoopDoObservers(rl, rlm, kCFRunLoopAfterWaiting); | |
handle_msg:; //看是谁唤醒RunLoop,进行相应的处理 | |
mach_port_t livePort = msg ? msg->msgh_local_port : MACH_PORT_NULL; | |
if (MACH_PORT_NULL == livePort) { | |
// handle nothing | |
} else if (livePort == rl->_wakeUpPort) { | |
// do nothing on Mac OS | |
} else if (livePort == rlm->_timerPort) { //被Timer唤醒,处理Timers事件 | |
__CFRunLoopDoTimers(rl, rlm, mach_absolute_time()); | |
} else if (livePort == dispatchPort) { //GCD唤醒,处理GCD async to main async 事件 | |
_dispatch_main_queue_callback_4CF(msg); | |
} else { //Source1唤醒,处理Source1事件 | |
__CFRunLoopDoSource1(rl, rlm, rls, msg, msg->msgh_size, &reply) || sourceHandledThisLoop; | |
//执行Blocks | |
__CFRunLoopDoBlocks(rl, rlm); | |
//根据之前的执行结果来看是否要继续循环? | |
if (sourceHandledThisLoop && stopAfterHandle) { | |
retVal = kCFRunLoopRunHandledSource; | |
} else if (timeout_context->termTSR < (int64_t)mach_absolute_time()) { | |
retVal = kCFRunLoopRunTimedOut; | |
} else if (__CFRunLoopIsStopped(rl)) { | |
__CFRunLoopUnsetStopped(rl); | |
retVal = kCFRunLoopRunStopped; | |
} else if (rlm->_stopped) { | |
rlm->_stopped = false; | |
retVal = kCFRunLoopRunStopped; | |
} else if (__CFRunLoopModeIsEmpty(rl, rlm, previousMode)) { | |
retVal = kCFRunLoopRunFinished; | |
} | |
} while (0 == retVal); | |
return retVal; | |
} | |
SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterval seconds, Boolean returnAfterSourceHandled) { /* DOES CALLOUT */ | |
//通知Observers:进入loop | |
__CFRunLoopDoObservers(rl, currentMode, kCFRunLoopEntry); | |
//开始执行Run | |
result = __CFRunLoopRun(rl, currentMode, seconds, returnAfterSourceHandled, previousMode); | |
//通知Observers:推出Loop | |
__CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit); | |
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); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment