美文网首页
RunLoop -1⃣️- CFRunLoopGet0

RunLoop -1⃣️- CFRunLoopGet0

作者: 派大星的博客 | 来源:发表于2020-06-12 17:40 被阅读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) 表示的,是线程退出时,操作系统实现试图销毁线程私有数据的最大次数。

    相关文章

      网友评论

          本文标题:RunLoop -1⃣️- CFRunLoopGet0

          本文链接:https://www.haomeiwen.com/subject/hacntktx.html