Permalink
Browse files

Added 'streaming' capability to libtransmission. Additionally #5755, …

…#5754, #5736, #5734
  • Loading branch information...
cfpp2p
cfpp2p committed Jul 31, 2014
1 parent e418740 commit e91d645d9a89c4591ef478e0979d558e8c70e90b
View
@@ -167,7 +167,7 @@ struct block_request
struct weighted_piece
{
tr_piece_index_t index;
int16_t salt;
tr_piece_index_t salt;
int16_t requestCount;
};
@@ -965,6 +965,13 @@ comparePieceByWeight( const void * va, const void * vb )
const tr_torrent * tor = weightTorrent;
const uint16_t * rep = weightReplication;
/* forced streaming */
if( tr_torrentGetStreamingMode( tor ) >= TR_STREAMING_FORCED )
{
if( a->salt < b->salt ) return -1;
if( a->salt > b->salt ) return 1;
}
/* primary key: weight */
missing = tr_cpMissingBlocksInPiece( &tor->completion, a->index );
pending = a->requestCount;
@@ -975,12 +982,26 @@ comparePieceByWeight( const void * va, const void * vb )
if( ia < ib ) return -1;
if( ia > ib ) return 1;
/* weighted streaming */
if( tr_torrentGetStreamingMode( tor ) == TR_STREAMING_WEIGHTED )
{
if( a->salt < b->salt ) return -1;
if( a->salt > b->salt ) return 1;
}
/* secondary key: higher priorities go first */
ia = tor->info.pieces[a->index].priority;
ib = tor->info.pieces[b->index].priority;
if( ia > ib ) return -1;
if( ia < ib ) return 1;
/* priority streaming */
if( tr_torrentGetStreamingMode( tor ) == TR_STREAMING_PRIORITY )
{
if( a->salt < b->salt ) return -1;
if( a->salt > b->salt ) return 1;
}
/* tertiary key: rarest first. */
ia = rep[a->index];
ib = rep[b->index];
@@ -1090,6 +1111,9 @@ pieceListRebuild( Torrent * t )
if( !tr_torrentIsSeed( t->tor ) )
{
// tr_streamingMode_t streamingMode = tr_torrentGetStreamingMode( t->tor );
tr_piece_index_t i;
tr_piece_index_t * pool;
tr_piece_index_t poolCount = 0;
@@ -1110,7 +1134,14 @@ pieceListRebuild( Torrent * t )
struct weighted_piece * piece = pieces + i;
piece->index = pool[i];
piece->requestCount = 0;
piece->salt = tr_cryptoWeakRandInt( 4096 );
// piece->salt = tr_cryptoWeakRandInt( 4096 );
if( tr_torrentGetStreamingMode( t->tor ) > TR_STREAMING_OFF )
piece->salt = piece->index;
else
piece->salt = (tr_piece_index_t)tr_cryptoWeakRandInt( 4096 );
}
/* if we already had a list of pieces, merge it into
View
@@ -48,6 +48,7 @@
#define KEY_IDLELIMIT "idle-limit"
#define KEY_UPLOADED "uploaded"
#define KEY_CHEATMODE "cheat-mode"
#define KEY_STREAMINGMODE "streaming-mode"
#define KEY_SPEED_KiBps "speed"
#define KEY_SPEED_Bps "speed-Bps"
@@ -303,6 +304,13 @@ saveCheatMode( tr_benc * dict, const tr_torrent * tor )
tr_bencDictAddInt( dict, KEY_CHEATMODE, tr_torrentGetCheatMode( tor ) );
}
static void
saveStreamingMode( tr_benc * dict, const tr_torrent * tor )
{
tr_bencDictReserve( dict, 1 );
tr_bencDictAddInt( dict, KEY_STREAMINGMODE, tr_torrentGetStreamingMode( tor ) );
}
static void
loadSingleSpeedLimit( tr_benc * d, tr_direction dir, tr_torrent * tor )
{
@@ -423,6 +431,21 @@ loadCheatMode( tr_benc * dict, tr_torrent * tor)
return ret;
}
static uint64_t
loadStreamingMode( tr_benc * dict, tr_torrent * tor)
{
uint64_t ret = 0;
int64_t val;
if( tr_bencDictFindInt( dict, KEY_STREAMINGMODE, &val ) )
{
tr_torrentSetStreamingMode( tor, (uint8_t) val );
ret = TR_FR_STREAMINGMODE;
}
return ret;
}
/***
****
***/
@@ -683,6 +706,7 @@ tr_torrentSaveResume( tr_torrent * tor )
saveSpeedLimits( &top, tor );
saveRatioLimits( &top, tor );
saveIdleLimits( &top, tor );
saveStreamingMode( &top, tor );
saveCheatMode( &top, tor );
filename = getResumeFilename( tor );
@@ -848,9 +872,13 @@ loadFromFile( tr_torrent * tor, uint64_t fieldsToLoad )
if( fieldsToLoad & TR_FR_IDLELIMIT )
fieldsLoaded |= loadIdleLimits( &top, tor );
if( fieldsToLoad & TR_FR_STREAMINGMODE )
fieldsLoaded |= loadStreamingMode( &top, tor );
if( fieldsToLoad & TR_FR_CHEATMODE )
fieldsLoaded |= loadCheatMode( &top, tor );
/* loading the resume file triggers of a lot of changes,
* but none of them needs to trigger a re-saving of the
* same resume information... */
View
@@ -39,8 +39,9 @@ enum
TR_FR_IDLELIMIT = ( 1 << 17 ),
TR_FR_TIME_SEEDING = ( 1 << 18 ),
TR_FR_TIME_DOWNLOADING = ( 1 << 19 ),
TR_FR_CHEATMODE = ( 1 << 20 ),
TR_FR_PIECE_TEMP_DIR = ( 1 << 21 )
TR_FR_STREAMINGMODE = ( 1 << 20 ),
TR_FR_CHEATMODE = ( 1 << 21 ),
TR_FR_PIECE_TEMP_DIR = ( 1 << 22 )
};
/**
@@ -611,6 +611,8 @@ addField( const tr_torrent * const tor,
tr_bencDictAddInt( d, key, st->addedDate );
else if( tr_streq( key, keylen, "bandwidthPriority" ) )
tr_bencDictAddInt( d, key, tr_torrentGetPriority( tor ) );
else if( tr_streq( key, keylen, "streamingMode" ) )
tr_bencDictAddInt( d, key, tr_torrentGetStreamingMode( tor ) );
else if( tr_streq( key, keylen, "cheatMode" ) )
tr_bencDictAddInt( d, key, tr_torrentGetCheatMode( tor ) );
else if( tr_streq( key, keylen, "comment" ) )
@@ -1132,6 +1134,8 @@ torrentSet( tr_session * session,
if( tr_bencDictFindInt( args_in, "bandwidthPriority", &tmp ) )
if( tr_isPriority( tmp ) )
tr_torrentSetPriority( tor, tmp );
if( tr_bencDictFindInt( args_in, "streamingMode", &tmp ) )
tr_torrentSetStreamingMode( tor, tmp );
if( tr_bencDictFindInt( args_in, "cheatMode", &tmp ) )
tr_torrentSetCheatMode( tor, tmp );
if( !errmsg && tr_bencDictFindList( args_in, "files-unwanted", &files ) )
View
@@ -269,6 +269,30 @@ tr_torrentGetCheatMode( const tr_torrent * tor )
return tor->cheatMode;
}
void
tr_torrentSetStreamingMode( tr_torrent * tor, tr_streamingMode_t mode )
{
assert( tr_isTorrent( tor ) );
if( ( mode >= TR_STREAMING_OFF ) && ( mode < TR_STREAMING_COUNT ) && ( mode != tor->streamingMode ) )
{
tr_torrentLock( tor );
tor->streamingMode = mode;
tr_torrentSetDirty( tor );
tr_peerMgrRebuildRequests( tor );
tr_torrentUnlock( tor );
}
}
tr_streamingMode_t
tr_torrentGetStreamingMode( const tr_torrent * tor )
{
assert( tr_isTorrent( tor ) );
return tor->streamingMode;
}
void
tr_torrentSetRatioMode( tr_torrent * tor, tr_ratiolimit mode )
{
@@ -968,6 +992,11 @@ torrentInit( tr_torrent * tor, const tr_ctor * ctor )
tr_torrentSetIdleLimit( tor, tr_sessionGetIdleLimit( tor->session ) );
}
if( !( loaded & TR_FR_STREAMINGMODE ) )
{
tr_torrentSetStreamingMode( tor, TR_STREAMING_OFF );
}
if( !( loaded & TR_FR_CHEATMODE ) )
{
tr_torrentSetCheatMode( tor, TR_CHEAT_DEACT );
@@ -2112,12 +2141,22 @@ removeTorrent( void * vdata )
{
struct remove_data * data = vdata;
// July 25 2014 -cfp- we need to make sure the torrent is stopped
// and locked to prevent crashes with stalled peer io and cache
tr_session * session = data->tor->session;
tr_sessionLock( session );
if( data->deleteFlag )
{
stopTorrent( data->tor );
tr_torrentDeleteLocalData( data->tor, data->deleteFunc );
}
tr_torrentClearCompletenessCallback( data->tor );
closeTorrent( data->tor );
tr_free( data );
tr_sessionUnlock( session );
}
void
@@ -2128,13 +2167,21 @@ tr_torrentRemove( tr_torrent * tor,
struct remove_data * data;
assert( tr_isTorrent( tor ) );
tr_session * session = tor->session;
tr_sessionLock( session );
tor->isDeleting = 1;
tor->magnetVerify = false;
data = tr_new0( struct remove_data, 1 );
data->tor = tor;
data->deleteFlag = deleteFlag;
data->deleteFunc = deleteFunc;
tr_runInEventThread( tor->session, removeTorrent, data );
tr_sessionUnlock( session );
}
/**
@@ -274,6 +274,7 @@ struct tr_torrent
float desiredRatio;
tr_ratiolimit ratioLimitMode;
uint8_t streamingMode;
uint8_t cheatMode;
float cheatRand;
@@ -1277,6 +1277,21 @@ void tr_torrentSetCheatMode( tr_torrent * tor, tr_cheatMode_t mode );
tr_cheatMode_t tr_torrentGetCheatMode( const tr_torrent * tor );
typedef int8_t tr_streamingMode_t;
enum
{
TR_STREAMING_OFF = 0,
TR_STREAMING_WEAK = 1,
TR_STREAMING_PRIORITY = 2,
TR_STREAMING_WEIGHTED = 3,
TR_STREAMING_FORCED = 4,
TR_STREAMING_COUNT
};
void tr_torrentSetStreamingMode( tr_torrent * tor, tr_streamingMode_t mode );
tr_streamingMode_t tr_torrentGetStreamingMode( const tr_torrent * tor );
/****
***** Ratio Limits