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;
}

两个全局静态变量


 // 注册一个回调,当线程销毁时,顺便也销毁其对应的 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) 表示的,是线程退出时,操作系统实现试图销毁线程私有数据的最大次数。

上一篇下一篇

猜你喜欢

热点阅读