diff options
Diffstat (limited to 'ot_clean.c')
| -rw-r--r-- | ot_clean.c | 33 |
1 files changed, 31 insertions, 2 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> |
| @@ -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 | } | ||
