summaryrefslogtreecommitdiff
path: root/ot_clean.c
diff options
context:
space:
mode:
Diffstat (limited to 'ot_clean.c')
-rw-r--r--ot_clean.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/ot_clean.c b/ot_clean.c
new file mode 100644
index 0000000..46b3e0c
--- /dev/null
+++ b/ot_clean.c
@@ -0,0 +1,119 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4/* System */
5#include <stdlib.h>
6#include <string.h>
7
8/* Libowfat */
9#include "byte.h"
10
11/* Opentracker */
12#include "trackerlogic.h"
13#include "ot_mutex.h"
14
15/* To remember, when we last cleaned up */
16static ot_time all_torrents_clean[OT_BUCKET_COUNT];
17
18/* Clean a single torrent
19 return 1 if torrent timed out
20*/
21int clean_single_torrent( ot_torrent *torrent ) {
22 ot_peerlist *peer_list = torrent->peer_list;
23 size_t peers_count = 0, seeds_count;
24 time_t timedout = (int)( NOW - peer_list->base );
25 int i;
26#ifdef WANT_TRACKER_SYNC
27 char *new_peers;
28#endif
29
30 /* Torrent has idled out */
31 if( timedout > OT_TORRENT_TIMEOUT )
32 return 1;
33
34 /* Nothing to be cleaned here? Test if torrent is worth keeping */
35 if( timedout > OT_POOLS_COUNT ) {
36 if( !peer_list->peer_count )
37 return peer_list->down_count ? 0 : 1;
38 timedout = OT_POOLS_COUNT;
39 }
40
41 /* Release vectors that have timed out */
42 for( i = OT_POOLS_COUNT - timedout; i < OT_POOLS_COUNT; ++i )
43 free( peer_list->peers[i].data);
44
45 /* Shift vectors back by the amount of pools that were shifted out */
46 memmove( peer_list->peers + timedout, peer_list->peers, sizeof( ot_vector ) * ( OT_POOLS_COUNT - timedout ) );
47 byte_zero( peer_list->peers, sizeof( ot_vector ) * timedout );
48
49 /* Shift back seed counts as well */
50 memmove( peer_list->seed_counts + timedout, peer_list->seed_counts, sizeof( size_t ) * ( OT_POOLS_COUNT - timedout ) );
51 byte_zero( peer_list->seed_counts, sizeof( size_t ) * timedout );
52
53#ifdef WANT_TRACKER_SYNC
54 /* Save the block modified within last OT_POOLS_TIMEOUT */
55 if( peer_list->peers[1].size &&
56 ( new_peers = realloc( peer_list->changeset.data, sizeof( ot_peer ) * peer_list->peers[1].size ) ) )
57 {
58 memmove( new_peers, peer_list->peers[1].data, peer_list->peers[1].size );
59 peer_list->changeset.data = new_peers;
60 peer_list->changeset.size = sizeof( ot_peer ) * peer_list->peers[1].size;
61 } else {
62 free( peer_list->changeset.data );
63
64 memset( &peer_list->changeset, 0, sizeof( ot_vector ) );
65 }
66#endif
67
68 peers_count = seeds_count = 0;
69 for( i = 0; i < OT_POOLS_COUNT; ++i ) {
70 peers_count += peer_list->peers[i].size;
71 seeds_count += peer_list->seed_counts[i];
72 }
73 peer_list->seed_count = seeds_count;
74 peer_list->peer_count = peers_count;
75
76 if( peers_count )
77 peer_list->base = NOW;
78 else {
79 /* When we got here, the last time that torrent
80 has been touched is OT_POOLS_COUNT units before */
81 peer_list->base = NOW - OT_POOLS_COUNT;
82 }
83 return 0;
84}
85
86/* Clean up all peers in current bucket, remove timedout pools and
87 torrents */
88void clean_all_torrents( void ) {
89 ot_vector *torrents_list;
90 size_t i;
91 static int bucket;
92 ot_time time_now = NOW;
93
94 /* Search for an uncleaned bucked */
95 while( ( all_torrents_clean[bucket] == time_now ) && ( ++bucket < OT_BUCKET_COUNT ) );
96 if( bucket >= OT_BUCKET_COUNT ) {
97 bucket = 0; return;
98 }
99
100 all_torrents_clean[bucket] = time_now;
101
102 torrents_list = mutex_bucket_lock( bucket );
103 for( i=0; i<torrents_list->size; ++i ) {
104 ot_torrent *torrent = ((ot_torrent*)(torrents_list->data)) + i;
105 if( clean_single_torrent( torrent ) ) {
106 vector_remove_torrent( torrents_list, torrent );
107 --i; continue;
108 }
109 }
110 mutex_bucket_unlock( bucket );
111}
112
113void clean_init( void ) {
114 byte_zero( all_torrents_clean, sizeof( all_torrents_clean ) );
115}
116
117void clean_deinit( void ) {
118 byte_zero( all_torrents_clean, sizeof( all_torrents_clean ) );
119} \ No newline at end of file