fix race condition in the torrent rechecker.

This commit is contained in:
Charles Kerr 2007-09-24 17:47:15 +00:00
parent 6897fe4327
commit dd6f87a5eb
2 changed files with 43 additions and 31 deletions

View File

@ -302,6 +302,14 @@ static tr_thread * recheckThread = NULL;
static int stopCurrent = FALSE;
static tr_lock* getRecheckLock( void )
{
static tr_lock * lock = NULL;
if( lock == NULL )
lock = tr_lockNew( );
return lock;
}
static void
recheckThreadFunc( void * unused UNUSED )
{
@ -309,8 +317,11 @@ recheckThreadFunc( void * unused UNUSED )
{
int i;
tr_torrent * tor;
struct recheck_node * node;
struct recheck_node * node = (struct recheck_node*) recheckList ? recheckList->data : NULL;
tr_lockLock( getRecheckLock( ) );
fprintf( stderr, "popping `node' from recheckList\n" );
node = (struct recheck_node*) recheckList ? recheckList->data : NULL;
if( node == NULL )
break;
@ -318,6 +329,7 @@ recheckThreadFunc( void * unused UNUSED )
tor = currentNode.torrent;
tr_list_remove_data( &recheckList, node );
tr_free( node );
tr_lockUnlock( getRecheckLock( ) );
if( tor->uncheckedPieces == NULL ) {
fireCheckDone( tor, currentNode.recheck_done_cb, currentNode.status_when_done );
@ -352,7 +364,9 @@ recheckThreadFunc( void * unused UNUSED )
fireCheckDone( tor, currentNode.recheck_done_cb, currentNode.status_when_done );
}
fprintf( stderr, "setting old recheck thread to NULL because the queue is empty\n" );
recheckThread = NULL;
tr_lockUnlock( getRecheckLock( ) );
}
void
@ -360,24 +374,21 @@ tr_ioRecheckAdd( tr_torrent * tor,
tr_recheck_done_cb recheck_done_cb,
run_status_t status_when_done )
{
if( tor->uncheckedPieces == NULL )
{
fireCheckDone( tor, recheck_done_cb, status_when_done );
}
else
{
struct recheck_node * node;
node = tr_new( struct recheck_node, 1 );
node->torrent = tor;
node->recheck_done_cb = recheck_done_cb;
node->status_when_done = status_when_done;
tr_list_append( &recheckList, node );
struct recheck_node * node;
node = tr_new( struct recheck_node, 1 );
node->torrent = tor;
node->recheck_done_cb = recheck_done_cb;
node->status_when_done = status_when_done;
fprintf( stderr, "appending `node' to recheckList\n" );
tor->runStatus = TR_RUN_CHECKING_WAIT;
if( recheckThread == NULL )
recheckThread = tr_threadNew( recheckThreadFunc, NULL, "recheckThreadFunc" );
tr_lockLock( getRecheckLock( ) );
tr_list_append( &recheckList, node );
tor->runStatus = TR_RUN_CHECKING_WAIT;
if( recheckThread == NULL ) {
fprintf( stderr, "creating new recheck thread\n" );
recheckThread = tr_threadNew( recheckThreadFunc, NULL, "recheckThreadFunc" );
}
tr_lockUnlock( getRecheckLock( ) );
}
static int

View File

@ -1239,7 +1239,6 @@ sendPex( tr_peermsgs * msgs )
tr_bencFree( &val );
tr_free( diffs.added );
tr_free( diffs.dropped );
tr_free( diffs.elements );
tr_free( newPex );
msgs->clientSentPexAt = time( NULL );
@ -1308,21 +1307,23 @@ tr_peerMsgsNew( struct tr_torrent * torrent, struct tr_peer * info )
}
void
tr_peerMsgsFree( tr_peermsgs* p )
tr_peerMsgsFree( tr_peermsgs* msgs )
{
if( p != NULL )
if( msgs != NULL )
{
tr_timerFree( &p->pulseTimer );
tr_timerFree( &p->pexTimer );
tr_publisherFree( &p->publisher );
tr_list_foreach( p->clientAskedFor, tr_free );
tr_list_free( &p->clientAskedFor );
tr_list_foreach( p->peerAskedFor, tr_free );
tr_list_free( &p->peerAskedFor );
evbuffer_free( p->outMessages );
evbuffer_free( p->outBlock );
evbuffer_free( p->inBlock );
tr_free( p );
tr_timerFree( &msgs->pulseTimer );
tr_timerFree( &msgs->pexTimer );
tr_publisherFree( &msgs->publisher );
tr_list_foreach( msgs->clientAskedFor, tr_free );
tr_list_free( &msgs->clientAskedFor );
tr_list_foreach( msgs->peerAskedFor, tr_free );
tr_list_free( &msgs->peerAskedFor );
evbuffer_free( msgs->outMessages );
evbuffer_free( msgs->outBlock );
evbuffer_free( msgs->inBlock );
tr_free( msgs->pex );
msgs->pexCount = 0;
tr_free( msgs );
}
}