diff options
Diffstat (limited to 'ot_clean.c')
-rw-r--r-- | ot_clean.c | 102 |
1 files changed, 48 insertions, 54 deletions
@@ -5,80 +5,79 @@ | |||
5 | 5 | ||
6 | /* System */ | 6 | /* System */ |
7 | #include <pthread.h> | 7 | #include <pthread.h> |
8 | #include <unistd.h> | ||
9 | #include <string.h> | 8 | #include <string.h> |
9 | #include <unistd.h> | ||
10 | 10 | ||
11 | /* Libowfat */ | 11 | /* Libowfat */ |
12 | #include "io.h" | 12 | #include "io.h" |
13 | 13 | ||
14 | /* Opentracker */ | 14 | /* Opentracker */ |
15 | #include "trackerlogic.h" | 15 | #include "ot_accesslist.h" |
16 | #include "ot_mutex.h" | ||
17 | #include "ot_vector.h" | ||
18 | #include "ot_clean.h" | 16 | #include "ot_clean.h" |
17 | #include "ot_mutex.h" | ||
19 | #include "ot_stats.h" | 18 | #include "ot_stats.h" |
20 | #include "ot_accesslist.h" | 19 | #include "ot_vector.h" |
20 | #include "trackerlogic.h" | ||
21 | 21 | ||
22 | /* Returns amount of removed peers */ | 22 | /* Returns amount of removed peers */ |
23 | static ssize_t clean_single_bucket( ot_peer *peers, size_t peer_count, size_t peer_size, time_t timedout, int *removed_seeders ) { | 23 | static ssize_t clean_single_bucket(ot_peer *peers, size_t peer_count, size_t peer_size, time_t timedout, int *removed_seeders) { |
24 | ot_peer *last_peer = peers + peer_count * peer_size, *insert_point; | 24 | ot_peer *last_peer = peers + peer_count * peer_size, *insert_point; |
25 | 25 | ||
26 | /* Two scan modes: unless there is one peer removed, just increase ot_peertime */ | 26 | /* Two scan modes: unless there is one peer removed, just increase ot_peertime */ |
27 | while( peers < last_peer ) { | 27 | while (peers < last_peer) { |
28 | time_t timediff = timedout + OT_PEERTIME( peers, peer_size ); | 28 | time_t timediff = timedout + OT_PEERTIME(peers, peer_size); |
29 | if( timediff >= OT_PEER_TIMEOUT ) | 29 | if (timediff >= OT_PEER_TIMEOUT) |
30 | break; | 30 | break; |
31 | OT_PEERTIME( peers, peer_size ) = timediff; | 31 | OT_PEERTIME(peers, peer_size) = timediff; |
32 | peers += peer_size; | 32 | peers += peer_size; |
33 | } | 33 | } |
34 | 34 | ||
35 | /* If we at least remove one peer, we have to copy */ | 35 | /* If we at least remove one peer, we have to copy */ |
36 | for( insert_point = peers; peers < last_peer; peers += peer_size ) { | 36 | for (insert_point = peers; peers < last_peer; peers += peer_size) { |
37 | time_t timediff = timedout + OT_PEERTIME( peers, peer_size ); | 37 | time_t timediff = timedout + OT_PEERTIME(peers, peer_size); |
38 | 38 | ||
39 | if( timediff < OT_PEER_TIMEOUT ) { | 39 | if (timediff < OT_PEER_TIMEOUT) { |
40 | OT_PEERTIME( peers, peer_size ) = timediff; | 40 | OT_PEERTIME(peers, peer_size) = timediff; |
41 | memcpy( insert_point, peers, peer_size); | 41 | memcpy(insert_point, peers, peer_size); |
42 | insert_point += peer_size; | 42 | insert_point += peer_size; |
43 | } else | 43 | } else if (OT_PEERFLAG_D(peers, peer_size) & PEER_FLAG_SEEDING) |
44 | if( OT_PEERFLAG_D( peers, peer_size ) & PEER_FLAG_SEEDING ) | 44 | (*removed_seeders)++; |
45 | (*removed_seeders)++; | ||
46 | } | 45 | } |
47 | 46 | ||
48 | return (peers - insert_point) / peer_size; | 47 | return (peers - insert_point) / peer_size; |
49 | } | 48 | } |
50 | 49 | ||
51 | int clean_single_peer_list( ot_peerlist *peer_list, size_t peer_size ) { | 50 | int clean_single_peer_list(ot_peerlist *peer_list, size_t peer_size) { |
52 | ot_vector *peer_vector = &peer_list->peers; | 51 | ot_vector *peer_vector = &peer_list->peers; |
53 | time_t timedout = (time_t)( g_now_minutes - peer_list->base ); | 52 | time_t timedout = (time_t)(g_now_minutes - peer_list->base); |
54 | int num_buckets = 1, removed_seeders = 0; | 53 | int num_buckets = 1, removed_seeders = 0; |
55 | 54 | ||
56 | /* No need to clean empty torrent */ | 55 | /* No need to clean empty torrent */ |
57 | if( !timedout ) | 56 | if (!timedout) |
58 | return 0; | 57 | return 0; |
59 | 58 | ||
60 | /* Torrent has idled out */ | 59 | /* Torrent has idled out */ |
61 | if( timedout > OT_TORRENT_TIMEOUT ) | 60 | if (timedout > OT_TORRENT_TIMEOUT) |
62 | return 1; | 61 | return 1; |
63 | 62 | ||
64 | /* Nothing to be cleaned here? Test if torrent is worth keeping */ | 63 | /* Nothing to be cleaned here? Test if torrent is worth keeping */ |
65 | if( timedout > OT_PEER_TIMEOUT ) { | 64 | if (timedout > OT_PEER_TIMEOUT) { |
66 | if( !peer_list->peer_count ) | 65 | if (!peer_list->peer_count) |
67 | return peer_list->down_count ? 0 : 1; | 66 | return peer_list->down_count ? 0 : 1; |
68 | timedout = OT_PEER_TIMEOUT; | 67 | timedout = OT_PEER_TIMEOUT; |
69 | } | 68 | } |
70 | 69 | ||
71 | if( OT_PEERLIST_HASBUCKETS( peer_list ) ) { | 70 | if (OT_PEERLIST_HASBUCKETS(peer_list)) { |
72 | num_buckets = peer_vector->size; | 71 | num_buckets = peer_vector->size; |
73 | peer_vector = (ot_vector *)peer_vector->data; | 72 | peer_vector = (ot_vector *)peer_vector->data; |
74 | } | 73 | } |
75 | 74 | ||
76 | while( num_buckets-- ) { | 75 | while (num_buckets--) { |
77 | size_t removed_peers = clean_single_bucket( peer_vector->data, peer_vector->size, peer_size, timedout, &removed_seeders ); | 76 | size_t removed_peers = clean_single_bucket(peer_vector->data, peer_vector->size, peer_size, timedout, &removed_seeders); |
78 | peer_list->peer_count -= removed_peers; | 77 | peer_list->peer_count -= removed_peers; |
79 | peer_vector->size -= removed_peers; | 78 | peer_vector->size -= removed_peers; |
80 | if( removed_peers ) | 79 | if (removed_peers) |
81 | vector_fixup_peers( peer_vector, peer_size ); | 80 | vector_fixup_peers(peer_vector, peer_size); |
82 | 81 | ||
83 | /* Skip to next bucket, a vector containing peers */ | 82 | /* Skip to next bucket, a vector containing peers */ |
84 | ++peer_vector; | 83 | ++peer_vector; |
@@ -87,10 +86,10 @@ int clean_single_peer_list( ot_peerlist *peer_list, size_t peer_size ) { | |||
87 | peer_list->seed_count -= removed_seeders; | 86 | peer_list->seed_count -= removed_seeders; |
88 | 87 | ||
89 | /* See if we need to convert a torrent from simple vector to bucket list */ | 88 | /* See if we need to convert a torrent from simple vector to bucket list */ |
90 | if( ( peer_list->peer_count > OT_PEER_BUCKET_MINCOUNT ) || OT_PEERLIST_HASBUCKETS(peer_list) ) | 89 | if ((peer_list->peer_count > OT_PEER_BUCKET_MINCOUNT) || OT_PEERLIST_HASBUCKETS(peer_list)) |
91 | vector_redistribute_buckets( peer_list, peer_size ); | 90 | vector_redistribute_buckets(peer_list, peer_size); |
92 | 91 | ||
93 | if( peer_list->peer_count ) | 92 | if (peer_list->peer_count) |
94 | peer_list->base = g_now_minutes; | 93 | peer_list->base = g_now_minutes; |
95 | else { | 94 | else { |
96 | /* When we got here, the last time that torrent | 95 | /* When we got here, the last time that torrent |
@@ -103,34 +102,33 @@ int clean_single_peer_list( ot_peerlist *peer_list, size_t peer_size ) { | |||
103 | /* Clean a single torrent | 102 | /* Clean a single torrent |
104 | return 1 if torrent timed out | 103 | return 1 if torrent timed out |
105 | */ | 104 | */ |
106 | int clean_single_torrent( ot_torrent *torrent ) { | 105 | int clean_single_torrent(ot_torrent *torrent) { |
107 | return clean_single_peer_list( torrent->peer_list6, OT_PEER_SIZE6) * | 106 | return clean_single_peer_list(torrent->peer_list6, OT_PEER_SIZE6) * clean_single_peer_list(torrent->peer_list4, OT_PEER_SIZE4); |
108 | clean_single_peer_list( torrent->peer_list4, OT_PEER_SIZE4); | ||
109 | } | 107 | } |
110 | 108 | ||
111 | /* Clean up all peers in current bucket, remove timedout pools and | 109 | /* Clean up all peers in current bucket, remove timedout pools and |
112 | torrents */ | 110 | torrents */ |
113 | static void * clean_worker( void * args ) { | 111 | static void *clean_worker(void *args) { |
114 | (void) args; | 112 | (void)args; |
115 | while( 1 ) { | 113 | while (1) { |
116 | int bucket = OT_BUCKET_COUNT; | 114 | int bucket = OT_BUCKET_COUNT; |
117 | while( bucket-- ) { | 115 | while (bucket--) { |
118 | ot_vector *torrents_list = mutex_bucket_lock( bucket ); | 116 | ot_vector *torrents_list = mutex_bucket_lock(bucket); |
119 | size_t toffs; | 117 | size_t toffs; |
120 | int delta_torrentcount = 0; | 118 | int delta_torrentcount = 0; |
121 | 119 | ||
122 | for( toffs=0; toffs<torrents_list->size; ++toffs ) { | 120 | for (toffs = 0; toffs < torrents_list->size; ++toffs) { |
123 | ot_torrent *torrent = ((ot_torrent*)(torrents_list->data)) + toffs; | 121 | ot_torrent *torrent = ((ot_torrent *)(torrents_list->data)) + toffs; |
124 | if( clean_single_torrent( torrent ) ) { | 122 | if (clean_single_torrent(torrent)) { |
125 | vector_remove_torrent( torrents_list, torrent ); | 123 | vector_remove_torrent(torrents_list, torrent); |
126 | --delta_torrentcount; | 124 | --delta_torrentcount; |
127 | --toffs; | 125 | --toffs; |
128 | } | 126 | } |
129 | } | 127 | } |
130 | mutex_bucket_unlock( bucket, delta_torrentcount ); | 128 | mutex_bucket_unlock(bucket, delta_torrentcount); |
131 | if( !g_opentracker_running ) | 129 | if (!g_opentracker_running) |
132 | return NULL; | 130 | return NULL; |
133 | usleep( OT_CLEAN_SLEEP ); | 131 | usleep(OT_CLEAN_SLEEP); |
134 | } | 132 | } |
135 | stats_cleanup(); | 133 | stats_cleanup(); |
136 | #ifdef WANT_ACCESSLIST | 134 | #ifdef WANT_ACCESSLIST |
@@ -141,12 +139,8 @@ static void * clean_worker( void * args ) { | |||
141 | } | 139 | } |
142 | 140 | ||
143 | static pthread_t thread_id; | 141 | static pthread_t thread_id; |
144 | void clean_init( void ) { | 142 | void clean_init(void) { pthread_create(&thread_id, NULL, clean_worker, NULL); } |
145 | pthread_create( &thread_id, NULL, clean_worker, NULL ); | ||
146 | } | ||
147 | 143 | ||
148 | void clean_deinit( void ) { | 144 | void clean_deinit(void) { pthread_cancel(thread_id); } |
149 | pthread_cancel( thread_id ); | ||
150 | } | ||
151 | 145 | ||
152 | const char *g_version_clean_c = "$Source$: $Revision$\n"; | 146 | const char *g_version_clean_c = "$Source$: $Revision$\n"; |