From c51f7c23e3af71466f9bd2ae57ae7a2b998ee3e2 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 25 Sep 2013 14:31:59 -0400 Subject: [PATCH] Test a little more of compat_threads.c --- src/common/compat_threads.c | 20 +++++++++++--------- src/common/compat_threads.h | 9 ++++++++- src/common/workqueue.c | 4 ++-- src/common/workqueue.h | 2 +- src/test/test_workqueue.c | 19 ++++++++++++++++--- 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/common/compat_threads.c b/src/common/compat_threads.c index f2a516a4a3..648eaa2d80 100644 --- a/src/common/compat_threads.c +++ b/src/common/compat_threads.c @@ -155,19 +155,18 @@ sock_drain(tor_socket_t fd) /** Allocate a new set of alert sockets, and set the appropriate function * pointers, in socks_out. */ int -alert_sockets_create(alert_sockets_t *socks_out) +alert_sockets_create(alert_sockets_t *socks_out, uint32_t flags) { - tor_socket_t socks[2]; + tor_socket_t socks[2] = { TOR_INVALID_SOCKET, TOR_INVALID_SOCKET }; #ifdef HAVE_EVENTFD /* First, we try the Linux eventfd() syscall. This gives a 64-bit counter * associated with a single file descriptor. */ #if defined(EFD_CLOEXEC) && defined(EFD_NONBLOCK) - socks[0] = eventfd(0, EFD_CLOEXEC|EFD_NONBLOCK); -#else - socks[0] = -1; + if (!(flags & ASOCKS_NOEVENTFD2)) + socks[0] = eventfd(0, EFD_CLOEXEC|EFD_NONBLOCK); #endif - if (socks[0] < 0) { + if (socks[0] < 0 && !(flags & ASOCKS_NOEVENTFD)) { socks[0] = eventfd(0,0); if (socks[0] >= 0) { if (fcntl(socks[0], F_SETFD, FD_CLOEXEC) < 0 || @@ -188,7 +187,8 @@ alert_sockets_create(alert_sockets_t *socks_out) #ifdef HAVE_PIPE2 /* Now we're going to try pipes. First type the pipe2() syscall, if we * have it, so we can save some calls... */ - if (pipe2(socks, O_NONBLOCK|O_CLOEXEC) == 0) { + if (!(flags & ASOCKS_NOPIPE2) && + pipe2(socks, O_NONBLOCK|O_CLOEXEC) == 0) { socks_out->read_fd = socks[0]; socks_out->write_fd = socks[1]; socks_out->alert_fn = pipe_alert; @@ -200,7 +200,8 @@ alert_sockets_create(alert_sockets_t *socks_out) #ifdef HAVE_PIPE /* Now try the regular pipe() syscall. Pipes have a bit lower overhead than * socketpairs, fwict. */ - if (pipe(socks) == 0) { + if (!(flags & ASOCKS_NOPIPE) && + pipe(socks) == 0) { if (fcntl(socks[0], F_SETFD, FD_CLOEXEC) < 0 || fcntl(socks[1], F_SETFD, FD_CLOEXEC) < 0 || set_socket_nonblocking(socks[0]) < 0 || @@ -218,7 +219,8 @@ alert_sockets_create(alert_sockets_t *socks_out) #endif /* If nothing else worked, fall back on socketpair(). */ - if (tor_socketpair(AF_UNIX, SOCK_STREAM, 0, socks) == 0) { + if (!(flags & ASOCKS_NOSOCKETPAIR) && + tor_socketpair(AF_UNIX, SOCK_STREAM, 0, socks) == 0) { if (set_socket_nonblocking(socks[0]) < 0 || set_socket_nonblocking(socks[1])) { tor_close_socket(socks[0]); diff --git a/src/common/compat_threads.h b/src/common/compat_threads.h index 245df76178..1b59391d3b 100644 --- a/src/common/compat_threads.h +++ b/src/common/compat_threads.h @@ -102,7 +102,14 @@ typedef struct alert_sockets_s { int (*drain_fn)(tor_socket_t read_fd); } alert_sockets_t; -int alert_sockets_create(alert_sockets_t *socks_out); +/* Flags to disable one or more alert_sockets backends. */ +#define ASOCKS_NOEVENTFD2 (1u<<0) +#define ASOCKS_NOEVENTFD (1u<<1) +#define ASOCKS_NOPIPE2 (1u<<2) +#define ASOCKS_NOPIPE (1u<<3) +#define ASOCKS_NOSOCKETPAIR (1u<<4) + +int alert_sockets_create(alert_sockets_t *socks_out, uint32_t flags); void alert_sockets_close(alert_sockets_t *socks); #endif diff --git a/src/common/workqueue.c b/src/common/workqueue.c index e07787b404..9293e1f9f0 100644 --- a/src/common/workqueue.c +++ b/src/common/workqueue.c @@ -397,12 +397,12 @@ threadpool_get_replyqueue(threadpool_t *tp) * IO-centric event loop, it needs to get woken up with means other than a * condition variable. */ replyqueue_t * -replyqueue_new(void) +replyqueue_new(uint32_t alertsocks_flags) { replyqueue_t *rq; rq = tor_malloc_zero(sizeof(replyqueue_t)); - if (alert_sockets_create(&rq->alert) < 0) { + if (alert_sockets_create(&rq->alert, alertsocks_flags) < 0) { tor_free(rq); return NULL; } diff --git a/src/common/workqueue.h b/src/common/workqueue.h index dca947e915..5a6cd80fb0 100644 --- a/src/common/workqueue.h +++ b/src/common/workqueue.h @@ -40,7 +40,7 @@ threadpool_t *threadpool_new(int n_threads, void *arg); replyqueue_t *threadpool_get_replyqueue(threadpool_t *tp); -replyqueue_t *replyqueue_new(void); +replyqueue_t *replyqueue_new(uint32_t alertsocks_flags); tor_socket_t replyqueue_get_socket(replyqueue_t *rq); void replyqueue_process(replyqueue_t *queue); diff --git a/src/test/test_workqueue.c b/src/test/test_workqueue.c index 4077fb27a8..7ef54ef22b 100644 --- a/src/test/test_workqueue.c +++ b/src/test/test_workqueue.c @@ -249,8 +249,10 @@ help(void) " -N Run this many items of work\n" " -T Use this many threads\n" " -I Have no more than this many requests queued at once\n" - " -L Add items whenever fewer than this many are pending.\n" - " -R Make one out of this many items be a slow (RSA) one"); + " -L Add items whenever fewer than this many are pending\n" + " -R Make one out of this many items be a slow (RSA) one\n" + " --no-{eventfd2,eventfd,pipe2,pipe,socketpair}\n" + " Disable one of the alert_socket backends."); } int @@ -261,6 +263,7 @@ main(int argc, char **argv) int i; tor_libevent_cfg evcfg; struct event *ev; + uint32_t as_flags = 0; for (i = 1; i < argc; ++i) { if (!strcmp(argv[i], "-v")) { @@ -275,6 +278,16 @@ main(int argc, char **argv) opt_n_lowwater = atoi(argv[++i]); } else if (!strcmp(argv[i], "-R") && i+1