diff options
Diffstat (limited to 'ot_clean.c')
| -rw-r--r-- | ot_clean.c | 39 |
1 files changed, 34 insertions, 5 deletions
| @@ -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 | ||
| 47 | int clean_single_peer_list(ot_peerlist *peer_list, size_t peer_size) { | 48 | int 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 | ||
| 107 | static pthread_mutex_t g_clean_mutex = PTHREAD_MUTEX_INITIALIZER; | ||
| 108 | static pthread_cond_t g_clean_wakeup = PTHREAD_COND_INITIALIZER; | ||
| 109 | |||
| 110 | static 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 */ |
| 108 | static void *clean_worker(void *args) { | 132 | static 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) { | |||
| 138 | static pthread_t thread_id; | 162 | static pthread_t thread_id; |
| 139 | void clean_init(void) { pthread_create(&thread_id, NULL, clean_worker, NULL); } | 163 | void clean_init(void) { pthread_create(&thread_id, NULL, clean_worker, NULL); } |
| 140 | 164 | ||
| 141 | void clean_deinit(void) { pthread_cancel(thread_id); } | 165 | void 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 | } | ||
