From 3e926ca209e9ed7946d8287e579bdaff05f3c2b3 Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Thu, 5 Nov 2026 19:00:31 +0100 Subject: Use poll instead of a condition variable to time the sleepers --- src/ot_clean.c | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/ot_clean.c b/src/ot_clean.c index 2ebfd42..dfac011 100644 --- a/src/ot_clean.c +++ b/src/ot_clean.c @@ -2,8 +2,9 @@ It is considered beerware. Prost. Skol. Cheers or whatever. */ /* System */ -#include +#include #include +#include #include #include @@ -102,27 +103,18 @@ 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; +/* Written to once, by clean_deinit, and never read: the byte stays in and + every sleep after it returns at once */ +static int g_clean_pipe[2] = {-1, -1}; 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; - } + struct pollfd pfd; - /* 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); + pfd.fd = g_clean_pipe[0]; + pfd.events = POLLIN; + pfd.revents = 0; + + poll(&pfd, 1, OT_CLEAN_SLEEP / 1000); } /* Clean up all peers in one bucket, remove timedout pools and torrents */ @@ -166,11 +158,18 @@ 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_init(void) { + if (pipe(g_clean_pipe) == -1) + fprintf(stderr, "Warning: the cleaner has no pipe to be woken through and will take up to one sleep interval to stop.\n"); + pthread_create(&thread_id, NULL, clean_worker, NULL); +} void clean_deinit(void) { - pthread_mutex_lock(&g_clean_mutex); - pthread_cond_signal(&g_clean_wakeup); - pthread_mutex_unlock(&g_clean_mutex); + const char byte = 0; + + (void)!write(g_clean_pipe[1], &byte, 1); pthread_join(thread_id, NULL); + + close(g_clean_pipe[0]); + close(g_clean_pipe[1]); } -- cgit v1.3