From 6cbd21542cf7a751e6f0f38864e7e9eae8fa3b14 Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Tue, 27 Oct 2026 21:32:24 +0100 Subject: Plug in the new per-thread stats counter, also make sure that the ot_clean sleep does not stall tracker exit --- ot_clean.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'ot_clean.c') diff --git a/ot_clean.c b/ot_clean.c index dbfa04e..77ea239 100644 --- a/ot_clean.c +++ b/ot_clean.c @@ -4,6 +4,7 @@ $id$ */ /* System */ +#include #include #include #include @@ -103,6 +104,29 @@ int clean_single_torrent(ot_torrent *torrent) { return clean_single_peer_list(torrent->peer_list6, OT_PEER_SIZE6) * clean_single_peer_list(torrent->peer_list4, OT_PEER_SIZE4); } +static pthread_mutex_t g_clean_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t g_clean_wakeup = PTHREAD_COND_INITIALIZER; + +static void clean_sleep(void) { + struct timespec deadline; + + clock_gettime(CLOCK_REALTIME, &deadline); + deadline.tv_sec += OT_CLEAN_SLEEP / 1000000; + deadline.tv_nsec += (OT_CLEAN_SLEEP % 1000000) * 1000; + if (deadline.tv_nsec >= 1000000000) { + ++deadline.tv_sec; + deadline.tv_nsec -= 1000000000; + } + + /* Both sides hold the mutex, so the flag cannot be cleared and signalled + in the window between testing it and waiting on it */ + pthread_mutex_lock(&g_clean_mutex); + while (g_opentracker_running) + if (pthread_cond_timedwait(&g_clean_wakeup, &g_clean_mutex, &deadline) == ETIMEDOUT) + break; + pthread_mutex_unlock(&g_clean_mutex); +} + /* Clean up all peers in current bucket, remove timedout pools and torrents */ static void *clean_worker(void *args) { @@ -125,7 +149,7 @@ static void *clean_worker(void *args) { mutex_bucket_unlock(bucket, delta_torrentcount); if (!g_opentracker_running) return NULL; - usleep(OT_CLEAN_SLEEP); + clean_sleep(); } stats_cleanup(); #ifdef WANT_ACCESSLIST @@ -138,4 +162,9 @@ static void *clean_worker(void *args) { static pthread_t thread_id; void clean_init(void) { pthread_create(&thread_id, NULL, clean_worker, NULL); } -void clean_deinit(void) { pthread_cancel(thread_id); } +void clean_deinit(void) { + pthread_mutex_lock(&g_clean_mutex); + pthread_cond_signal(&g_clean_wakeup); + pthread_mutex_unlock(&g_clean_mutex); + pthread_join(thread_id, NULL); +} -- cgit v1.3