From ddcfa59c967c6fef53448f527dbe438328e9c4b7 Mon Sep 17 00:00:00 2001 From: Eric Petit Date: Mon, 29 Jan 2007 08:24:09 +0000 Subject: [PATCH] Always take the global lock when accessing the torrent list (fixes a race condition crash) --- libtransmission/ratecontrol.c | 4 ++++ libtransmission/torrent.c | 5 ++++- libtransmission/transmission.c | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libtransmission/ratecontrol.c b/libtransmission/ratecontrol.c index 7e8eb4a86..9e45f5022 100644 --- a/libtransmission/ratecontrol.c +++ b/libtransmission/ratecontrol.c @@ -23,6 +23,7 @@ *****************************************************************************/ #include "transmission.h" +#include "shared.h" /* Maximum number of packets we keep track of. Since most packets are * 1 KB, it means we remember the last 2 MB transferred */ @@ -93,6 +94,7 @@ int tr_rcCanGlobalTransfer( tr_handle_t * h, int isUpload ) return limit < 0; } + tr_sharedLock( h->shared ); for( tor = h->torrentList; tor; tor = tor->next ) { if( tor->customSpeedLimit ) @@ -107,9 +109,11 @@ int tr_rcCanGlobalTransfer( tr_handle_t * h, int isUpload ) if( rate >= (float)limit ) { + tr_sharedUnlock( h->shared ); return 0; } } + tr_sharedUnlock( h->shared ); return 1; } diff --git a/libtransmission/torrent.c b/libtransmission/torrent.c index 336e293a9..5e006fa92 100644 --- a/libtransmission/torrent.c +++ b/libtransmission/torrent.c @@ -97,6 +97,8 @@ static tr_torrent_t * torrentRealInit( tr_handle_t * h, tr_torrent_t * tor, inf = &tor->info; inf->flags = flags; + tr_sharedLock( h->shared ); + /* Make sure this torrent is not already open */ for( tor_tmp = h->torrentList; tor_tmp; tor_tmp = tor_tmp->next ) { @@ -106,6 +108,7 @@ static tr_torrent_t * torrentRealInit( tr_handle_t * h, tr_torrent_t * tor, *error = TR_EDUPLICATE; tr_metainfoFree( &tor->info ); free( tor ); + tr_sharedUnlock( h->shared ); return NULL; } } @@ -136,7 +139,6 @@ static tr_torrent_t * torrentRealInit( tr_handle_t * h, tr_torrent_t * tor, tor->swarmspeed = tr_rcInit(); /* We have a new torrent */ - tr_sharedLock( h->shared ); tor->publicPort = tr_sharedGetPublicPort( h->shared ); tor->prev = NULL; tor->next = h->torrentList; @@ -146,6 +148,7 @@ static tr_torrent_t * torrentRealInit( tr_handle_t * h, tr_torrent_t * tor, } h->torrentList = tor; (h->torrentCount)++; + tr_sharedUnlock( h->shared ); if( !h->isPortSet ) diff --git a/libtransmission/transmission.c b/libtransmission/transmission.c index 69f3a24a6..6ef08c1f0 100644 --- a/libtransmission/transmission.c +++ b/libtransmission/transmission.c @@ -108,6 +108,7 @@ void tr_torrentRates( tr_handle_t * h, float * dl, float * ul ) *dl = 0.0; *ul = 0.0; + tr_sharedLock( h->shared ); for( tor = h->torrentList; tor; tor = tor->next ) { tr_lockLock( &tor->lock ); @@ -116,6 +117,7 @@ void tr_torrentRates( tr_handle_t * h, float * dl, float * ul ) *ul += tr_rcRate( tor->upload ); tr_lockUnlock( &tor->lock ); } + tr_sharedUnlock( h->shared ); } int tr_torrentCount( tr_handle_t * h )