summaryrefslogtreecommitdiff
path: root/ot_clean.c
diff options
context:
space:
mode:
Diffstat (limited to 'ot_clean.c')
-rw-r--r--ot_clean.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/ot_clean.c b/ot_clean.c
index bf0504c..77ea239 100644
--- a/ot_clean.c
+++ b/ot_clean.c
@@ -4,6 +4,7 @@
4 $id$ */ 4 $id$ */
5 5
6/* System */ 6/* System */
7#include <errno.h>
7#include <pthread.h> 8#include <pthread.h>
8#include <string.h> 9#include <string.h>
9#include <unistd.h> 10#include <unistd.h>
@@ -46,7 +47,7 @@ static ssize_t clean_single_bucket(ot_peer *peers, size_t peer_count, size_t pee
46 47
47int clean_single_peer_list(ot_peerlist *peer_list, size_t peer_size) { 48int clean_single_peer_list(ot_peerlist *peer_list, size_t peer_size) {
48 ot_vector *peer_vector = &peer_list->peers; 49 ot_vector *peer_vector = &peer_list->peers;
49 time_t timedout = (time_t)(g_now_minutes - peer_list->base); 50 time_t timedout = (time_t)(time_now_minutes() - peer_list->base);
50 size_t num_buckets = 1, removed_seeders = 0; 51 size_t num_buckets = 1, removed_seeders = 0;
51 52
52 /* No need to clean empty torrent */ 53 /* No need to clean empty torrent */
@@ -87,11 +88,11 @@ int clean_single_peer_list(ot_peerlist *peer_list, size_t peer_size) {
87 vector_redistribute_buckets(peer_list, peer_size); 88 vector_redistribute_buckets(peer_list, peer_size);
88 89
89 if (peer_list->peer_count) 90 if (peer_list->peer_count)
90 peer_list->base = g_now_minutes; 91 peer_list->base = time_now_minutes();
91 else { 92 else {
92 /* When we got here, the last time that torrent 93 /* When we got here, the last time that torrent
93 has been touched is OT_PEER_TIMEOUT Minutes before */ 94 has been touched is OT_PEER_TIMEOUT Minutes before */
94 peer_list->base = g_now_minutes - OT_PEER_TIMEOUT; 95 peer_list->base = time_now_minutes() - OT_PEER_TIMEOUT;
95 } 96 }
96 return 0; 97 return 0;
97} 98}
@@ -103,6 +104,29 @@ int clean_single_torrent(ot_torrent *torrent) {
103 return clean_single_peer_list(torrent->peer_list6, OT_PEER_SIZE6) * clean_single_peer_list(torrent->peer_list4, OT_PEER_SIZE4); 104 return clean_single_peer_list(torrent->peer_list6, OT_PEER_SIZE6) * clean_single_peer_list(torrent->peer_list4, OT_PEER_SIZE4);
104} 105}
105 106
107static pthread_mutex_t g_clean_mutex = PTHREAD_MUTEX_INITIALIZER;
108static pthread_cond_t g_clean_wakeup = PTHREAD_COND_INITIALIZER;
109
110static void clean_sleep(void) {
111 struct timespec deadline;
112
113 clock_gettime(CLOCK_REALTIME, &deadline);
114 deadline.tv_sec += OT_CLEAN_SLEEP / 1000000;
115 deadline.tv_nsec += (OT_CLEAN_SLEEP % 1000000) * 1000;
116 if (deadline.tv_nsec >= 1000000000) {
117 ++deadline.tv_sec;
118 deadline.tv_nsec -= 1000000000;
119 }
120
121 /* Both sides hold the mutex, so the flag cannot be cleared and signalled
122 in the window between testing it and waiting on it */
123 pthread_mutex_lock(&g_clean_mutex);
124 while (g_opentracker_running)
125 if (pthread_cond_timedwait(&g_clean_wakeup, &g_clean_mutex, &deadline) == ETIMEDOUT)
126 break;
127 pthread_mutex_unlock(&g_clean_mutex);
128}
129
106/* Clean up all peers in current bucket, remove timedout pools and 130/* Clean up all peers in current bucket, remove timedout pools and
107 torrents */ 131 torrents */
108static void *clean_worker(void *args) { 132static void *clean_worker(void *args) {
@@ -125,7 +149,7 @@ static void *clean_worker(void *args) {
125 mutex_bucket_unlock(bucket, delta_torrentcount); 149 mutex_bucket_unlock(bucket, delta_torrentcount);
126 if (!g_opentracker_running) 150 if (!g_opentracker_running)
127 return NULL; 151 return NULL;
128 usleep(OT_CLEAN_SLEEP); 152 clean_sleep();
129 } 153 }
130 stats_cleanup(); 154 stats_cleanup();
131#ifdef WANT_ACCESSLIST 155#ifdef WANT_ACCESSLIST
@@ -138,4 +162,9 @@ static void *clean_worker(void *args) {
138static pthread_t thread_id; 162static pthread_t thread_id;
139void clean_init(void) { pthread_create(&thread_id, NULL, clean_worker, NULL); } 163void clean_init(void) { pthread_create(&thread_id, NULL, clean_worker, NULL); }
140 164
141void clean_deinit(void) { pthread_cancel(thread_id); } 165void clean_deinit(void) {
166 pthread_mutex_lock(&g_clean_mutex);
167 pthread_cond_signal(&g_clean_wakeup);
168 pthread_mutex_unlock(&g_clean_mutex);
169 pthread_join(thread_id, NULL);
170}