diff options
-rw-r--r-- | configure.in | 4 | ||||
-rw-r--r-- | src/common/compat.c | 81 | ||||
-rw-r--r-- | src/common/compat.h | 6 |
3 files changed, 78 insertions, 13 deletions
diff --git a/configure.in b/configure.in index 5a7022417d..1958cd717e 100644 --- a/configure.in +++ b/configure.in @@ -146,9 +146,9 @@ AC_CHECK_HEADERS(event.h, , AC_MSG_ERROR(Libevent header (event.h) not found. To dnl These headers are not essential -AC_CHECK_HEADERS(stdint.h sys/types.h inttypes.h sys/param.h sys/wait.h sys/limits.h netinet/in.h arpa/inet.h machine/limits.h syslog.h sys/time.h sys/resource.h) +AC_CHECK_HEADERS(stdint.h sys/types.h inttypes.h sys/param.h sys/wait.h sys/limits.h netinet/in.h arpa/inet.h machine/limits.h syslog.h sys/time.h sys/resource.h pthread.h) -AC_CHECK_FUNCS(gettimeofday ftime socketpair uname inet_aton strptime getrlimit setrlimit strlcat strlcpy strtoull getpwnam ftello) +AC_CHECK_FUNCS(gettimeofday ftime socketpair uname inet_aton strptime getrlimit setrlimit strlcat strlcpy strtoull getpwnam ftello pthread_create) AC_FUNC_FSEEKO AC_CHECK_MEMBERS([struct timeval.tv_sec]) diff --git a/src/common/compat.c b/src/common/compat.c index 17338dd16a..0b5de082cc 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -65,6 +65,9 @@ const char compat_c_id[] = "$Id$"; #include <stdlib.h> #include <string.h> #include <assert.h> +#ifdef HAVE_PTHREAD_H +#include <pthread.h> +#endif #include "log.h" #include "util.h" @@ -601,6 +604,25 @@ get_uname(void) * Process control */ +#if defined(USE_PTHREADS) +struct tor_pthread_data_t { + int (*func)(void *); + void *data; +}; +static void * +tor_pthread_helper_fn(void *_data) +{ + struct tor_pthread_data_t *data = _data; + int (*func)(void*); + void *arg; + func = data->func; + arg = data->data; + tor_free(_data); + func(arg); + return NULL; +} +#endif + /** Minimalist interface to run a void function in the background. On * unix calls fork, on win32 calls beginthread. Returns -1 on failure. * func should not return, but rather should call spawn_exit. @@ -613,12 +635,23 @@ get_uname(void) int spawn_func(int (*func)(void *), void *data) { -#ifdef MS_WINDOWS +#if defined(USE_WIN32_THREADS) int rv; rv = _beginthread(func, 0, data); if (rv == (unsigned long) -1) return -1; return 0; +#elif defined(USE_PTHREADS) + pthread_t thread; + struct tor_pthread_data_t *d; + d = tor_malloc(sizeof(struct tor_pthread_data_t)); + d->data = data; + d->func = func; + if (pthread_create(&thread,NULL,tor_pthread_helper_fn,d)) + return -1; + if (pthread_detach(thread)) + return -1; + return 0; #else pid_t pid; pid = fork(); @@ -640,8 +673,10 @@ spawn_func(int (*func)(void *), void *data) */ void spawn_exit() { -#ifdef MS_WINDOWS +#if defined(USE_WIN32_THREADS) _endthread(); +#elif defined(USE_PTHREADS) + pthread_exit(NULL); #else exit(0); #endif @@ -669,14 +704,7 @@ void tor_gettimeofday(struct timeval *timeval) { return; } -#ifndef MS_WINDOWS -struct tor_mutex_t { -}; -tor_mutex_t *tor_mutex_new(void) { return NULL; } -void tor_mutex_acquire(tor_mutex_t *m) { } -void tor_mutex_release(tor_mutex_t *m) { } -void tor_mutex_free(tor_mutex_t *m) { } -#else +#ifdef USE_WIN32_THREADS struct tor_mutex_t { HANDLE handle; }; @@ -716,6 +744,39 @@ void tor_mutex_release(tor_mutex_t *m) log_fn(LOG_WARN, "Failed to release mutex: %d", GetLastError()); } } +#elif defined(USE_PTHREADS) +struct tor_mutex_t { + pthread_mutex_t mutex; +}; +tor_mutex_t *tor_mutex_new(void) +{ + tor_mutex_t *mutex = tor_malloc_zero(sizeof(tor_mutex_t)); + pthread_mutex_init(&mutex->mutex, NULL); + return mutex; +} +void tor_mutex_acquire(tor_mutex_t *m) +{ + tor_assert(m); + pthread_mutex_lock(&m->mutex); +} +void tor_mutex_release(tor_mutex_t *m) +{ + tor_assert(m); + pthread_mutex_unlock(&m->mutex); +} +void tor_mutex_free(tor_mutex_t *m) +{ + tor_assert(m); + pthread_mutex_destroy(&m->mutex); + tor_free(m); +} +#else +struct tor_mutex_t { +}; +tor_mutex_t *tor_mutex_new(void) { return NULL; } +void tor_mutex_acquire(tor_mutex_t *m) { } +void tor_mutex_release(tor_mutex_t *m) { } +void tor_mutex_free(tor_mutex_t *m) { } #endif /** diff --git a/src/common/compat.h b/src/common/compat.h index e10a6b620d..f75e39b122 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -196,7 +196,11 @@ void tor_mutex_acquire(tor_mutex_t *m); void tor_mutex_release(tor_mutex_t *m); void tor_mutex_free(tor_mutex_t *m); -#ifdef MS_WINDOWS +#if defined(MS_WINDOWS) +#define USE_WIN32_THREADS +#define TOR_IS_MULTITHREADED 1 +#elif defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_CREATE) +#define USE_PTHREADS #define TOR_IS_MULTITHREADED 1 #else #undef TOR_IS_MULTITHREADED |