这个文件内是针对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; }