diff --git a/libtransmission/list.c b/libtransmission/list.c index 1510216b3..8b4bee3f9 100644 --- a/libtransmission/list.c +++ b/libtransmission/list.c @@ -29,44 +29,70 @@ node_free( tr_list_t* node ) ***/ void -tr_list_free( tr_list_t* list ) +tr_list_free( tr_list_t** list ) { - while( list ) + while( *list ) { - tr_list_t * node = list; - list = list->next; + tr_list_t * node = *list; + *list = (*list)->next; node_free( node ); } } -tr_list_t* -tr_list_prepend( tr_list_t * list, void * data ) +void +tr_list_prepend( tr_list_t ** list, void * data ) { tr_list_t * node = node_alloc (); node->data = data; - node->next = list; - if( list ) - list->prev = node; - return node; + node->next = *list; + if( *list ) + (*list)->prev = node; + *list = node; } -tr_list_t* -tr_list_append( tr_list_t * list, void * data ) +void +tr_list_append( tr_list_t ** list, void * data ) { tr_list_t * node = node_alloc( ); node->data = data; - if( !list ) - return node; + if( !*list ) + *list = node; else { - tr_list_t * l = list; + tr_list_t * l = *list; while( l->next ) l = l->next; l->next = node; node->prev = l; - return list; } } +void +tr_list_insert_sorted( tr_list_t ** list, + void * data, + int compare(const void*,const void*) ) +{ + /* find l, the node that we'll insert this data before */ + tr_list_t * l; + for( l=*list; l!=NULL; l=l->next ) { + const int c = (compare)( data, l->data ); + if( c <= 0 ) + break; + } + + if( l == NULL) + tr_list_append( list, data ); + else if( l == *list ) + tr_list_prepend( list, data ); + else { + tr_list_t * node = node_alloc( ); + node->data = data; + if( l->prev ) { node->prev = l->prev; node->prev->next = node; } + node->next = l; + l->prev = node; + } +} + + tr_list_t* tr_list_find_data ( tr_list_t * list, const void * data ) { @@ -77,21 +103,20 @@ tr_list_find_data ( tr_list_t * list, const void * data ) return NULL; } -tr_list_t* -tr_list_remove_data ( tr_list_t * list, const void * data ) +void +tr_list_remove_data ( tr_list_t ** list, const void * data ) { - tr_list_t * node = tr_list_find_data( list, data ); + tr_list_t * node = tr_list_find_data( *list, data ); tr_list_t * prev = node ? node->prev : NULL; tr_list_t * next = node ? node->next : NULL; if( prev ) prev->next = next; if( next ) next->prev = prev; - if( list == node ) list = next; + if( *list == node ) *list = next; node_free( node ); - return list; } tr_list_t* -tr_list_find ( tr_list_t * list , TrListCompareFunc func, const void * b ) +tr_list_find ( tr_list_t * list , const void * b, TrListCompareFunc func ) { for( ; list; list=list->next ) if( !func( list->data, b ) ) diff --git a/libtransmission/list.h b/libtransmission/list.h index 48ba66752..ef3c20f55 100644 --- a/libtransmission/list.h +++ b/libtransmission/list.h @@ -19,17 +19,33 @@ typedef struct tr_list_s } tr_list_t; -void tr_list_free ( tr_list_t* ); -tr_list_t* tr_list_append ( tr_list_t*, void * data ); -tr_list_t* tr_list_prepend ( tr_list_t*, void * data ); -tr_list_t* tr_list_remove_data ( tr_list_t*, const void * data ); - typedef int (*TrListCompareFunc)(const void * a, const void * b); -tr_list_t* tr_list_find ( tr_list_t*, TrListCompareFunc func, const void * b ); -tr_list_t* tr_list_find_data ( tr_list_t*, const void * data ); - typedef void (*TrListForeachFunc)(void *); -void tr_list_foreach ( tr_list_t*, TrListForeachFunc func ); + +void tr_list_free ( tr_list_t ** list ); + +void tr_list_append ( tr_list_t ** list, + void * data ); + +void tr_list_prepend ( tr_list_t ** list, + void * data ); + +void tr_list_remove_data ( tr_list_t ** list, + const void * data ); + +void tr_list_insert_sorted ( tr_list_t ** list, + void * data, + TrListCompareFunc compare_func ); + +tr_list_t* tr_list_find ( tr_list_t * list, + const void * b, + TrListCompareFunc compare_func ); + +tr_list_t* tr_list_find_data ( tr_list_t * list, + const void * data ); + +void tr_list_foreach ( tr_list_t * list, + TrListForeachFunc foreach_func ); #endif /* TR_LIST_H */ diff --git a/libtransmission/peer.c b/libtransmission/peer.c index fc488a140..e14831215 100644 --- a/libtransmission/peer.c +++ b/libtransmission/peer.c @@ -313,7 +313,7 @@ void tr_peerDestroy( tr_peer_t * peer ) tr_bitfieldFree( peer->banfield ); tr_bitfieldFree( peer->reqfield ); tr_list_foreach( peer->outRequests, tr_free ); - tr_list_free( peer->outRequests ); + tr_list_free( &peer->outRequests ); tr_free( peer->inRequests ); tr_free( peer->buf ); tr_free( peer->outMessages ); diff --git a/libtransmission/peermessages.h b/libtransmission/peermessages.h index 2c49aed28..8f37bb3c4 100644 --- a/libtransmission/peermessages.h +++ b/libtransmission/peermessages.h @@ -123,7 +123,7 @@ blockPending( tr_torrent_t * tor, r = (tr_request_t*) peer->outRequests->data; assert( r != NULL ); - peer->outRequests = tr_list_remove_data( peer->outRequests, r ); + tr_list_remove_data( &peer->outRequests, r ); if( !tr_cpPieceIsComplete( tor->completion, r->index ) ) /* sanity clause */ { @@ -226,7 +226,7 @@ static void sendChoke( tr_peer_t * peer, int yes ) { /* Drop older requests from the last time it was unchoked, if any */ tr_list_foreach( peer->outRequests, tr_free ); - tr_list_free( peer->outRequests ); + tr_list_free( &peer->outRequests ); peer->outRequests = NULL; } diff --git a/libtransmission/peerparse.h b/libtransmission/peerparse.h index 81b92ab6c..18d7ccf42 100644 --- a/libtransmission/peerparse.h +++ b/libtransmission/peerparse.h @@ -244,7 +244,7 @@ static int parseRequest( tr_torrent_t * tor, tr_peer_t * peer, r->index = index; r->begin = begin; r->length = length; - peer->outRequests = tr_list_append( peer->outRequests, r ); + tr_list_append( &peer->outRequests, r ); return TR_OK; } @@ -418,9 +418,9 @@ static int parseCancel( tr_torrent_t * tor, tr_peer_t * peer, req.index = index; req.begin = begin; req.length = length; - while(( l = tr_list_find( peer->outRequests, reqCompare, &req ) )) { + while(( l = tr_list_find( peer->outRequests, &req, reqCompare ) )) { tr_request_t * r = (tr_request_t *) l->data; - peer->outRequests = tr_list_remove_data( peer->outRequests, r ); + tr_list_remove_data( &peer->outRequests, r ); tr_free( r ); } diff --git a/libtransmission/transmission.c b/libtransmission/transmission.c index 3c2bca09d..cdcf5605b 100644 --- a/libtransmission/transmission.c +++ b/libtransmission/transmission.c @@ -270,7 +270,7 @@ tr_loadTorrents ( tr_handle_t * h, tr_buildPath( path, sizeof(path), torrentDir, d->d_name, NULL ); tor = tr_torrentInit( h, path, destination, flags, NULL ); if( tor != NULL ) { - list = tr_list_append( list, tor ); + tr_list_append( &list, tor ); //fprintf (stderr, "#%d - %s\n", n, tor->info.name ); n++; } @@ -284,7 +284,7 @@ tr_loadTorrents ( tr_handle_t * h, torrents[i++] = (tr_torrent_t*) l->data; assert( i==n ); - tr_list_free( list ); + tr_list_free( &list ); *setmeCount = n; tr_inf( "Loaded %d torrents from disk", *setmeCount );