RunLoop -1⃣️- CFRunLoopGet0
2020-06-12 本文已影响0人
派大星的博客
// should only be called by Foundation
// t==0 is a synonym for "main thread" that always works
// [pthreadPointer(t): RunLoop] : 指向线程的指针 和 RunLoop 一一对应
static CFMutableDictionaryRef __CFRunLoops = NULL; // 全局静态的集合
static CFLock_t loopsLock = CFLockInit; // 为保证线程安全的静态锁对象
CF_EXPORT CFRunLoopRef _CFRunLoopGet0(pthread_t t)
{
// 参数检验,如果没有指定线程,默认设置为主线程
if (pthread_equal(t, kNilPthreadT))
{
t = pthread_main_thread_np();
}
__CFLock(&loopsLock);
// __CFRunLoops 不存在, 就创建临时dict, 添加主线程默认的mainLoop。 dict 和 __CFRunLoops 交换指针, 释放临时变量dict 和 mainLoop
if (!__CFRunLoops)
{
__CFUnlock(&loopsLock);
CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
CFRunLoopRef mainLoop = __CFRunLoopCreate(pthread_main_thread_np());
CFDictionarySetValue(dict, pthreadPointer(pthread_main_thread_np()), mainLoop);
if (!OSAtomicCompareAndSwapPtrBarrier(NULL, dict, (void *volatile *)&__CFRunLoops))
{
CFRelease(dict);
}
CFRelease(mainLoop);
__CFLock(&loopsLock);
}
CFRunLoopRef loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t));
__CFUnlock(&loopsLock);
// 如果不存在对应的runloop,就创建新的,并将新的runloop保存到 _CFRunLoops 中
if (!loop)
{
CFRunLoopRef newLoop = __CFRunLoopCreate(t);
__CFLock(&loopsLock);
loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t));
if (!loop)
{
CFDictionarySetValue(__CFRunLoops, pthreadPointer(t), newLoop);
loop = newLoop;
}
// don't release run loops inside the loopsLock, because CFRunLoopDeallocate may end up taking it
__CFUnlock(&loopsLock);
CFRelease(newLoop);
}
// 如过入参 t 是当前线程, 则在线程对应的Table中更行__CFTSDKeyRunLoop 和 __CFTSDKeyRunLoopCntr
if (pthread_equal(t, pthread_self()))
{
_CFSetTSD(__CFTSDKeyRunLoop, (void *)loop, NULL);
if (0 == _CFGetTSD(__CFTSDKeyRunLoopCntr))
{
// 注册一个回调,当线程销毁时,顺便也销毁其对应的 RunLoop。
_CFSetTSD(__CFTSDKeyRunLoopCntr, (void *)(PTHREAD_DESTRUCTOR_ITERATIONS - 1), (void (*)(void *))__CFFinalizeRunLoop);
}
}
return loop;
}
-
参数检验,如果没有指定线程,默认设置为主线程
-
__CFRunLoops 不存在, 就创建临时dict, 添加主线程默认的mainLoop。 dict 和 __CFRunLoops 交换指针, 释放临时变量dict 和 mainLoop
- 如果不存在对应的runloop,就创建新的,并将新的runloop保存到 _CFRunLoops 中
- 如过入参 t 是当前线程, 则在线程对应的Table中更行__CFTSDKeyRunLoop 和 __CFTSDKeyRunLoopCntr
两个全局静态变量
-
static CFMutableDictionaryRef __CFRunLoops = NULL;
// 全局静态的集合
// [pthreadPointer(t): RunLoop] : 指向线程的指针 和 RunLoop 一一对应 -
static CFLock_t loopsLock = CFLockInit;
// 为保证线程安全的静态锁对象
// 注册一个回调,当线程销毁时,顺便也销毁其对应的 RunLoop。
_CFSetTSD(__CFTSDKeyRunLoopCntr, (void *)(PTHREAD_DESTRUCTOR_ITERATIONS-1), (void (*)(void *))__CFFinalizeRunLoop);
__CFTSDKeyRunLoop: 存储 loop。
__CFTSDKeyRunLoopCntr: 设置了清理 loop 的回调
Cntr: 可逆计数器(CNTR)指令基本情况 可逆循环计数器指令。
参数值: PTHREAD_DESTRUCTOR_ITERATIONS - 1
PTHREAD_DESTRUCTOR_ITERATIONS
( = 4) 表示的,是线程退出时,操作系统实现试图销毁线程私有数据的最大次数。