size_t base_url_len;
int torrent_id;
tr_bool is_stopping;
+ int consecutive_failures;
};
enum
{
- TR_IDLE_TIMER_MSEC = 2000
+ TR_IDLE_TIMER_MSEC = 2000,
+
+ MAX_CONSECUIVE_FAILURES = 5
};
static void
}
static void
-fire_client_got_block( tr_torrent * tor, tr_webseed * w, tr_block_index_t block )
+fire_client_got_rej( tr_torrent * tor, tr_webseed * w, tr_block_index_t block )
{
tr_peer_event e = blank_event;
+ e.eventType = TR_PEER_CLIENT_GOT_REJ;
e.pieceIndex = tr_torBlockPiece( tor, block );
e.offset = tor->blockSize * block - tor->info.pieceSize * e.pieceIndex;
e.length = tr_torBlockCountBytes( tor, block );
+ publish( w, &e );
+}
+
+static void
+fire_client_got_block( tr_torrent * tor, tr_webseed * w, tr_block_index_t block )
+{
+ tr_peer_event e = blank_event;
e.eventType = TR_PEER_CLIENT_GOT_BLOCK;
+ e.pieceIndex = tr_torBlockPiece( tor, block );
+ e.offset = tor->blockSize * block - tor->info.pieceSize * e.pieceIndex;
+ e.length = tr_torBlockCountBytes( tor, block );
publish( w, &e );
}
{
webseed_free( w );
}
- else if( !w->is_stopping && tor && tor->isRunning && !tr_torrentIsSeed( tor ) )
+ else if( !w->is_stopping && tor
+ && tor->isRunning
+ && !tr_torrentIsSeed( tor )
+ && ( w->consecutive_failures < MAX_CONSECUIVE_FAILURES ) )
{
int i;
int got = 0;
void * vtask )
{
struct tr_webseed_task * t = vtask;
+ tr_webseed * w = t->webseed;
tr_torrent * tor = tr_torrentFindFromId( session, t->torrent_id );
const int success = ( response_code == 206 );
- if( success && tor )
+ if( success )
+ w->consecutive_failures = 0;
+ else
+ ++w->consecutive_failures;
+
+ if( tor )
{
- if( evbuffer_get_length( t->content ) < t->length )
- {
- task_request_next_chunk( t );
- }
- else
+ if( !success )
{
- tr_webseed * w = t->webseed;
-
- tr_cacheWriteBlock( session->cache, tor,
- t->piece_index, t->piece_offset, t->length,
- t->content );
- fire_client_got_block( tor, w, t->block );
+ fire_client_got_rej( tor, w, t->block );
tr_list_remove_data( &w->tasks, t );
evbuffer_free( t->content );
tr_free( t );
-
- on_idle( w );
+ }
+ else
+ {
+ if( evbuffer_get_length( t->content ) < t->length )
+ {
+ task_request_next_chunk( t );
+ }
+ else
+ {
+ tr_cacheWriteBlock( session->cache, tor,
+ t->piece_index, t->piece_offset, t->length,
+ t->content );
+ fire_client_got_block( tor, w, t->block );
+
+ tr_list_remove_data( &w->tasks, t );
+ evbuffer_free( t->content );
+ tr_free( t );
+
+ on_idle( w );
+ }
}
}
}