summaryrefslogtreecommitdiff
path: root/ot_clean.c
diff options
context:
space:
mode:
Diffstat (limited to 'ot_clean.c')
-rw-r--r--ot_clean.c102
1 files changed, 48 insertions, 54 deletions
diff --git a/ot_clean.c b/ot_clean.c
index 739e785..2506cc1 100644
--- a/ot_clean.c
+++ b/ot_clean.c
@@ -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 */
23static ssize_t clean_single_bucket( ot_peer *peers, size_t peer_count, size_t peer_size, time_t timedout, int *removed_seeders ) { 23static 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
51int clean_single_peer_list( ot_peerlist *peer_list, size_t peer_size ) { 50int 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*/
106int clean_single_torrent( ot_torrent *torrent ) { 105int 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 */
113static void * clean_worker( void * args ) { 111static 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
143static pthread_t thread_id; 141static pthread_t thread_id;
144void clean_init( void ) { 142void clean_init(void) { pthread_create(&thread_id, NULL, clean_worker, NULL); }
145 pthread_create( &thread_id, NULL, clean_worker, NULL );
146}
147 143
148void clean_deinit( void ) { 144void clean_deinit(void) { pthread_cancel(thread_id); }
149 pthread_cancel( thread_id );
150}
151 145
152const char *g_version_clean_c = "$Source$: $Revision$\n"; 146const char *g_version_clean_c = "$Source$: $Revision$\n";