From 8900cc0dd980cb08a0af957a1d0dd849bf3c2ac6 Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Tue, 6 Nov 2007 11:58:32 +0000 Subject: No one can get access to buckets now without locking them. Also split up the trackerlogic.c-monster in functional sub-units. HEADS UP: this code is untested and not considered stable. --- ot_clean.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 ot_clean.c (limited to 'ot_clean.c') 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 @@ +/* This software was written by Dirk Engling + It is considered beerware. Prost. Skol. Cheers or whatever. */ + +/* System */ +#include +#include + +/* Libowfat */ +#include "byte.h" + +/* Opentracker */ +#include "trackerlogic.h" +#include "ot_mutex.h" + +/* To remember, when we last cleaned up */ +static ot_time all_torrents_clean[OT_BUCKET_COUNT]; + +/* Clean a single torrent + return 1 if torrent timed out +*/ +int clean_single_torrent( ot_torrent *torrent ) { + ot_peerlist *peer_list = torrent->peer_list; + size_t peers_count = 0, seeds_count; + time_t timedout = (int)( NOW - peer_list->base ); + int i; +#ifdef WANT_TRACKER_SYNC + char *new_peers; +#endif + + /* Torrent has idled out */ + if( timedout > OT_TORRENT_TIMEOUT ) + return 1; + + /* Nothing to be cleaned here? Test if torrent is worth keeping */ + if( timedout > OT_POOLS_COUNT ) { + if( !peer_list->peer_count ) + return peer_list->down_count ? 0 : 1; + timedout = OT_POOLS_COUNT; + } + + /* Release vectors that have timed out */ + for( i = OT_POOLS_COUNT - timedout; i < OT_POOLS_COUNT; ++i ) + free( peer_list->peers[i].data); + + /* Shift vectors back by the amount of pools that were shifted out */ + memmove( peer_list->peers + timedout, peer_list->peers, sizeof( ot_vector ) * ( OT_POOLS_COUNT - timedout ) ); + byte_zero( peer_list->peers, sizeof( ot_vector ) * timedout ); + + /* Shift back seed counts as well */ + memmove( peer_list->seed_counts + timedout, peer_list->seed_counts, sizeof( size_t ) * ( OT_POOLS_COUNT - timedout ) ); + byte_zero( peer_list->seed_counts, sizeof( size_t ) * timedout ); + +#ifdef WANT_TRACKER_SYNC + /* Save the block modified within last OT_POOLS_TIMEOUT */ + if( peer_list->peers[1].size && + ( new_peers = realloc( peer_list->changeset.data, sizeof( ot_peer ) * peer_list->peers[1].size ) ) ) + { + memmove( new_peers, peer_list->peers[1].data, peer_list->peers[1].size ); + peer_list->changeset.data = new_peers; + peer_list->changeset.size = sizeof( ot_peer ) * peer_list->peers[1].size; + } else { + free( peer_list->changeset.data ); + + memset( &peer_list->changeset, 0, sizeof( ot_vector ) ); + } +#endif + + peers_count = seeds_count = 0; + for( i = 0; i < OT_POOLS_COUNT; ++i ) { + peers_count += peer_list->peers[i].size; + seeds_count += peer_list->seed_counts[i]; + } + peer_list->seed_count = seeds_count; + peer_list->peer_count = peers_count; + + if( peers_count ) + peer_list->base = NOW; + else { + /* When we got here, the last time that torrent + has been touched is OT_POOLS_COUNT units before */ + peer_list->base = NOW - OT_POOLS_COUNT; + } + return 0; +} + +/* Clean up all peers in current bucket, remove timedout pools and + torrents */ +void clean_all_torrents( void ) { + ot_vector *torrents_list; + size_t i; + static int bucket; + ot_time time_now = NOW; + + /* Search for an uncleaned bucked */ + while( ( all_torrents_clean[bucket] == time_now ) && ( ++bucket < OT_BUCKET_COUNT ) ); + if( bucket >= OT_BUCKET_COUNT ) { + bucket = 0; return; + } + + all_torrents_clean[bucket] = time_now; + + torrents_list = mutex_bucket_lock( bucket ); + for( i=0; isize; ++i ) { + ot_torrent *torrent = ((ot_torrent*)(torrents_list->data)) + i; + if( clean_single_torrent( torrent ) ) { + vector_remove_torrent( torrents_list, torrent ); + --i; continue; + } + } + mutex_bucket_unlock( bucket ); +} + +void clean_init( void ) { + byte_zero( all_torrents_clean, sizeof( all_torrents_clean ) ); +} + +void clean_deinit( void ) { + byte_zero( all_torrents_clean, sizeof( all_torrents_clean ) ); +} \ No newline at end of file -- cgit v1.2.3