diff --git a/changes/ticket40719 b/changes/ticket40719 new file mode 100644 index 0000000000..eec84dce0f --- /dev/null +++ b/changes/ticket40719 @@ -0,0 +1,3 @@ + o Minor bugfixes (cpuworker, relay): + - Fix an off by one overload calculation on the number of CPUs being used by + our thread pool. Fixes bug 40719; bugfix on 0.3.5.1-alpha. diff --git a/src/core/mainloop/cpuworker.c b/src/core/mainloop/cpuworker.c index 3ad556a184..39d4899075 100644 --- a/src/core/mainloop/cpuworker.c +++ b/src/core/mainloop/cpuworker.c @@ -144,6 +144,16 @@ cpu_init(void) set_max_pending_tasks(NULL); } +/** Return the number of threads configured for our CPU worker. */ +unsigned int +cpuworker_get_n_threads(void) +{ + if (!threadpool) { + return 0; + } + return threadpool_get_n_threads(threadpool); +} + /** Magic numbers to make sure our cpuworker_requests don't grow any * mis-framing bugs. */ #define CPUWORKER_REQUEST_MAGIC 0xda4afeed diff --git a/src/core/mainloop/cpuworker.h b/src/core/mainloop/cpuworker.h index 94545af586..9eee287c1f 100644 --- a/src/core/mainloop/cpuworker.h +++ b/src/core/mainloop/cpuworker.h @@ -38,5 +38,7 @@ void cpuworker_log_onionskin_overhead(int severity, int onionskin_type, const char *onionskin_type_name); void cpuworker_cancel_circ_handshake(or_circuit_t *circ); +unsigned int cpuworker_get_n_threads(void); + #endif /* !defined(TOR_CPUWORKER_H) */ diff --git a/src/feature/relay/onion_queue.c b/src/feature/relay/onion_queue.c index 6d1a6de15c..b844aefcd1 100644 --- a/src/feature/relay/onion_queue.c +++ b/src/feature/relay/onion_queue.c @@ -152,7 +152,13 @@ have_room_for_onionskin(uint16_t type) /* If we've got fewer than 50 entries, we always have room for one more. */ if (ol_entries[type] < 50) return 1; - num_cpus = get_num_cpus(options); + + /* If zero, this means our thread pool was never initialized meaning we can't + * really get here but make sure we don't have such value because we are + * using as a divisor. */ + num_cpus = cpuworker_get_n_threads(); + tor_assert(num_cpus > 0); + max_onion_queue_delay = get_onion_queue_max_delay(options); /* Compute how many microseconds we'd expect to need to clear all diff --git a/src/lib/evloop/workqueue.c b/src/lib/evloop/workqueue.c index 603dddd5a3..bc929148eb 100644 --- a/src/lib/evloop/workqueue.c +++ b/src/lib/evloop/workqueue.c @@ -672,3 +672,11 @@ replyqueue_process(replyqueue_t *queue) tor_mutex_release(&queue->lock); } + +/** Return the number of threads configured for the given pool. */ +unsigned int +threadpool_get_n_threads(threadpool_t *tp) +{ + tor_assert(tp); + return tp->n_threads; +} diff --git a/src/lib/evloop/workqueue.h b/src/lib/evloop/workqueue.h index 50391759bf..134fe7434f 100644 --- a/src/lib/evloop/workqueue.h +++ b/src/lib/evloop/workqueue.h @@ -65,5 +65,6 @@ void replyqueue_process(replyqueue_t *queue); int threadpool_register_reply_event(threadpool_t *tp, void (*cb)(threadpool_t *tp)); +unsigned int threadpool_get_n_threads(threadpool_t *tp); #endif /* !defined(TOR_WORKQUEUE_H) */