more work on the speed limits as hammered out w/BentMyWookie

This commit is contained in:
Charles Kerr 2007-07-20 03:24:04 +00:00
parent 42e150a786
commit 4ef1592e6b
8 changed files with 127 additions and 160 deletions

View File

@ -1433,20 +1433,26 @@ refresh_files (GtkWidget * top)
***** OPTIONS
****/
static void
speed_toggled_cb( GtkToggleButton * tb, gpointer gtor, int up_or_down )
{
tr_torrent_t * tor = tr_torrent_handle (gtor);
gboolean b = gtk_toggle_button_get_active(tb);
tr_torrentSetSpeedMode( tor, up_or_down, b ? TR_SPEEDLIMIT_SINGLE
: TR_SPEEDLIMIT_GLOBAL );
}
static void
ul_speed_toggled_cb (GtkToggleButton *tb, gpointer gtor)
{
tr_torrent_set_upload_cap_enabled (TR_TORRENT(gtor),
gtk_toggle_button_get_active(tb));
speed_toggled_cb( tb, gtor, TR_UP );
}
static void
dl_speed_toggled_cb (GtkToggleButton *tb, gpointer gtor)
{
tr_torrent_set_download_cap_enabled (TR_TORRENT(gtor),
gtk_toggle_button_get_active(tb));
speed_toggled_cb( tb, gtor, TR_DOWN );
}
static void
seeding_cap_toggled_cb (GtkToggleButton *tb, gpointer gtor)
{
@ -1461,18 +1467,22 @@ sensitize_from_check_cb (GtkToggleButton *toggle, gpointer w)
gtk_toggle_button_get_active(toggle));
}
static void
setSpeedLimit( GtkSpinButton* spin, gpointer gtor, int up_or_down )
{
tr_torrent_t * tor = tr_torrent_handle (gtor);
int KiB_sec = gtk_spin_button_get_value_as_int (spin);
tr_torrentSetSpeedLimit( tor, up_or_down, KiB_sec );
}
static void
ul_speed_spun_cb (GtkSpinButton *spin, gpointer gtor)
{
tr_torrent_set_upload_cap_speed (TR_TORRENT(gtor),
gtk_spin_button_get_value_as_int (spin));
setSpeedLimit( spin, gtor, TR_UP );
}
static void
dl_speed_spun_cb (GtkSpinButton *spin, gpointer gtor)
{
tr_torrent_set_download_cap_speed (TR_TORRENT(gtor),
gtk_spin_button_get_value_as_int (spin));
setSpeedLimit( spin, gtor, TR_DOWN );
}
static void
@ -1485,9 +1495,11 @@ seeding_ratio_spun_cb (GtkSpinButton *spin, gpointer gtor)
GtkWidget*
options_page_new ( TrTorrent * gtor )
{
int row;
int i, row;
gboolean b;
GtkAdjustment *a;
GtkWidget *t, *w, *tb;
tr_torrent_t * tor = tr_torrent_handle (gtor);
row = 0;
t = hig_workarea_create ();
@ -1495,9 +1507,12 @@ options_page_new ( TrTorrent * gtor )
hig_workarea_add_section_spacer (t, row, 2);
tb = gtk_check_button_new_with_mnemonic (_("Limit _Download Speed (KiB/s):"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(tb), gtor->dl_cap_enabled);
b = tr_torrentGetSpeedMode(tor,TR_DOWN) == TR_SPEEDLIMIT_SINGLE;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(tb), b );
g_signal_connect (tb, "toggled", G_CALLBACK(dl_speed_toggled_cb), gtor);
a = (GtkAdjustment*) gtk_adjustment_new (gtor->dl_cap, 0.0, G_MAXDOUBLE, 1, 1, 1);
i = tr_torrentGetSpeedLimit( tor, TR_DOWN );
a = (GtkAdjustment*) gtk_adjustment_new (i, 0.0, G_MAXDOUBLE, 1, 1, 1);
w = gtk_spin_button_new (a, 1, 0);
g_signal_connect (w, "value-changed", G_CALLBACK(dl_speed_spun_cb), gtor);
g_signal_connect (tb, "toggled", G_CALLBACK(sensitize_from_check_cb), w);
@ -1505,9 +1520,12 @@ options_page_new ( TrTorrent * gtor )
hig_workarea_add_row_w (t, &row, tb, w, NULL);
tb = gtk_check_button_new_with_mnemonic (_("Limit _Upload Speed (KiB/s):"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(tb), gtor->ul_cap_enabled);
b = tr_torrentGetSpeedMode(tor,TR_UP) == TR_SPEEDLIMIT_SINGLE;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(tb), b );
g_signal_connect (tb, "toggled", G_CALLBACK(ul_speed_toggled_cb), gtor);
a = (GtkAdjustment*) gtk_adjustment_new (gtor->ul_cap, 0.0, G_MAXDOUBLE, 1, 1, 1);
i = tr_torrentGetSpeedLimit( tor, TR_UP );
a = (GtkAdjustment*) gtk_adjustment_new (i, 0.0, G_MAXDOUBLE, 1, 1, 1);
w = gtk_spin_button_new (a, 1, 0);
g_signal_connect (w, "value-changed", G_CALLBACK(ul_speed_spun_cb), gtor);
g_signal_connect (tb, "toggled", G_CALLBACK(sensitize_from_check_cb), w);

View File

@ -137,10 +137,6 @@ tr_torrent_init(GTypeInstance *instance, gpointer g_class SHUTUP) {
self->delfile = NULL;
self->severed = FALSE;
self->disposed = FALSE;
self->ul_cap_enabled = FALSE;
self->ul_cap = 0;
self->dl_cap_enabled = FALSE;
self->dl_cap = 0;
}
static void
@ -155,12 +151,6 @@ tr_torrent_set_property(GObject *object, guint property_id,
case TR_TORRENT_HANDLE:
g_assert(NULL == self->handle);
self->handle = g_value_get_pointer(value);
if( self->handle ) {
self->ul_cap = tr_torrentGetMaxSpeedUL ( self->handle );
self->ul_cap_enabled = tr_torrentIsMaxSpeedEnabledUL ( self->handle );
self->dl_cap = tr_torrentGetMaxSpeedDL ( self->handle );
self->dl_cap_enabled = tr_torrentIsMaxSpeedEnabledDL ( self->handle );
}
if(NULL != self->handle && NULL != self->dir)
tr_torrent_set_folder(self);
break;
@ -490,7 +480,7 @@ tr_torrent_get_state( TrTorrent * tor, benc_val_t * state )
tr_bencInitInt( tr_bencDictAdd( state, "paused" ),
(refreshStat(tor)->status & TR_STATUS_INACTIVE) ? 1 : 0);
tr_bencInitInt( tr_bencDictAdd( state, "seeding-cap-ratio" ),
(int)(tor->dl_cap * 100.0)); /* two decimal places */
(int)(tor->seeding_cap * 100.0)); /* two decimal places */
tr_bencInitInt( tr_bencDictAdd( state, "seeding-cap-enabled" ),
tor->seeding_cap_enabled ? 1 : 0);
@ -526,44 +516,6 @@ tr_torrent_set_folder(TrTorrent *tor) {
}
}
static void
refresh_upload_cap ( TrTorrent *gtor )
{
tr_torrentEnableMaxSpeedUL( gtor->handle, gtor->ul_cap_enabled );
tr_torrentSetMaxSpeedUL( gtor->handle, gtor->ul_cap );
}
void
tr_torrent_set_upload_cap_speed ( TrTorrent *gtor, int KiB_sec )
{
gtor->ul_cap = KiB_sec;
refresh_upload_cap ( gtor );
}
void
tr_torrent_set_upload_cap_enabled ( TrTorrent *gtor, gboolean b )
{
gtor->ul_cap_enabled = b;
refresh_upload_cap ( gtor );
}
static void
refresh_download_cap ( TrTorrent *gtor )
{
tr_torrentEnableMaxSpeedDL( gtor->handle, gtor->dl_cap_enabled );
tr_torrentSetMaxSpeedDL( gtor->handle, gtor->dl_cap );
}
void
tr_torrent_set_download_cap_speed ( TrTorrent *gtor, int KiB_sec )
{
gtor->dl_cap = KiB_sec;
refresh_download_cap( gtor );
}
void
tr_torrent_set_download_cap_enabled ( TrTorrent *gtor, gboolean b )
{
gtor->dl_cap_enabled = b;
refresh_download_cap( gtor );
}
void
tr_torrent_check_seeding_cap ( TrTorrent *gtor)
{

View File

@ -62,11 +62,7 @@ struct _TrTorrent {
/* FIXME: hm, are these heavyweight enough to deserve their own properties? */
gboolean severed;
gboolean disposed;
gboolean ul_cap_enabled;
gboolean dl_cap_enabled;
gboolean seeding_cap_enabled;
gint ul_cap; /* KiB/sec */
gint dl_cap; /* KiB/sec */
gdouble seeding_cap; /* ratio to stop seeding at */
};
@ -95,16 +91,6 @@ tr_torrent_stop( TrTorrent * tor );
char*
tr_torrent_status_str ( TrTorrent * tor );
void
tr_torrent_set_upload_cap_speed ( TrTorrent*, int KiB_sec );
void
tr_torrent_set_upload_cap_enabled ( TrTorrent*, gboolean );
void
tr_torrent_set_download_cap_speed ( TrTorrent*, int KiB_sec );
void
tr_torrent_set_download_cap_enabled ( TrTorrent*, gboolean );
void
tr_torrent_check_seeding_cap ( TrTorrent* );
void

View File

@ -75,10 +75,10 @@ enum
FR_ID_PRIORITY = 6,
/* transfer speeds
* uint32_t: the dl speed rate to use when the flag is true
* char: t,f for whether or not dl speed is capped
* uint32_t: the ul speed rate to use when the flag is true
* char: t,f for whether or not ul speed is capped
* uint32_t: dl speed rate to use when the mode is single
* uint32_t: dl's tr_speedlimit_t
* uint32_t: ul speed rate to use when the mode is single
* uint32_t: ul's tr_speedlimit_t
*/
FR_ID_SPEED = 7
};
@ -227,21 +227,19 @@ void fastResumeSave( const tr_torrent_t * tor )
/* Write the torrent ul/dl speed caps */
if( TRUE )
{
const int len = ( sizeof(uint32_t) + sizeof(char) ) * 2;
const int len = sizeof(uint32_t) * 4;
char * buf = tr_new0( char, len );
char * walk = buf;
char enabled;
uint32_t i;
i = (uint32_t) tr_torrentGetMaxSpeedDL( tor );
i = (uint32_t) tr_torrentGetSpeedLimit( tor, TR_DOWN );
memcpy( walk, &i, 4 ); walk += 4;
enabled = tr_torrentIsMaxSpeedEnabledDL( tor ) ? 't' : 'f';
*walk++ = enabled;
i = (uint32_t) tr_torrentGetMaxSpeedUL( tor );
i = (uint32_t) tr_torrentGetSpeedMode( tor, TR_DOWN );
memcpy( walk, &i, 4 ); walk += 4;
i = (uint32_t) tr_torrentGetSpeedLimit( tor, TR_UP );
memcpy( walk, &i, 4 ); walk += 4;
i = (uint32_t) tr_torrentGetSpeedMode( tor, TR_UP );
memcpy( walk, &i, 4 ); walk += 4;
enabled = tr_torrentIsMaxSpeedEnabledUL( tor ) ? 't' : 'f';
*walk++ = enabled;
assert( walk - buf == len );
fastResumeWriteData( FR_ID_SPEED, buf, 1, walk-buf, file );
@ -274,10 +272,10 @@ void fastResumeSave( const tr_torrent_t * tor )
static int
loadSpeeds( tr_torrent_t * tor, FILE * file )
{
const size_t len = 2 * (sizeof(uint32_t) + sizeof(char));
const size_t len = sizeof(uint32_t) * 4;
char * buf = tr_new0( char, len );
char * walk = buf;
uint32_t rate;
uint32_t i;
char enabled;
if( len != fread( buf, 1, len, file ) ) {
@ -286,15 +284,14 @@ loadSpeeds( tr_torrent_t * tor, FILE * file )
return TR_ERROR_IO_OTHER;
}
memcpy( &rate, walk, 4 ); walk += 4;
memcpy( &enabled, walk, 1 ); walk += 1;
tr_torrentSetMaxSpeedDL( tor, rate );
tr_torrentEnableMaxSpeedDL( tor, enabled=='t' );
memcpy( &rate, walk, 4 ); walk += 4;
memcpy( &enabled, walk, 1 ); walk += 1;
tr_torrentSetMaxSpeedUL( tor, rate );
tr_torrentEnableMaxSpeedUL( tor, enabled=='t' );
memcpy( &i, walk, 4 ); walk += 4;
tr_torrentSetSpeedLimit( tor, TR_DOWN, i );
memcpy( &i, walk, 4 ); walk += 4;
tr_torrentSetSpeedMode( tor, TR_DOWN, (tr_speedlimit_t)i );
memcpy( &i, walk, 4 ); walk += 4;
tr_torrentSetSpeedLimit( tor, TR_UP, i );
memcpy( &i, walk, 4 ); walk += 4;
tr_torrentSetSpeedMode( tor, TR_UP, (tr_speedlimit_t)i );
tr_free( buf );
return TR_OK;
@ -517,7 +514,7 @@ fastResumeLoad( tr_torrent_t * tor,
case FR_ID_SPEED:
/* read speed data */
if( len == (uint32_t)(2*sizeof(uint32_t)+2) )
if( len == (uint32_t)(sizeof(uint32_t)*4) )
{
ret = loadSpeeds( tor, file );

View File

@ -161,8 +161,8 @@ struct tr_torrent_s
tr_handle_t * handle;
tr_info_t info;
int customUploadLimit;
int customDownloadLimit;
tr_speedlimit_t uploadLimitMode;
tr_speedlimit_t downloadLimitMode;
tr_ratecontrol_t * upload;
tr_ratecontrol_t * download;
tr_ratecontrol_t * swarmspeed;

View File

@ -377,12 +377,14 @@ int tr_peerRead( tr_peer_t * peer )
{
if( tor )
{
if( tor->customDownloadLimit
? !tr_rcCanTransfer( tor->download )
: !tr_rcCanTransfer( tor->handle->download ) )
{
break;
int canDL;
switch( tor->downloadLimitMode ) {
case TR_SPEEDLIMIT_GLOBAL: canDL = tr_rcCanTransfer( tor->handle->download ); break;
case TR_SPEEDLIMIT_SINGLE: canDL = tr_rcCanTransfer( tor->download ); break;
default: canDL = TRUE; /* unlimited */
}
if( !canDL )
break;
}
if( peer->size < 1 )
@ -580,12 +582,16 @@ writeBegin:
/* Send pieces if we can */
while( ( p = blockPending( tor, peer, &size ) ) )
{
if( SWIFT_ENABLED && !isSeeding && (peer->credit<0) )
break;
int canUL;
if( tor->customUploadLimit
? !tr_rcCanTransfer( tor->upload )
: !tr_rcCanTransfer( tor->handle->upload ) )
if( SWIFT_ENABLED && !isSeeding && (peer->credit<0) )
canUL = FALSE;
else switch( tor->uploadLimitMode ) {
case TR_SPEEDLIMIT_GLOBAL: canUL = tr_rcCanTransfer( tor->handle->upload ); break;
case TR_SPEEDLIMIT_SINGLE: canUL = tr_rcCanTransfer( tor->upload ); break;
default: canUL = TRUE; /* unlimited */
}
if( !canUL )
break;
ret = tr_netSend( peer->socket, p, size );
@ -855,8 +861,7 @@ tr_peerSentBlockToUs ( tr_peer_t * peer, int byteCount )
tor->downloadedCur += byteCount;
tr_rcTransferred( peer->download, byteCount );
tr_rcTransferred( tor->download, byteCount );
if ( !tor->customUploadLimit )
tr_rcTransferred( tor->handle->download, byteCount );
tr_rcTransferred( tor->handle->download, byteCount );
peer->credit += (int)(byteCount * SWIFT_REPAYMENT_RATIO);
}
@ -872,8 +877,7 @@ tr_peerGotBlockFromUs ( tr_peer_t * peer, int byteCount )
tor->uploadedCur += byteCount;
tr_rcTransferred( peer->upload, byteCount );
tr_rcTransferred( tor->upload, byteCount );
if ( !tor->customDownloadLimit )
tr_rcTransferred( tor->handle->upload, byteCount );
tr_rcTransferred( tor->handle->upload, byteCount );
peer->credit -= byteCount;
}

View File

@ -67,44 +67,39 @@ tr_torrentWriterUnlock( tr_torrent_t * tor )
***/
void
tr_torrentEnableMaxSpeedUL( tr_torrent_t * tor, char doThrottle )
tr_torrentSetSpeedMode( tr_torrent_t * tor,
int up_or_down,
tr_speedlimit_t mode )
{
tor->customUploadLimit = doThrottle;
tr_speedlimit_t * limit = up_or_down==TR_UP
? &tor->uploadLimitMode
: &tor->downloadLimitMode;
*limit = mode;
}
tr_speedlimit_t
tr_torrentGetSpeedMode( const tr_torrent_t * tor,
int up_or_down)
{
return up_or_down==TR_UP ? tor->uploadLimitMode
: tor->downloadLimitMode;
}
void
tr_torrentEnableMaxSpeedDL( tr_torrent_t * tor, char doThrottle )
tr_torrentSetSpeedLimit( tr_torrent_t * tor,
int up_or_down,
int single_KiB_sec )
{
tor->customDownloadLimit = doThrottle;
}
void
tr_torrentSetMaxSpeedUL( tr_torrent_t * tor, int KiB_sec )
{
tr_rcSetLimit( tor->upload, KiB_sec );
}
void
tr_torrentSetMaxSpeedDL( tr_torrent_t * tor, int KiB_sec )
{
tr_rcSetLimit( tor->download, KiB_sec );
tr_ratecontrol_t * rc = up_or_down==TR_UP ? tor->upload : tor->download;
tr_rcSetLimit( rc, single_KiB_sec );
}
int
tr_torrentIsMaxSpeedEnabledUL( const tr_torrent_t * tor )
tr_torrentGetSpeedLimit( const tr_torrent_t * tor,
int up_or_down )
{
return tor->customUploadLimit;
}
int
tr_torrentIsMaxSpeedEnabledDL( const tr_torrent_t * tor )
{
return tor->customDownloadLimit;
}
int
tr_torrentGetMaxSpeedUL( const tr_torrent_t * tor )
{
return tr_rcGetLimit( tor->upload );
}
int
tr_torrentGetMaxSpeedDL( const tr_torrent_t * tor )
{
return tr_rcGetLimit( tor->download );
tr_ratecontrol_t * rc = up_or_down==TR_UP ? tor->upload : tor->download;
return tr_rcGetLimit( rc );
}
/***

View File

@ -196,19 +196,34 @@ typedef struct tr_torrent_s tr_torrent_t;
typedef void (*tr_callback_t) ( tr_torrent_t *, void * );
void tr_torrentIterate( tr_handle_t *, tr_callback_t, void * );
/**
*** Speed Throttle
/***********************************************************************
*** Speed Limits
**/
void tr_torrentEnableMaxSpeedUL ( tr_torrent_t * , char doThrottle );
void tr_torrentEnableMaxSpeedDL ( tr_torrent_t * , char doThrottle );
void tr_torrentSetMaxSpeedUL ( tr_torrent_t * , int KiB_sec );
void tr_torrentSetMaxSpeedDL ( tr_torrent_t * , int KiB_sec );
typedef enum
{
TR_SPEEDLIMIT_GLOBAL, /* indirectly follow the global pool's limit */
TR_SPEEDLIMIT_SINGLE, /* directly follow tr_torrentSetMaxSpeed() */
TR_SPEEDLIMIT_UNLIMITED /* no limits at all */
}
tr_speedlimit_t;
int tr_torrentIsMaxSpeedEnabledUL ( const tr_torrent_t * );
int tr_torrentIsMaxSpeedEnabledDL ( const tr_torrent_t * );
int tr_torrentGetMaxSpeedUL ( const tr_torrent_t * );
int tr_torrentGetMaxSpeedDL ( const tr_torrent_t * );
enum { TR_UP, TR_DOWN };
void tr_torrentSetSpeedMode( tr_torrent_t * tor,
int up_or_down,
tr_speedlimit_t mode );
tr_speedlimit_t tr_torrentGetSpeedMode( const tr_torrent_t * tor,
int up_or_down);
void tr_torrentSetSpeedLimit( tr_torrent_t * tor,
int up_or_down,
int single_KiB_sec );
int tr_torrentGetSpeedLimit( const tr_torrent_t * tor,
int up_or_down );
/***********************************************************************
* Torrent Priorities