FreeSWITCH - mod_xml_rpc源码分析六thread_windows.c

这个文件内是针对windows平台的线程实现。在VisualStudio内可以看到,socket_openssl.c、socket_unix.c、thread_fork.c和thread_pthread.c这四个文件在abyss工程生成时不会生成代码。这很好理解,尤其是thread_fork.c和thread_pthread.c这两个文件,再加上thread_windows.c文件,就可以理解成在windows平台下编译abyss只使用windows平台下线程相关的特定代码。


线程

struct abyss_thread {
    HANDLE handle;
    void * userHandle;
    TThreadProc *   func;
    TThreadDoneFn * threadDone;
};
typedef struct abyss_thread TThread;


TThread是库内部针对线程的封装。ThreadCreate函数的作用就是创建一个TThread结构体变量,并启动一个线程。TThread结构体变量将提供给线程主函数。用户代码想向线程提供任何自定义的数据可以将其放置在userHandle中。用户代码中的线程主函数必须是TThreadProc类型。同时,用户代码还可以提供一个TThreadDoneFn类型的线程完成处理函数。useSigchld参数可能在windows平台下无意义,所以没有使用它。注意到线程被创建后不会立即启动,因为使用了CREATE_SUSPENDED参数。线程创建完毕后句柄保存在TThread变量的handle属性内。

void
ThreadCreate(TThread **      const threadPP,
             void *          const userHandle,
             TThreadProc   * const func,
             TThreadDoneFn * const threadDone,
             bool            const useSigchld,
             const char **   const errorP) {

    TThread * threadP;

    MALLOCVAR(threadP);

    if (threadP == NULL)
        xmlrpc_asprintf(errorP,
                        "Can't allocate memory for thread descriptor.");
    else {
        DWORD z;

        threadP->userHandle = userHandle;
        threadP->func       = func;
        threadP->threadDone = threadDone;

        threadP->handle = (HANDLE)_beginthreadex(NULL,
                                                 THREAD_STACK_SIZE,
                                                 threadRun,
                                                 threadP,
                                                 CREATE_SUSPENDED,
                                                 &z);

        if (threadP->handle == NULL)
            xmlrpc_asprintf(errorP, "_beginthreadex() failed.");
        else {
            *errorP = NULL;
            *threadPP = threadP;
        }
        if (*errorP)
            free(threadP);
    }
}


static uint32_t WINAPI
threadRun(void * const arg) {

    struct abyss_thread * const threadP = arg;

    threadP->func(threadP->userHandle);

    threadP->threadDone(threadP->userHandle);

    return 0;
}

由于TThread中保存了线程句柄,所以其他所有线程封装函数均针对TThread的handle句柄进行操作。


Mutex

struct abyss_mutex {
    HANDLE winMutex;
};
typedef struct abyss_mutex TMutex;

abyss_mutex在windows平台下只是封装了一个句柄。MutexCreate函数处理过程也说明了这点。申请空间创建好TMutex后,接着只是调用CreateMutex函数创建windows平台下的mutex对象,成功后将句柄赋给TMutex的winMutex属性。其他Mutex函数就像线程函数一样,都只是针对Mutex句柄进行操作。

bool
MutexCreate(TMutex ** const mutexPP) {

    TMutex * mutexP;
    bool succeeded;

    MALLOCVAR(mutexP);

    if (mutexP) {

        mutexP->winMutex = CreateMutex(NULL, FALSE, NULL);

        succeeded = (mutexP->winMutex != NULL);
    } else
        succeeded = FALSE;

    if (!succeeded)
        free(mutexP);

    *mutexPP = mutexP;

    TraceMsg( "Created Mutex %s\n", (succeeded ? "ok" : "FAILED") );

    return succeeded;
}





你可能感兴趣的:(freeswitch,abyss)