📄 thread_pthread.c
字号:
#include <unistd.h>#include <pthread.h>#include <string.h>#include <errno.h>#include <signal.h>#include "xmlrpc_config.h"#include "mallocvar.h"#include "xmlrpc-c/string_int.h"#include "xmlrpc-c/abyss.h"#include "thread.h"struct abyss_thread { pthread_t thread; void * userHandle; TThreadProc * func; TThreadDoneFn * threadDone;};/* We used to have THREAD_STACK_SIZE = 16K, which was said to be the minimum stack size on Win32. Scott Kolodzeski found in November 2005 that this was insufficient for 64 bit Solaris -- we fail when creating the first thread. So we changed to 128K.*/#define THREAD_STACK_SIZE (128*1024L)typedef void * (pthreadStartRoutine)(void *);static pthreadStartRoutine pthreadStart;static void *pthreadStart(void * const arg) { struct abyss_thread * const threadP = arg; abyss_bool const executeTrue = true; pthread_cleanup_push(threadP->threadDone, threadP->userHandle); threadP->func(threadP->userHandle); pthread_cleanup_pop(executeTrue); return NULL;}voidThreadCreate(TThread ** const threadPP, void * const userHandle, TThreadProc * const func, TThreadDoneFn * const threadDone, abyss_bool const useSigchld ATTR_UNUSED, const char ** const errorP) { TThread * threadP; MALLOCVAR(threadP); if (threadP == NULL) xmlrpc_asprintf(errorP, "Can't allocate memory for thread descriptor."); else { pthread_attr_t attr; int rc; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE); threadP->userHandle = userHandle; threadP->func = func; threadP->threadDone = threadDone; rc = pthread_create(&threadP->thread, &attr, pthreadStart, threadP); if (rc == 0) { *errorP = NULL; *threadPP = threadP; } else xmlrpc_asprintf( errorP, "pthread_create() failed, errno = %d (%s)", errno, strerror(errno)); pthread_attr_destroy(&attr); if (*errorP) free(threadP); }}abyss_boolThreadRun(TThread * const threadP ATTR_UNUSED) { return TRUE; }abyss_boolThreadStop(TThread * const threadP ATTR_UNUSED) { return TRUE;}abyss_boolThreadKill(TThread * const threadP ATTR_UNUSED) { return (pthread_kill(threadP->thread, SIGTERM) == 0);}voidThreadWaitAndRelease(TThread * const threadP) { void * threadReturn; pthread_join(threadP->thread, &threadReturn); free(threadP);}voidThreadExit(int const retValue) { pthread_exit((void*)&retValue); /* Note that the above runs our cleanup routine (which we registered with pthread_cleanup_push() before exiting. */}voidThreadRelease(TThread * const threadP) { pthread_detach(threadP->thread); free(threadP);}abyss_boolThreadForks(void) { return FALSE;}voidThreadUpdateStatus(TThread * const threadP ATTR_UNUSED) { /* Threads keep their own statuses up to date, so there's nothing to do here. */}voidThreadHandleSigchld(pid_t const pid ATTR_UNUSED) { /* Death of a child signals have nothing to do with pthreads */}/*********************************************************************** Mutex*********************************************************************/abyss_boolMutexCreate(TMutex * const mutexP) { return (pthread_mutex_init(mutexP, NULL) == 0);}abyss_boolMutexLock(TMutex * const mutexP) { return (pthread_mutex_lock(mutexP) == 0);}abyss_boolMutexUnlock(TMutex * const mutexP) { return (pthread_mutex_unlock(mutexP) == 0);}abyss_boolMutexTryLock(TMutex * const mutexP) { return (pthread_mutex_trylock(mutexP) == 0);}voidMutexFree(TMutex * const mutexP) { pthread_mutex_destroy(mutexP);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -