tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

commit 451cc1d54b28918e49a191c2ea5ac45c28599961
parent e09c024c33d602ee363b8cb42f6a6a0cf4174932
Author: David Goulet <dgoulet@torproject.org>
Date:   Tue, 26 Aug 2025 10:16:39 -0400

Merge branch 'maint-0.4.8'

Diffstat:
Achanges/bug41109 | 3+++
Msrc/lib/evloop/workqueue.c | 31+++++++++++++++++++++++++------
2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/changes/bug41109 b/changes/bug41109 @@ -0,0 +1,3 @@ + o Minor bugfixes (threads): + - Make thread control POSIX compliant. + Fixes bug 41109; bugfix on 0.4.8.17-dev. diff --git a/src/lib/evloop/workqueue.c b/src/lib/evloop/workqueue.c @@ -278,6 +278,7 @@ static void worker_thread_main(void *thread_) { static int n_worker_threads_running = 0; + static unsigned long control_lock_owner = 0; workerthread_t *thread = thread_; threadpool_t *pool = thread->in_pool; workqueue_entry_t *work; @@ -297,6 +298,11 @@ worker_thread_main(void *thread_) * pool->lock must be prelocked here. */ tor_mutex_acquire(&pool->lock); + if (control_lock_owner == 0) { + tor_mutex_acquire(&pool->control_lock); + control_lock_owner = tor_get_thread_id(); + } + log_debug(LD_GENERAL, "Worker thread has entered the work loop [TID: %lu].", tor_get_thread_id()); @@ -362,11 +368,25 @@ exit: pool->n_threads_max - n_worker_threads_running + 1, pool->n_threads_max, tor_get_thread_id()); - if (--n_worker_threads_running == 0) + if (tor_get_thread_id() == control_lock_owner) { + if (n_worker_threads_running > 1) { + /* Wait for the other worker threads to exit so we + * can safely unlock pool->control_lock. */ + struct timespec ts = {.tv_sec = 0, .tv_nsec = 100000}; + do { + tor_mutex_release(&pool->lock); + nanosleep(&ts, NULL); + tor_mutex_acquire(&pool->lock); + } while (n_worker_threads_running > 1); + } + + tor_mutex_release(&pool->lock); /* Let the main thread know, the last worker thread has exited. */ tor_mutex_release(&pool->control_lock); - - tor_mutex_release(&pool->lock); + } else { + --n_worker_threads_running; + tor_mutex_release(&pool->lock); + } } /** Put a reply on the reply queue. The reply must not currently be on @@ -621,12 +641,11 @@ check_status: log_debug(LD_GENERAL, "Signaled the worker threads to exit..."); } + /* Let one of the worker threads take the ownership of pool->control_lock */ + tor_mutex_release(&pool->control_lock); /* Let worker threads enter the work loop. */ tor_mutex_release(&pool->lock); - /* pool->control_lock stays locked. This is required for the main thread - * to wait for the worker threads to exit on shutdown. */ - return status; }