#include "lib/net/alertsock.h"
#include "lib/net/socket.h"
#include "lib/thread/threads.h"
+#include "lib/time/compat_time.h"
#include "ext/tor_queue.h"
#include <event2/event.h>
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;
* pool->lock must be prelocked here. */
tor_mutex_acquire(&pool->lock);
+ if (control_lock_owner == 0) {
+ /* pool->control_lock stays locked. This is required for the main thread
+ * to wait for the worker threads to exit on shutdown, so the memory
+ * clean up won't begin before all threads have exited. */
+ 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());
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) {
+ /* Wait for the other worker threads to exit so we
+ * can safely unlock pool->control_lock. */
+ while (n_worker_threads_running > 1) {
+ tor_mutex_release(&pool->lock);
+ tor_sleep_msec(10);
+ tor_mutex_acquire(&pool->lock);
+ }
+
+ 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
/* 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. */
+ /* Let one of the worker threads take the ownership of pool->control_lock.
+ * This is required for compliance with POSIX. */
+ tor_mutex_release(&pool->control_lock);
return status;
}