mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 04:13:28 +01:00
Thread support is now required
Long ago we supported systems where there was no support for threads, or where the threading library was broken. We shouldn't have do that any more: on every OS that matters, threads exist, and the OS supports running threads across multiple CPUs. This resolves tickets 9495 and 12439. It's a prerequisite to making our workqueue code work better, since sensible workqueue implementations don't split across multiple processes.
This commit is contained in:
parent
5b4ee475aa
commit
58f4200789
12
changes/threads-required
Normal file
12
changes/threads-required
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
o Removed features:
|
||||||
|
- Tor no longer supports systems without threading support.
|
||||||
|
When we began working on Tor, there were several systems that didn't
|
||||||
|
have threads, or where the thread support wasn't able to run the
|
||||||
|
threads of a single process on multiple CPUs. That no longer holds:
|
||||||
|
every system where Tor needs to run well now has threading support.
|
||||||
|
Resolves ticket 12439.
|
||||||
|
|
||||||
|
o Minor features:
|
||||||
|
- Threads are no longer disabled by default on Solaris; we believe that
|
||||||
|
the versions of Solaris with broken threading support are all obsolete
|
||||||
|
by now. Resolves ticket 9495.
|
24
configure.ac
24
configure.ac
@ -107,26 +107,6 @@ AC_ARG_ENABLE(upnp,
|
|||||||
* ) AC_MSG_ERROR(bad value for --enable-upnp) ;;
|
* ) AC_MSG_ERROR(bad value for --enable-upnp) ;;
|
||||||
esac], [upnp=false])
|
esac], [upnp=false])
|
||||||
|
|
||||||
|
|
||||||
AC_ARG_ENABLE(threads,
|
|
||||||
AS_HELP_STRING(--disable-threads, disable multi-threading support))
|
|
||||||
|
|
||||||
if test x$enable_threads = x; then
|
|
||||||
case $host in
|
|
||||||
*-*-solaris* )
|
|
||||||
# Don't try multithreading on solaris -- cpuworkers seem to lock.
|
|
||||||
AC_MSG_NOTICE([You are running Solaris; Sometimes threading makes
|
|
||||||
cpu workers lock up here, so I will disable threads.])
|
|
||||||
enable_threads="no";;
|
|
||||||
*)
|
|
||||||
enable_threads="yes";;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$enable_threads" = "yes"; then
|
|
||||||
AC_DEFINE(ENABLE_THREADS, 1, [Defined if we will try to use multithreading])
|
|
||||||
fi
|
|
||||||
|
|
||||||
case $host in
|
case $host in
|
||||||
*-*-solaris* )
|
*-*-solaris* )
|
||||||
AC_DEFINE(_REENTRANT, 1, [Define on some platforms to activate x_r() functions in time.h])
|
AC_DEFINE(_REENTRANT, 1, [Define on some platforms to activate x_r() functions in time.h])
|
||||||
@ -326,10 +306,8 @@ if test "$LIBS" != "$saved_LIBS"; then
|
|||||||
have_rt=yes
|
have_rt=yes
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$enable_threads" = "yes"; then
|
|
||||||
AC_SEARCH_LIBS(pthread_create, [pthread])
|
AC_SEARCH_LIBS(pthread_create, [pthread])
|
||||||
AC_SEARCH_LIBS(pthread_detach, [pthread])
|
AC_SEARCH_LIBS(pthread_detach, [pthread])
|
||||||
fi
|
|
||||||
|
|
||||||
dnl -------------------------------------------------------------------
|
dnl -------------------------------------------------------------------
|
||||||
dnl Check for functions before libevent, since libevent-1.2 apparently
|
dnl Check for functions before libevent, since libevent-1.2 apparently
|
||||||
@ -372,7 +350,7 @@ AC_CHECK_FUNCS(
|
|||||||
_vscprintf
|
_vscprintf
|
||||||
)
|
)
|
||||||
|
|
||||||
if test "$enable_threads" = "yes"; then
|
if test "$bwin32" != true; then
|
||||||
AC_CHECK_HEADERS(pthread.h)
|
AC_CHECK_HEADERS(pthread.h)
|
||||||
AC_CHECK_FUNCS(pthread_create)
|
AC_CHECK_FUNCS(pthread_create)
|
||||||
fi
|
fi
|
||||||
|
@ -2722,7 +2722,7 @@ tor_gettimeofday(struct timeval *timeval)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(TOR_IS_MULTITHREADED) && !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
/** Defined iff we need to add locks when defining fake versions of reentrant
|
/** Defined iff we need to add locks when defining fake versions of reentrant
|
||||||
* versions of time-related functions. */
|
* versions of time-related functions. */
|
||||||
#define TIME_FNS_NEED_LOCKS
|
#define TIME_FNS_NEED_LOCKS
|
||||||
@ -2982,7 +2982,6 @@ tor_get_thread_id(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TOR_IS_MULTITHREADED
|
|
||||||
/** Return a newly allocated, ready-for-use mutex. */
|
/** Return a newly allocated, ready-for-use mutex. */
|
||||||
tor_mutex_t *
|
tor_mutex_t *
|
||||||
tor_mutex_new(void)
|
tor_mutex_new(void)
|
||||||
@ -3000,7 +2999,6 @@ tor_mutex_free(tor_mutex_t *m)
|
|||||||
tor_mutex_uninit(m);
|
tor_mutex_uninit(m);
|
||||||
tor_free(m);
|
tor_free(m);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Conditions. */
|
/* Conditions. */
|
||||||
#ifdef USE_PTHREADS
|
#ifdef USE_PTHREADS
|
||||||
|
@ -633,15 +633,12 @@ int get_total_system_memory(size_t *mem_out);
|
|||||||
int spawn_func(void (*func)(void *), void *data);
|
int spawn_func(void (*func)(void *), void *data);
|
||||||
void spawn_exit(void) ATTR_NORETURN;
|
void spawn_exit(void) ATTR_NORETURN;
|
||||||
|
|
||||||
#if defined(ENABLE_THREADS) && defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#define USE_WIN32_THREADS
|
#define USE_WIN32_THREADS
|
||||||
#define TOR_IS_MULTITHREADED 1
|
#elif defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_CREATE)
|
||||||
#elif (defined(ENABLE_THREADS) && defined(HAVE_PTHREAD_H) && \
|
|
||||||
defined(HAVE_PTHREAD_CREATE))
|
|
||||||
#define USE_PTHREADS
|
#define USE_PTHREADS
|
||||||
#define TOR_IS_MULTITHREADED 1
|
|
||||||
#else
|
#else
|
||||||
#undef TOR_IS_MULTITHREADED
|
#error "No threading system was found"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int compute_num_cpus(void);
|
int compute_num_cpus(void);
|
||||||
@ -667,7 +664,6 @@ typedef struct tor_mutex_t {
|
|||||||
|
|
||||||
int tor_mlockall(void);
|
int tor_mlockall(void);
|
||||||
|
|
||||||
#ifdef TOR_IS_MULTITHREADED
|
|
||||||
tor_mutex_t *tor_mutex_new(void);
|
tor_mutex_t *tor_mutex_new(void);
|
||||||
void tor_mutex_init(tor_mutex_t *m);
|
void tor_mutex_init(tor_mutex_t *m);
|
||||||
void tor_mutex_acquire(tor_mutex_t *m);
|
void tor_mutex_acquire(tor_mutex_t *m);
|
||||||
@ -676,21 +672,10 @@ void tor_mutex_free(tor_mutex_t *m);
|
|||||||
void tor_mutex_uninit(tor_mutex_t *m);
|
void tor_mutex_uninit(tor_mutex_t *m);
|
||||||
unsigned long tor_get_thread_id(void);
|
unsigned long tor_get_thread_id(void);
|
||||||
void tor_threads_init(void);
|
void tor_threads_init(void);
|
||||||
#else
|
|
||||||
#define tor_mutex_new() ((tor_mutex_t*)tor_malloc(sizeof(int)))
|
|
||||||
#define tor_mutex_init(m) STMT_NIL
|
|
||||||
#define tor_mutex_acquire(m) STMT_VOID(m)
|
|
||||||
#define tor_mutex_release(m) STMT_NIL
|
|
||||||
#define tor_mutex_free(m) STMT_BEGIN tor_free(m); STMT_END
|
|
||||||
#define tor_mutex_uninit(m) STMT_NIL
|
|
||||||
#define tor_get_thread_id() (1UL)
|
|
||||||
#define tor_threads_init() STMT_NIL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void set_main_thread(void);
|
void set_main_thread(void);
|
||||||
int in_main_thread(void);
|
int in_main_thread(void);
|
||||||
|
|
||||||
#ifdef TOR_IS_MULTITHREADED
|
|
||||||
#if 0
|
#if 0
|
||||||
typedef struct tor_cond_t tor_cond_t;
|
typedef struct tor_cond_t tor_cond_t;
|
||||||
tor_cond_t *tor_cond_new(void);
|
tor_cond_t *tor_cond_new(void);
|
||||||
@ -699,7 +684,6 @@ int tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex);
|
|||||||
void tor_cond_signal_one(tor_cond_t *cond);
|
void tor_cond_signal_one(tor_cond_t *cond);
|
||||||
void tor_cond_signal_all(tor_cond_t *cond);
|
void tor_cond_signal_all(tor_cond_t *cond);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Macros for MIN/MAX. Never use these when the arguments could have
|
/** Macros for MIN/MAX. Never use these when the arguments could have
|
||||||
* side-effects.
|
* side-effects.
|
||||||
|
@ -75,12 +75,10 @@
|
|||||||
/** Macro: is k a valid RSA private key? */
|
/** Macro: is k a valid RSA private key? */
|
||||||
#define PRIVATE_KEY_OK(k) ((k) && (k)->key && (k)->key->p)
|
#define PRIVATE_KEY_OK(k) ((k) && (k)->key && (k)->key->p)
|
||||||
|
|
||||||
#ifdef TOR_IS_MULTITHREADED
|
|
||||||
/** A number of preallocated mutexes for use by OpenSSL. */
|
/** A number of preallocated mutexes for use by OpenSSL. */
|
||||||
static tor_mutex_t **openssl_mutexes_ = NULL;
|
static tor_mutex_t **openssl_mutexes_ = NULL;
|
||||||
/** How many mutexes have we allocated for use by OpenSSL? */
|
/** How many mutexes have we allocated for use by OpenSSL? */
|
||||||
static int n_openssl_mutexes_ = 0;
|
static int n_openssl_mutexes_ = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
/** A public key, or a public/private key-pair. */
|
/** A public key, or a public/private key-pair. */
|
||||||
struct crypto_pk_t
|
struct crypto_pk_t
|
||||||
@ -3090,8 +3088,6 @@ memwipe(void *mem, uint8_t byte, size_t sz)
|
|||||||
memset(mem, byte, sz);
|
memset(mem, byte, sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TOR_IS_MULTITHREADED
|
|
||||||
|
|
||||||
#ifndef OPENSSL_THREADS
|
#ifndef OPENSSL_THREADS
|
||||||
#error OpenSSL has been built without thread support. Tor requires an \
|
#error OpenSSL has been built without thread support. Tor requires an \
|
||||||
OpenSSL library with thread support enabled.
|
OpenSSL library with thread support enabled.
|
||||||
@ -3178,13 +3174,6 @@ setup_openssl_threading(void)
|
|||||||
CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy_cb_);
|
CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy_cb_);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static int
|
|
||||||
setup_openssl_threading(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Uninitialize the crypto library. Return 0 on success, -1 on failure.
|
/** Uninitialize the crypto library. Return 0 on success, -1 on failure.
|
||||||
*/
|
*/
|
||||||
@ -3208,7 +3197,7 @@ crypto_global_cleanup(void)
|
|||||||
|
|
||||||
CONF_modules_unload(1);
|
CONF_modules_unload(1);
|
||||||
CRYPTO_cleanup_all_ex_data();
|
CRYPTO_cleanup_all_ex_data();
|
||||||
#ifdef TOR_IS_MULTITHREADED
|
|
||||||
if (n_openssl_mutexes_) {
|
if (n_openssl_mutexes_) {
|
||||||
int n = n_openssl_mutexes_;
|
int n = n_openssl_mutexes_;
|
||||||
tor_mutex_t **ms = openssl_mutexes_;
|
tor_mutex_t **ms = openssl_mutexes_;
|
||||||
@ -3220,7 +3209,7 @@ crypto_global_cleanup(void)
|
|||||||
}
|
}
|
||||||
tor_free(ms);
|
tor_free(ms);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
tor_free(crypto_openssl_version_str);
|
tor_free(crypto_openssl_version_str);
|
||||||
tor_free(crypto_openssl_header_version_str);
|
tor_free(crypto_openssl_header_version_str);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -414,12 +414,6 @@ cpuworker_main(void *data)
|
|||||||
cpuworker_reply_t rpl;
|
cpuworker_reply_t rpl;
|
||||||
|
|
||||||
fd = fdarray[1]; /* this side is ours */
|
fd = fdarray[1]; /* this side is ours */
|
||||||
#ifndef TOR_IS_MULTITHREADED
|
|
||||||
tor_close_socket(fdarray[0]); /* this is the side of the socketpair the
|
|
||||||
* parent uses */
|
|
||||||
tor_free_all(1); /* so the child doesn't hold the parent's fd's open */
|
|
||||||
handle_signals(0); /* ignore interrupts from the keyboard, etc */
|
|
||||||
#endif
|
|
||||||
tor_free(data);
|
tor_free(data);
|
||||||
|
|
||||||
setup_server_onion_keys(&onion_keys);
|
setup_server_onion_keys(&onion_keys);
|
||||||
@ -535,10 +529,6 @@ spawn_cpuworker(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
log_debug(LD_OR,"just spawned a cpu worker.");
|
log_debug(LD_OR,"just spawned a cpu worker.");
|
||||||
#ifndef TOR_IS_MULTITHREADED
|
|
||||||
tor_close_socket(fdarray[1]); /* don't need the worker's side of the pipe */
|
|
||||||
tor_free(fdarray);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
conn = connection_new(CONN_TYPE_CPUWORKER, AF_UNIX);
|
conn = connection_new(CONN_TYPE_CPUWORKER, AF_UNIX);
|
||||||
|
|
||||||
|
@ -1382,12 +1382,6 @@ test_util_threads(void)
|
|||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
tv.tv_sec=0;
|
tv.tv_sec=0;
|
||||||
tv.tv_usec=100*1000;
|
tv.tv_usec=100*1000;
|
||||||
#endif
|
|
||||||
#ifndef TOR_IS_MULTITHREADED
|
|
||||||
/* Skip this test if we aren't threading. We should be threading most
|
|
||||||
* everywhere by now. */
|
|
||||||
if (1)
|
|
||||||
return;
|
|
||||||
#endif
|
#endif
|
||||||
thread_test_mutex_ = tor_mutex_new();
|
thread_test_mutex_ = tor_mutex_new();
|
||||||
thread_test_start1_ = tor_mutex_new();
|
thread_test_start1_ = tor_mutex_new();
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
/* Define to 1 if you have the <ctype.h> header file. */
|
/* Define to 1 if you have the <ctype.h> header file. */
|
||||||
#define HAVE_CTYPE_H
|
#define HAVE_CTYPE_H
|
||||||
|
|
||||||
#define ENABLE_THREADS
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <errno.h> header file. */
|
/* Define to 1 if you have the <errno.h> header file. */
|
||||||
#define HAVE_ERRNO_H
|
#define HAVE_ERRNO_H
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user