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

RunLoop -1⃣️- CFRunLoopGetCurren

作者: 派大星的博客 | 来源:发表于2020-06-12 16:27 被阅读0次

CFRunLoopRef CFRunLoopGetCurrent(void) {
    CHECK_FOR_FORK();
    CFRunLoopRef rl = (CFRunLoopRef)_CFGetTSD(__CFTSDKeyRunLoop);
    if (rl) return rl;
    return _CFRunLoopGet0(pthread_self());
}
  • RunLoop --- CHECK_FOR_FORK()

Forking is a system call where a process creates a copy of itself. CHECK_FOR_FORK is a boolean value in the code which checks whether the given process was forked.

在Mac_OS中有用: (current thread 是不是 从别的进程fork()过来的?)


  • do {...} while (0) 在宏定义中的作用

使用do{...}while(0)构造后的宏定义不会受到大括号、分号等的影响,总是会按你期望的方式调用运行。


  • linux中fork()函数

入门:一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。
一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。


  • TSD是thread special data
    表示线程私有数据,在 C++ 中,全局变量可以被所有线程访问,局部变量只有函数内部可以访问。而 TSD 的作用就是能够在同一个线程的不同函数中被访问。(转载,感觉说的挺对。)

  • __CFTSDKeyRunLoopCFInternal.h的一个枚举值, 其他的值如下:

// Foundation uses 20-40
// Foundation knows about the value of __CFTSDKeyAutoreleaseData1
enum {
    __CFTSDKeyAllocator = 1,
    __CFTSDKeyIsInCFLog = 2,
    __CFTSDKeyIsInNSCache = 3,
    __CFTSDKeyIsInGCDMainQ = 4,
    __CFTSDKeyICUConverter = 7,
    __CFTSDKeyCollatorLocale = 8,
    __CFTSDKeyCollatorUCollator = 9,
    __CFTSDKeyRunLoop = 10,
    __CFTSDKeyRunLoopCntr = 11,
        __CFTSDKeyMachMessageBoost = 12, // valid only in the context of a CFMachPort callout
        __CFTSDKeyMachMessageHasVoucher = 13,
    // autorelease pool stuff must be higher than run loop constants
    __CFTSDKeyAutoreleaseData2 = 61,
    __CFTSDKeyAutoreleaseData1 = 62,
    __CFTSDKeyExceptionData = 63,
};
  • _CFGetTSD 以枚举值[slot]为key在__CFTSDTable.data 上查找
//  CFPlatform.c
// For the use of CF and Foundation only
CF_EXPORT void *_CFGetTSD(uint32_t slot) {
  // CF_TSD_MAX_SLOTS =70, 
    if (slot > CF_TSD_MAX_SLOTS) {
        _CFLogSimple(kCFLogLevelError, "Error: TSD slot %d out of range (get)", slot);
        HALT;
    }
    __CFTSDTable *table = __CFTSDGetTable();
    if (!table) {
        // Someone is getting TSD during thread destruction. The table is gone, so we can't get any data anymore.
        _CFLogSimple(kCFLogLevelWarning, "Warning: TSD slot %d retrieved but the thread data has already been torn down.", slot);
        return NULL;
    }
    uintptr_t *slots = (uintptr_t *)(table->data);
    return (void *)slots[slot];
}
  • __CFTSDGetTable
// Get or initialize a thread local storage. It is created on demand.
static __CFTSDTable *__CFTSDGetTable() {
    __CFTSDTable *table = (__CFTSDTable *)__CFTSDGetSpecific();
    // Make sure we're not setting data again after destruction.
    if (table == CF_TSD_BAD_PTR) {
        return NULL;
    }
    // Create table on demand
    if (!table) {
        // This memory is freed in the finalize function
        table = (__CFTSDTable *)calloc(1, sizeof(__CFTSDTable));
        // Windows and Linux have created the table already, we need to initialize it here for other platforms. On Windows, the cleanup function is called by DllMain when a thread exits. On Linux the destructor is set at init time.
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
        pthread_key_init_np(CF_TSD_KEY, __CFTSDFinalize);
#endif
        __CFTSDSetSpecific(table);
    }
    
    return table;
}
  • _CFGetTSD 获取线程私有数据的Method。
    参数:slot 枚举值 eg: __CFTSDKeyRunLoop
调用列举.png

相关文章

网友评论

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

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