1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-03-04 02:28:03 +00:00

make list less error-prone by changing the API s.t. we're guaranteed to update the list's pointer correctly.

This commit is contained in:
Charles Kerr 2007-08-14 14:18:54 +00:00
parent 8f8100e4d8
commit 26dabf816e
6 changed files with 80 additions and 39 deletions

View file

@ -29,44 +29,70 @@ node_free( tr_list_t* node )
***/ ***/
void void
tr_list_free( tr_list_t* list ) tr_list_free( tr_list_t** list )
{ {
while( list ) while( *list )
{ {
tr_list_t * node = list; tr_list_t * node = *list;
list = list->next; *list = (*list)->next;
node_free( node ); node_free( node );
} }
} }
tr_list_t* void
tr_list_prepend( tr_list_t * list, void * data ) tr_list_prepend( tr_list_t ** list, void * data )
{ {
tr_list_t * node = node_alloc (); tr_list_t * node = node_alloc ();
node->data = data; node->data = data;
node->next = list; node->next = *list;
if( list ) if( *list )
list->prev = node; (*list)->prev = node;
return node; *list = node;
} }
tr_list_t* void
tr_list_append( tr_list_t * list, void * data ) tr_list_append( tr_list_t ** list, void * data )
{ {
tr_list_t * node = node_alloc( ); tr_list_t * node = node_alloc( );
node->data = data; node->data = data;
if( !list ) if( !*list )
return node; *list = node;
else { else {
tr_list_t * l = list; tr_list_t * l = *list;
while( l->next ) while( l->next )
l = l->next; l = l->next;
l->next = node; l->next = node;
node->prev = l; 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_t*
tr_list_find_data ( tr_list_t * list, const void * data ) 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; return NULL;
} }
tr_list_t* void
tr_list_remove_data ( tr_list_t * list, const void * data ) 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 * prev = node ? node->prev : NULL;
tr_list_t * next = node ? node->next : NULL; tr_list_t * next = node ? node->next : NULL;
if( prev ) prev->next = next; if( prev ) prev->next = next;
if( next ) next->prev = prev; if( next ) next->prev = prev;
if( list == node ) list = next; if( *list == node ) *list = next;
node_free( node ); node_free( node );
return list;
} }
tr_list_t* 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 ) for( ; list; list=list->next )
if( !func( list->data, b ) ) if( !func( list->data, b ) )

View file

@ -19,17 +19,33 @@ typedef struct tr_list_s
} }
tr_list_t; 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); 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 *); 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 */ #endif /* TR_LIST_H */

View file

@ -313,7 +313,7 @@ void tr_peerDestroy( tr_peer_t * peer )
tr_bitfieldFree( peer->banfield ); tr_bitfieldFree( peer->banfield );
tr_bitfieldFree( peer->reqfield ); tr_bitfieldFree( peer->reqfield );
tr_list_foreach( peer->outRequests, tr_free ); tr_list_foreach( peer->outRequests, tr_free );
tr_list_free( peer->outRequests ); tr_list_free( &peer->outRequests );
tr_free( peer->inRequests ); tr_free( peer->inRequests );
tr_free( peer->buf ); tr_free( peer->buf );
tr_free( peer->outMessages ); tr_free( peer->outMessages );

View file

@ -123,7 +123,7 @@ blockPending( tr_torrent_t * tor,
r = (tr_request_t*) peer->outRequests->data; r = (tr_request_t*) peer->outRequests->data;
assert( r != NULL ); 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 */ 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 */ /* Drop older requests from the last time it was unchoked, if any */
tr_list_foreach( peer->outRequests, tr_free ); tr_list_foreach( peer->outRequests, tr_free );
tr_list_free( peer->outRequests ); tr_list_free( &peer->outRequests );
peer->outRequests = NULL; peer->outRequests = NULL;
} }

View file

@ -244,7 +244,7 @@ static int parseRequest( tr_torrent_t * tor, tr_peer_t * peer,
r->index = index; r->index = index;
r->begin = begin; r->begin = begin;
r->length = length; r->length = length;
peer->outRequests = tr_list_append( peer->outRequests, r ); tr_list_append( &peer->outRequests, r );
return TR_OK; return TR_OK;
} }
@ -418,9 +418,9 @@ static int parseCancel( tr_torrent_t * tor, tr_peer_t * peer,
req.index = index; req.index = index;
req.begin = begin; req.begin = begin;
req.length = length; 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; 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 ); tr_free( r );
} }

View file

@ -270,7 +270,7 @@ tr_loadTorrents ( tr_handle_t * h,
tr_buildPath( path, sizeof(path), torrentDir, d->d_name, NULL ); tr_buildPath( path, sizeof(path), torrentDir, d->d_name, NULL );
tor = tr_torrentInit( h, path, destination, flags, NULL ); tor = tr_torrentInit( h, path, destination, flags, NULL );
if( tor != NULL ) { if( tor != NULL ) {
list = tr_list_append( list, tor ); tr_list_append( &list, tor );
//fprintf (stderr, "#%d - %s\n", n, tor->info.name ); //fprintf (stderr, "#%d - %s\n", n, tor->info.name );
n++; n++;
} }
@ -284,7 +284,7 @@ tr_loadTorrents ( tr_handle_t * h,
torrents[i++] = (tr_torrent_t*) l->data; torrents[i++] = (tr_torrent_t*) l->data;
assert( i==n ); assert( i==n );
tr_list_free( list ); tr_list_free( &list );
*setmeCount = n; *setmeCount = n;
tr_inf( "Loaded %d torrents from disk", *setmeCount ); tr_inf( "Loaded %d torrents from disk", *setmeCount );