(trunk libT) avoid some unnecessary memory fragmentation... for composited objects that have a tr_ptrArray, contain the tr_ptrArray directly rather than a pointer to one allocated elsewhere on the heap.
This commit is contained in:
parent
db381a5e40
commit
427f639664
|
@ -98,8 +98,8 @@ struct tr_bandwidth
|
|||
struct tr_bandwidth * parent;
|
||||
int magicNumber;
|
||||
tr_session * session;
|
||||
tr_ptrArray * children; /* struct tr_bandwidth */
|
||||
tr_ptrArray * peers; /* tr_peerIo */
|
||||
tr_ptrArray children; /* struct tr_bandwidth */
|
||||
tr_ptrArray peers; /* tr_peerIo */
|
||||
};
|
||||
|
||||
/***
|
||||
|
@ -130,8 +130,8 @@ tr_bandwidthNew( tr_session * session, tr_bandwidth * parent )
|
|||
{
|
||||
tr_bandwidth * b = tr_new0( tr_bandwidth, 1 );
|
||||
b->session = session;
|
||||
b->children = tr_ptrArrayNew( );
|
||||
b->peers = tr_ptrArrayNew( );
|
||||
b->children = TR_PTR_ARRAY_INIT;
|
||||
b->peers = TR_PTR_ARRAY_INIT;
|
||||
b->magicNumber = MAGIC_NUMBER;
|
||||
b->band[TR_UP].honorParentLimits = TRUE;
|
||||
b->band[TR_DOWN].honorParentLimits = TRUE;
|
||||
|
@ -145,8 +145,8 @@ tr_bandwidthFree( tr_bandwidth * b )
|
|||
assert( tr_isBandwidth( b ) );
|
||||
|
||||
tr_bandwidthSetParent( b, NULL );
|
||||
tr_ptrArrayFree( b->peers, NULL );
|
||||
tr_ptrArrayFree( b->children, NULL );
|
||||
tr_ptrArrayDestruct( &b->peers, NULL );
|
||||
tr_ptrArrayDestruct( &b->children, NULL );
|
||||
b->magicNumber = 0xDEAD;
|
||||
tr_free( b );
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ tr_bandwidthSetParent( tr_bandwidth * b,
|
|||
{
|
||||
assert( tr_isBandwidth( b->parent ) );
|
||||
|
||||
tr_ptrArrayRemoveSorted( b->parent->children, b, comparePointers );
|
||||
tr_ptrArrayRemoveSorted( &b->parent->children, b, comparePointers );
|
||||
b->parent = NULL;
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,7 @@ tr_bandwidthSetParent( tr_bandwidth * b,
|
|||
assert( tr_isBandwidth( parent ) );
|
||||
assert( parent->parent != b );
|
||||
|
||||
tr_ptrArrayInsertSorted( parent->children, b, comparePointers );
|
||||
tr_ptrArrayInsertSorted( &parent->children, b, comparePointers );
|
||||
b->parent = parent;
|
||||
}
|
||||
}
|
||||
|
@ -269,9 +269,9 @@ allocateBandwidth( tr_bandwidth * b,
|
|||
/* traverse & repeat for the subtree */
|
||||
{
|
||||
int i;
|
||||
const int n = tr_ptrArraySize( b->peers );
|
||||
const int n = TR_PTR_ARRAY_LENGTH( &b->peers );
|
||||
for( i=0; i<n; ++i )
|
||||
tr_ptrArrayAppend( peer_pool, tr_ptrArrayNth( b->peers, i ) );
|
||||
tr_ptrArrayAppend( peer_pool, tr_ptrArrayNth( &b->peers, i ) );
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DIRECTION
|
||||
|
@ -281,8 +281,9 @@ fprintf( stderr, "bandwidth %p has %d peers\n", b, n );
|
|||
|
||||
/* all children should reallocate too */
|
||||
if( 1 ) {
|
||||
int i, n=0;
|
||||
struct tr_bandwidth ** children = (struct tr_bandwidth**) tr_ptrArrayPeek( b->children, &n );
|
||||
int i;
|
||||
struct tr_bandwidth ** children = (struct tr_bandwidth**) TR_PTR_ARRAY_DATA( &b->children );
|
||||
const int n = TR_PTR_ARRAY_LENGTH( &b->children );
|
||||
for( i=0; i<n; ++i )
|
||||
allocateBandwidth( children[i], dir, period_msec, peer_pool );
|
||||
}
|
||||
|
@ -294,7 +295,7 @@ tr_bandwidthAllocate( tr_bandwidth * b,
|
|||
int period_msec )
|
||||
{
|
||||
int i, n, peerCount;
|
||||
tr_ptrArray * tmp;
|
||||
tr_ptrArray tmp = TR_PTR_ARRAY_INIT;
|
||||
struct tr_peerIo ** peers;
|
||||
const uint64_t now = tr_date( );
|
||||
const uint64_t cutoff = now + 100; /* 1/10th of a second */
|
||||
|
@ -303,9 +304,8 @@ tr_bandwidthAllocate( tr_bandwidth * b,
|
|||
/* allocateBandwidth() is a helper function with two purposes:
|
||||
* 1. allocate bandwidth to b and its subtree
|
||||
* 2. accumulate an array of all the peerIos from b and its subtree. */
|
||||
tmp = tr_ptrArrayNew( );
|
||||
allocateBandwidth( b, dir, period_msec, tmp );
|
||||
peers = (struct tr_peerIo**) tr_ptrArrayPeek( tmp, &peerCount );
|
||||
allocateBandwidth( b, dir, period_msec, &tmp );
|
||||
peers = (struct tr_peerIo**) tr_ptrArrayPeek( &tmp, &peerCount );
|
||||
|
||||
/* Stop all peers from listening for the socket to be ready for IO.
|
||||
* See "Second phase of IO" lower in this function for more info. */
|
||||
|
@ -347,7 +347,7 @@ tr_bandwidthAllocate( tr_bandwidth * b,
|
|||
tr_peerIoSetEnabled( peers[i], dir, TRUE );
|
||||
|
||||
/* cleanup */
|
||||
tr_ptrArrayFree( tmp, NULL );
|
||||
tr_ptrArrayDestruct( &tmp, NULL );
|
||||
}
|
||||
|
||||
/***
|
||||
|
@ -361,7 +361,7 @@ tr_bandwidthAddPeer( tr_bandwidth * b,
|
|||
assert( tr_isBandwidth( b ) );
|
||||
assert( tr_isPeerIo( peerIo ) );
|
||||
|
||||
tr_ptrArrayInsertSorted( b->peers, peerIo, comparePointers );
|
||||
tr_ptrArrayInsertSorted( &b->peers, peerIo, comparePointers );
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -371,7 +371,7 @@ tr_bandwidthRemovePeer( tr_bandwidth * b,
|
|||
assert( tr_isBandwidth( b ) );
|
||||
assert( tr_isPeerIo( peerIo ) );
|
||||
|
||||
tr_ptrArrayRemoveSorted( b->peers, peerIo, comparePointers );
|
||||
tr_ptrArrayRemoveSorted( &b->peers, peerIo, comparePointers );
|
||||
}
|
||||
|
||||
/***
|
||||
|
|
|
@ -326,14 +326,14 @@ tr_bencParse( const void * buf,
|
|||
const uint8_t ** setme_end )
|
||||
{
|
||||
int err;
|
||||
tr_ptrArray * parentStack = tr_ptrArrayNew( );
|
||||
tr_ptrArray parentStack = TR_PTR_ARRAY_INIT;
|
||||
|
||||
top->type = 0; /* set to `uninitialized' */
|
||||
err = tr_bencParseImpl( buf, end, top, parentStack, setme_end );
|
||||
err = tr_bencParseImpl( buf, end, top, &parentStack, setme_end );
|
||||
if( err )
|
||||
tr_bencFree( top );
|
||||
|
||||
tr_ptrArrayFree( parentStack, NULL );
|
||||
tr_ptrArrayDestruct( &parentStack, NULL );
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -932,13 +932,13 @@ bencWalk( const tr_benc * top,
|
|||
struct WalkFuncs * walkFuncs,
|
||||
void * user_data )
|
||||
{
|
||||
tr_ptrArray * stack = tr_ptrArrayNew( );
|
||||
tr_ptrArray stack = TR_PTR_ARRAY_INIT;
|
||||
|
||||
tr_ptrArrayAppend( stack, nodeNew( top ) );
|
||||
tr_ptrArrayAppend( &stack, nodeNew( top ) );
|
||||
|
||||
while( !tr_ptrArrayEmpty( stack ) )
|
||||
while( !tr_ptrArrayEmpty( &stack ) )
|
||||
{
|
||||
struct SaveNode * node = tr_ptrArrayBack( stack );
|
||||
struct SaveNode * node = tr_ptrArrayBack( &stack );
|
||||
const tr_benc * val;
|
||||
|
||||
if( !node->valIsVisited )
|
||||
|
@ -955,7 +955,7 @@ bencWalk( const tr_benc * top,
|
|||
{
|
||||
if( isContainer( node->val ) )
|
||||
walkFuncs->containerEndFunc( node->val, user_data );
|
||||
tr_ptrArrayPop( stack );
|
||||
tr_ptrArrayPop( &stack );
|
||||
tr_free( node->children );
|
||||
tr_free( node );
|
||||
continue;
|
||||
|
@ -973,14 +973,14 @@ bencWalk( const tr_benc * top,
|
|||
|
||||
case TYPE_LIST:
|
||||
if( val != node->val )
|
||||
tr_ptrArrayAppend( stack, nodeNew( val ) );
|
||||
tr_ptrArrayAppend( &stack, nodeNew( val ) );
|
||||
else
|
||||
walkFuncs->listBeginFunc( val, user_data );
|
||||
break;
|
||||
|
||||
case TYPE_DICT:
|
||||
if( val != node->val )
|
||||
tr_ptrArrayAppend( stack, nodeNew( val ) );
|
||||
tr_ptrArrayAppend( &stack, nodeNew( val ) );
|
||||
else
|
||||
walkFuncs->dictBeginFunc( val, user_data );
|
||||
break;
|
||||
|
@ -992,7 +992,7 @@ bencWalk( const tr_benc * top,
|
|||
}
|
||||
}
|
||||
|
||||
tr_ptrArrayFree( stack, NULL );
|
||||
tr_ptrArrayDestruct( &stack, NULL );
|
||||
}
|
||||
|
||||
/****
|
||||
|
@ -1087,7 +1087,7 @@ tr_bencFree( tr_benc * val )
|
|||
{
|
||||
if( val && val->type )
|
||||
{
|
||||
tr_ptrArray * freeme = tr_ptrArrayNew( );
|
||||
tr_ptrArray a = TR_PTR_ARRAY_INIT;
|
||||
struct WalkFuncs walkFuncs;
|
||||
|
||||
walkFuncs.intFunc = freeDummyFunc;
|
||||
|
@ -1095,9 +1095,9 @@ tr_bencFree( tr_benc * val )
|
|||
walkFuncs.dictBeginFunc = freeContainerBeginFunc;
|
||||
walkFuncs.listBeginFunc = freeContainerBeginFunc;
|
||||
walkFuncs.containerEndFunc = freeDummyFunc;
|
||||
bencWalk( val, &walkFuncs, freeme );
|
||||
bencWalk( val, &walkFuncs, &a );
|
||||
|
||||
tr_ptrArrayFree( freeme, tr_free );
|
||||
tr_ptrArrayDestruct( &a, tr_free );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
struct json_benc_data
|
||||
{
|
||||
tr_benc * top;
|
||||
tr_ptrArray * stack;
|
||||
tr_ptrArray stack;
|
||||
char * key;
|
||||
};
|
||||
|
||||
|
@ -39,10 +39,10 @@ getNode( struct json_benc_data * data )
|
|||
tr_benc * parent;
|
||||
tr_benc * node = NULL;
|
||||
|
||||
if( tr_ptrArrayEmpty( data->stack ) )
|
||||
if( tr_ptrArrayEmpty( &data->stack ) )
|
||||
parent = NULL;
|
||||
else
|
||||
parent = tr_ptrArrayBack( data->stack );
|
||||
parent = tr_ptrArrayBack( &data->stack );
|
||||
|
||||
if( !parent )
|
||||
node = data->top;
|
||||
|
@ -71,21 +71,21 @@ callback( void * vdata,
|
|||
case JSON_T_ARRAY_BEGIN:
|
||||
node = getNode( data );
|
||||
tr_bencInitList( node, 0 );
|
||||
tr_ptrArrayAppend( data->stack, node );
|
||||
tr_ptrArrayAppend( &data->stack, node );
|
||||
break;
|
||||
|
||||
case JSON_T_ARRAY_END:
|
||||
tr_ptrArrayPop( data->stack );
|
||||
tr_ptrArrayPop( &data->stack );
|
||||
break;
|
||||
|
||||
case JSON_T_OBJECT_BEGIN:
|
||||
node = getNode( data );
|
||||
tr_bencInitDict( node, 0 );
|
||||
tr_ptrArrayAppend( data->stack, node );
|
||||
tr_ptrArrayAppend( &data->stack, node );
|
||||
break;
|
||||
|
||||
case JSON_T_OBJECT_END:
|
||||
tr_ptrArrayPop( data->stack );
|
||||
tr_ptrArrayPop( &data->stack );
|
||||
break;
|
||||
|
||||
case JSON_T_FLOAT:
|
||||
|
@ -148,7 +148,7 @@ tr_jsonParse( const void * vbuf,
|
|||
|
||||
data.key = NULL;
|
||||
data.top = setme_benc;
|
||||
data.stack = tr_ptrArrayNew( );
|
||||
data.stack = TR_PTR_ARRAY_INIT;
|
||||
|
||||
checker = new_JSON_parser( &config );
|
||||
while( ( buf != bufend ) && JSON_parser_char( checker, *buf ) )
|
||||
|
@ -161,7 +161,7 @@ tr_jsonParse( const void * vbuf,
|
|||
*setme_end = (const uint8_t*) buf;
|
||||
|
||||
delete_JSON_parser( checker );
|
||||
tr_ptrArrayFree( data.stack, NULL );
|
||||
tr_ptrArrayDestruct( &data.stack, NULL );
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -125,10 +125,10 @@ typedef struct
|
|||
|
||||
uint8_t hash[SHA_DIGEST_LENGTH];
|
||||
int * pendingRequestCount;
|
||||
tr_ptrArray * outgoingHandshakes; /* tr_handshake */
|
||||
tr_ptrArray * pool; /* struct peer_atom */
|
||||
tr_ptrArray * peers; /* tr_peer */
|
||||
tr_ptrArray * webseeds; /* tr_webseed */
|
||||
tr_ptrArray outgoingHandshakes; /* tr_handshake */
|
||||
tr_ptrArray pool; /* struct peer_atom */
|
||||
tr_ptrArray peers; /* tr_peer */
|
||||
tr_ptrArray webseeds; /* tr_webseed */
|
||||
tr_timer * reconnectTimer;
|
||||
tr_timer * rechokeTimer;
|
||||
tr_timer * refillTimer;
|
||||
|
@ -142,9 +142,9 @@ Torrent;
|
|||
struct tr_peerMgr
|
||||
{
|
||||
tr_session * session;
|
||||
tr_ptrArray * torrents; /* Torrent */
|
||||
tr_ptrArray * incomingHandshakes; /* tr_handshake */
|
||||
tr_ptrArray * finishedHandshakes; /* tr_handshake */
|
||||
tr_ptrArray torrents; /* Torrent */
|
||||
tr_ptrArray incomingHandshakes; /* tr_handshake */
|
||||
tr_ptrArray finishedHandshakes; /* tr_handshake */
|
||||
tr_timer * bandwidthTimer;
|
||||
};
|
||||
|
||||
|
@ -263,7 +263,7 @@ static Torrent*
|
|||
getExistingTorrent( tr_peerMgr * manager,
|
||||
const uint8_t * hash )
|
||||
{
|
||||
return (Torrent*) tr_ptrArrayFindSorted( manager->torrents,
|
||||
return (Torrent*) tr_ptrArrayFindSorted( &manager->torrents,
|
||||
hash,
|
||||
torrentCompareToHash );
|
||||
}
|
||||
|
@ -292,15 +292,16 @@ getExistingPeer( Torrent * torrent,
|
|||
assert( torrentIsLocked( torrent ) );
|
||||
assert( addr );
|
||||
|
||||
return tr_ptrArrayFindSorted( torrent->peers, addr, peerCompareToAddr );
|
||||
return tr_ptrArrayFindSorted( &torrent->peers, addr, peerCompareToAddr );
|
||||
}
|
||||
|
||||
static struct peer_atom*
|
||||
getExistingAtom( const Torrent * t,
|
||||
const tr_address * addr )
|
||||
{
|
||||
Torrent * tt = (Torrent*)t;
|
||||
assert( torrentIsLocked( t ) );
|
||||
return tr_ptrArrayFindSorted( t->pool, addr, comparePeerAtomToAddress );
|
||||
return tr_ptrArrayFindSorted( &tt->pool, addr, comparePeerAtomToAddress );
|
||||
}
|
||||
|
||||
static tr_bool
|
||||
|
@ -312,8 +313,8 @@ peerIsInUse( const Torrent * ct,
|
|||
assert( torrentIsLocked ( t ) );
|
||||
|
||||
return getExistingPeer( t, addr )
|
||||
|| getExistingHandshake( t->outgoingHandshakes, addr )
|
||||
|| getExistingHandshake( t->manager->incomingHandshakes, addr );
|
||||
|| getExistingHandshake( &t->outgoingHandshakes, addr )
|
||||
|| getExistingHandshake( &t->manager->incomingHandshakes, addr );
|
||||
}
|
||||
|
||||
static tr_peer*
|
||||
|
@ -339,7 +340,7 @@ getPeer( Torrent * torrent,
|
|||
if( peer == NULL )
|
||||
{
|
||||
peer = peerConstructor( torrent->tor, addr );
|
||||
tr_ptrArrayInsertSorted( torrent->peers, peer, peerCompare );
|
||||
tr_ptrArrayInsertSorted( &torrent->peers, peer, peerCompare );
|
||||
}
|
||||
|
||||
return peer;
|
||||
|
@ -380,7 +381,7 @@ removePeer( Torrent * t,
|
|||
assert( atom );
|
||||
atom->time = time( NULL );
|
||||
|
||||
removed = tr_ptrArrayRemoveSorted( t->peers, peer, peerCompare );
|
||||
removed = tr_ptrArrayRemoveSorted( &t->peers, peer, peerCompare );
|
||||
assert( removed == peer );
|
||||
peerDestructor( removed );
|
||||
}
|
||||
|
@ -388,8 +389,8 @@ removePeer( Torrent * t,
|
|||
static void
|
||||
removeAllPeers( Torrent * t )
|
||||
{
|
||||
while( !tr_ptrArrayEmpty( t->peers ) )
|
||||
removePeer( t, tr_ptrArrayNth( t->peers, 0 ) );
|
||||
while( !tr_ptrArrayEmpty( &t->peers ) )
|
||||
removePeer( t, tr_ptrArrayNth( &t->peers, 0 ) );
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -400,10 +401,9 @@ torrentDestructor( void * vt )
|
|||
|
||||
assert( t );
|
||||
assert( !t->isRunning );
|
||||
assert( t->peers );
|
||||
assert( torrentIsLocked( t ) );
|
||||
assert( tr_ptrArrayEmpty( t->outgoingHandshakes ) );
|
||||
assert( tr_ptrArrayEmpty( t->peers ) );
|
||||
assert( tr_ptrArrayEmpty( &t->outgoingHandshakes ) );
|
||||
assert( tr_ptrArrayEmpty( &t->peers ) );
|
||||
|
||||
memcpy( hash, t->hash, SHA_DIGEST_LENGTH );
|
||||
|
||||
|
@ -411,10 +411,10 @@ torrentDestructor( void * vt )
|
|||
tr_timerFree( &t->rechokeTimer );
|
||||
tr_timerFree( &t->refillTimer );
|
||||
|
||||
tr_ptrArrayFree( t->webseeds, (PtrArrayForeachFunc)tr_webseedFree );
|
||||
tr_ptrArrayFree( t->pool, (PtrArrayForeachFunc)tr_free );
|
||||
tr_ptrArrayFree( t->outgoingHandshakes, NULL );
|
||||
tr_ptrArrayFree( t->peers, NULL );
|
||||
tr_ptrArrayDestruct( &t->webseeds, (PtrArrayForeachFunc)tr_webseedFree );
|
||||
tr_ptrArrayDestruct( &t->pool, (PtrArrayForeachFunc)tr_free );
|
||||
tr_ptrArrayDestruct( &t->outgoingHandshakes, NULL );
|
||||
tr_ptrArrayDestruct( &t->peers, NULL );
|
||||
|
||||
tr_free( t->pendingRequestCount );
|
||||
tr_free( t );
|
||||
|
@ -434,18 +434,17 @@ torrentConstructor( tr_peerMgr * manager,
|
|||
t = tr_new0( Torrent, 1 );
|
||||
t->manager = manager;
|
||||
t->tor = tor;
|
||||
t->pool = tr_ptrArrayNew( );
|
||||
t->peers = tr_ptrArrayNew( );
|
||||
t->webseeds = tr_ptrArrayNew( );
|
||||
t->outgoingHandshakes = tr_ptrArrayNew( );
|
||||
t->pool = TR_PTR_ARRAY_INIT;
|
||||
t->peers = TR_PTR_ARRAY_INIT;
|
||||
t->webseeds = TR_PTR_ARRAY_INIT;
|
||||
t->outgoingHandshakes = TR_PTR_ARRAY_INIT;
|
||||
memcpy( t->hash, tor->info.hash, SHA_DIGEST_LENGTH );
|
||||
|
||||
for( i = 0; i < tor->info.webseedCount; ++i )
|
||||
{
|
||||
tr_webseed * w =
|
||||
tr_webseedNew( tor, tor->info.webseeds[i], peerCallbackFunc,
|
||||
t );
|
||||
tr_ptrArrayAppend( t->webseeds, w );
|
||||
tr_webseedNew( tor, tor->info.webseeds[i], peerCallbackFunc, t );
|
||||
tr_ptrArrayAppend( &t->webseeds, w );
|
||||
}
|
||||
|
||||
return t;
|
||||
|
@ -461,9 +460,9 @@ tr_peerMgrNew( tr_session * session )
|
|||
tr_peerMgr * m = tr_new0( tr_peerMgr, 1 );
|
||||
|
||||
m->session = session;
|
||||
m->torrents = tr_ptrArrayNew( );
|
||||
m->incomingHandshakes = tr_ptrArrayNew( );
|
||||
m->finishedHandshakes = tr_ptrArrayNew( );
|
||||
m->torrents = TR_PTR_ARRAY_INIT;
|
||||
m->incomingHandshakes = TR_PTR_ARRAY_INIT;
|
||||
m->finishedHandshakes = TR_PTR_ARRAY_INIT;
|
||||
m->bandwidthTimer = tr_timerNew( session, bandwidthPulse, m, BANDWIDTH_PERIOD_MSEC );
|
||||
return m;
|
||||
}
|
||||
|
@ -479,18 +478,18 @@ tr_peerMgrFree( tr_peerMgr * manager )
|
|||
|
||||
/* free the handshakes. Abort invokes handshakeDoneCB(), which removes
|
||||
* the item from manager->handshakes, so this is a little roundabout... */
|
||||
while( !tr_ptrArrayEmpty( manager->incomingHandshakes ) )
|
||||
tr_handshakeAbort( tr_ptrArrayNth( manager->incomingHandshakes, 0 ) );
|
||||
while( !tr_ptrArrayEmpty( &manager->incomingHandshakes ) )
|
||||
tr_handshakeAbort( tr_ptrArrayNth( &manager->incomingHandshakes, 0 ) );
|
||||
|
||||
tr_ptrArrayFree( manager->incomingHandshakes, NULL );
|
||||
tr_ptrArrayDestruct( &manager->incomingHandshakes, NULL );
|
||||
|
||||
while(( handshake = tr_ptrArrayPop( manager->finishedHandshakes )))
|
||||
while(( handshake = tr_ptrArrayPop( &manager->finishedHandshakes )))
|
||||
tr_handshakeFree( handshake );
|
||||
|
||||
tr_ptrArrayFree( manager->finishedHandshakes, NULL );
|
||||
tr_ptrArrayDestruct( &manager->finishedHandshakes, NULL );
|
||||
|
||||
/* free the torrents. */
|
||||
tr_ptrArrayFree( manager->torrents, torrentDestructor );
|
||||
tr_ptrArrayDestruct( &manager->torrents, torrentDestructor );
|
||||
|
||||
managerUnlock( manager );
|
||||
tr_free( manager );
|
||||
|
@ -505,7 +504,7 @@ getConnectedPeers( Torrent * t, int * setmeCount )
|
|||
|
||||
assert( torrentIsLocked( t ) );
|
||||
|
||||
peers = (tr_peer **) tr_ptrArrayPeek( t->peers, &peerCount );
|
||||
peers = (tr_peer **) tr_ptrArrayPeek( &t->peers, &peerCount );
|
||||
ret = tr_new( tr_peer *, peerCount );
|
||||
|
||||
for( i = connectionCount = 0; i < peerCount; ++i )
|
||||
|
@ -758,7 +757,7 @@ getPeersUploadingToClient( Torrent * t,
|
|||
int j;
|
||||
int peerCount = 0;
|
||||
int retCount = 0;
|
||||
tr_peer ** peers = (tr_peer **) tr_ptrArrayPeek( t->peers, &peerCount );
|
||||
tr_peer ** peers = (tr_peer **) tr_ptrArrayPeek( &t->peers, &peerCount );
|
||||
tr_peer ** ret = tr_new( tr_peer *, peerCount );
|
||||
|
||||
j = 0; /* this is a temporary test to make sure we walk through all the peers */
|
||||
|
@ -812,8 +811,8 @@ refillPulse( void * vtorrent )
|
|||
|
||||
blockIterator = blockIteratorNew( t );
|
||||
peers = getPeersUploadingToClient( t, &peerCount );
|
||||
webseedCount = tr_ptrArraySize( t->webseeds );
|
||||
webseeds = tr_memdup( tr_ptrArrayBase( t->webseeds ),
|
||||
webseedCount = tr_ptrArraySize( &t->webseeds );
|
||||
webseeds = tr_memdup( tr_ptrArrayBase( &t->webseeds ),
|
||||
webseedCount * sizeof( tr_webseed* ) );
|
||||
|
||||
while( ( webseedCount || peerCount )
|
||||
|
@ -1182,7 +1181,7 @@ ensureAtomExists( Torrent * t,
|
|||
a->flags = flags;
|
||||
a->from = from;
|
||||
tordbg( t, "got a new atom: %s", tr_peerIoAddrStr( &a->addr, a->port ) );
|
||||
tr_ptrArrayInsertSorted( t->pool, a, comparePeerAtoms );
|
||||
tr_ptrArrayInsertSorted( &t->pool, a, comparePeerAtoms );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1195,7 +1194,7 @@ getMaxPeerCount( const tr_torrent * tor )
|
|||
static int
|
||||
getPeerCount( const Torrent * t )
|
||||
{
|
||||
return tr_ptrArraySize( t->peers ) + tr_ptrArraySize( t->outgoingHandshakes );
|
||||
return tr_ptrArraySize( &t->peers ) + tr_ptrArraySize( &t->outgoingHandshakes );
|
||||
}
|
||||
|
||||
/* FIXME: this is kind of a mess. */
|
||||
|
@ -1222,10 +1221,10 @@ myHandshakeDoneCB( tr_handshake * handshake,
|
|||
: NULL;
|
||||
|
||||
if( tr_peerIoIsIncoming ( io ) )
|
||||
ours = tr_ptrArrayRemoveSorted( manager->incomingHandshakes,
|
||||
ours = tr_ptrArrayRemoveSorted( &manager->incomingHandshakes,
|
||||
handshake, handshakeCompare );
|
||||
else if( t )
|
||||
ours = tr_ptrArrayRemoveSorted( t->outgoingHandshakes,
|
||||
ours = tr_ptrArrayRemoveSorted( &t->outgoingHandshakes,
|
||||
handshake, handshakeCompare );
|
||||
else
|
||||
ours = handshake;
|
||||
|
@ -1296,7 +1295,7 @@ myHandshakeDoneCB( tr_handshake * handshake,
|
|||
}
|
||||
|
||||
if( !success )
|
||||
tr_ptrArrayAppend( manager->finishedHandshakes, handshake );
|
||||
tr_ptrArrayAppend( &manager->finishedHandshakes, handshake );
|
||||
|
||||
if( t )
|
||||
torrentUnlock( t );
|
||||
|
@ -1317,7 +1316,7 @@ tr_peerMgrAddIncoming( tr_peerMgr * manager,
|
|||
tr_dbg( "Banned IP address \"%s\" tried to connect to us", tr_ntop_non_ts( addr ) );
|
||||
tr_netClose( socket );
|
||||
}
|
||||
else if( getExistingHandshake( manager->incomingHandshakes, addr ) )
|
||||
else if( getExistingHandshake( &manager->incomingHandshakes, addr ) )
|
||||
{
|
||||
tr_netClose( socket );
|
||||
}
|
||||
|
@ -1333,7 +1332,7 @@ tr_peerMgrAddIncoming( tr_peerMgr * manager,
|
|||
myHandshakeDoneCB,
|
||||
manager );
|
||||
|
||||
tr_ptrArrayInsertSorted( manager->incomingHandshakes, handshake,
|
||||
tr_ptrArrayInsertSorted( &manager->incomingHandshakes, handshake,
|
||||
handshakeCompare );
|
||||
}
|
||||
|
||||
|
@ -1456,7 +1455,7 @@ tr_peerMgrSetBlame( tr_peerMgr * manager,
|
|||
|
||||
assert( torrentIsLocked( t ) );
|
||||
|
||||
peers = (tr_peer **) tr_ptrArrayPeek( t->peers, &peerCount );
|
||||
peers = (tr_peer **) tr_ptrArrayPeek( &t->peers, &peerCount );
|
||||
for( i = 0; i < peerCount; ++i )
|
||||
{
|
||||
tr_peer * peer = peers[i];
|
||||
|
@ -1508,7 +1507,6 @@ tr_peerMgrGetPeers( tr_peerMgr * manager,
|
|||
tr_pex ** setme_pex,
|
||||
uint8_t af)
|
||||
{
|
||||
int peerCount = 0;
|
||||
int peersReturning = 0;
|
||||
const Torrent * t;
|
||||
|
||||
|
@ -1522,7 +1520,8 @@ tr_peerMgrGetPeers( tr_peerMgr * manager,
|
|||
else
|
||||
{
|
||||
int i;
|
||||
const tr_peer ** peers = (const tr_peer **) tr_ptrArrayPeek( t->peers, &peerCount );
|
||||
const tr_peer ** peers = (const tr_peer**) TR_PTR_ARRAY_DATA( &t->peers );
|
||||
const int peerCount = TR_PTR_ARRAY_LENGTH( &t->peers );
|
||||
/* for now, this will waste memory on torrents that have both
|
||||
* ipv6 and ipv4 peers */
|
||||
tr_pex * pex = tr_new( tr_pex, peerCount );
|
||||
|
@ -1591,7 +1590,7 @@ tr_peerMgrStartTorrent( tr_peerMgr * manager,
|
|||
|
||||
rechokePulse( t );
|
||||
|
||||
if( !tr_ptrArrayEmpty( t->webseeds ) )
|
||||
if( !tr_ptrArrayEmpty( &t->webseeds ) )
|
||||
refillSoon( t );
|
||||
}
|
||||
|
||||
|
@ -1608,13 +1607,13 @@ stopTorrent( Torrent * t )
|
|||
tr_timerFree( &t->reconnectTimer );
|
||||
|
||||
/* disconnect the peers. */
|
||||
tr_ptrArrayForeach( t->peers, (PtrArrayForeachFunc)peerDestructor );
|
||||
tr_ptrArrayClear( t->peers );
|
||||
tr_ptrArrayForeach( &t->peers, (PtrArrayForeachFunc)peerDestructor );
|
||||
tr_ptrArrayClear( &t->peers );
|
||||
|
||||
/* disconnect the handshakes. handshakeAbort calls handshakeDoneCB(),
|
||||
* which removes the handshake from t->outgoingHandshakes... */
|
||||
while( !tr_ptrArrayEmpty( t->outgoingHandshakes ) )
|
||||
tr_handshakeAbort( tr_ptrArrayNth( t->outgoingHandshakes, 0 ) );
|
||||
while( !tr_ptrArrayEmpty( &t->outgoingHandshakes ) )
|
||||
tr_handshakeAbort( tr_ptrArrayNth( &t->outgoingHandshakes, 0 ) );
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1640,7 +1639,7 @@ tr_peerMgrAddTorrent( tr_peerMgr * manager,
|
|||
assert( getExistingTorrent( manager, tor->info.hash ) == NULL );
|
||||
|
||||
t = torrentConstructor( manager, tor );
|
||||
tr_ptrArrayInsertSorted( manager->torrents, t, torrentCompare );
|
||||
tr_ptrArrayInsertSorted( &manager->torrents, t, torrentCompare );
|
||||
|
||||
managerUnlock( manager );
|
||||
}
|
||||
|
@ -1656,7 +1655,7 @@ tr_peerMgrRemoveTorrent( tr_peerMgr * manager,
|
|||
t = getExistingTorrent( manager, torrentHash );
|
||||
assert( t );
|
||||
stopTorrent( t );
|
||||
tr_ptrArrayRemoveSorted( manager->torrents, t, torrentCompare );
|
||||
tr_ptrArrayRemoveSorted( &manager->torrents, t, torrentCompare );
|
||||
torrentDestructor( t );
|
||||
|
||||
managerUnlock( manager );
|
||||
|
@ -1682,7 +1681,8 @@ tr_peerMgrTorrentAvailability( const tr_peerMgr * manager,
|
|||
tor = t->tor;
|
||||
interval = tor->info.pieceCount / (float)tabCount;
|
||||
isSeed = tor && ( tr_cpGetStatus ( tor->completion ) == TR_SEED );
|
||||
peers = (const tr_peer **) tr_ptrArrayPeek( t->peers, &peerCount );
|
||||
peers = (const tr_peer **) TR_PTR_ARRAY_DATA( &t->peers );
|
||||
peerCount = TR_PTR_ARRAY_LENGTH( &t->peers );
|
||||
|
||||
memset( tab, 0, tabCount );
|
||||
|
||||
|
@ -1734,7 +1734,7 @@ tr_peerMgrHasConnections( const tr_peerMgr * manager,
|
|||
managerLock( manager );
|
||||
|
||||
t = getExistingTorrent( (tr_peerMgr*)manager, torrentHash );
|
||||
ret = t && ( !tr_ptrArrayEmpty( t->peers ) || !tr_ptrArrayEmpty( t->webseeds ) );
|
||||
ret = t && ( !tr_ptrArrayEmpty( &t->peers ) || !tr_ptrArrayEmpty( &t->webseeds ) );
|
||||
|
||||
managerUnlock( manager );
|
||||
return ret;
|
||||
|
@ -1759,9 +1759,10 @@ tr_peerMgrTorrentStats( const tr_peerMgr * manager,
|
|||
managerLock( manager );
|
||||
|
||||
t = getExistingTorrent( (tr_peerMgr*)manager, torrentHash );
|
||||
peers = (const tr_peer **) tr_ptrArrayPeek( t->peers, &size );
|
||||
peers = (const tr_peer **) TR_PTR_ARRAY_DATA( &t->peers );
|
||||
size = TR_PTR_ARRAY_LENGTH( &t->peers );
|
||||
|
||||
*setmePeersKnown = tr_ptrArraySize( t->pool );
|
||||
*setmePeersKnown = tr_ptrArraySize( &t->pool );
|
||||
*setmePeersConnected = 0;
|
||||
*setmeSeedsConnected = 0;
|
||||
*setmePeersGettingFromUs = 0;
|
||||
|
@ -1793,7 +1794,8 @@ tr_peerMgrTorrentStats( const tr_peerMgr * manager,
|
|||
++*setmeSeedsConnected;
|
||||
}
|
||||
|
||||
webseeds = (const tr_webseed **) tr_ptrArrayPeek( t->webseeds, &size );
|
||||
webseeds = (const tr_webseed**) TR_PTR_ARRAY_DATA( &t->webseeds );
|
||||
size = TR_PTR_ARRAY_LENGTH( &t->webseeds );
|
||||
for( i=0; i<size; ++i )
|
||||
if( tr_webseedIsActive( webseeds[i] ) )
|
||||
++*setmeWebseedsSendingToUs;
|
||||
|
@ -1815,8 +1817,8 @@ tr_peerMgrWebSpeeds( const tr_peerMgr * manager,
|
|||
managerLock( manager );
|
||||
|
||||
t = getExistingTorrent( (tr_peerMgr*)manager, torrentHash );
|
||||
webseeds = (const tr_webseed**) tr_ptrArrayPeek( t->webseeds,
|
||||
&webseedCount );
|
||||
webseeds = (const tr_webseed**) TR_PTR_ARRAY_DATA( &t->webseeds );
|
||||
webseedCount = TR_PTR_ARRAY_LENGTH( &t->webseeds );
|
||||
assert( webseedCount == t->tor->info.webseedCount );
|
||||
ret = tr_new0( float, webseedCount );
|
||||
|
||||
|
@ -2014,7 +2016,7 @@ rechoke( Torrent * t )
|
|||
{
|
||||
int n;
|
||||
struct ChokeData * c;
|
||||
tr_ptrArray * randPool = tr_ptrArrayNew( );
|
||||
tr_ptrArray randPool = TR_PTR_ARRAY_INIT;
|
||||
|
||||
for( ; i<size; ++i )
|
||||
{
|
||||
|
@ -2025,18 +2027,18 @@ rechoke( Torrent * t )
|
|||
if( isNew( peer ) ) x *= 3;
|
||||
if( isSame( peer ) ) x *= 3;
|
||||
for( y=0; y<x; ++y )
|
||||
tr_ptrArrayAppend( randPool, &choke[i] );
|
||||
tr_ptrArrayAppend( &randPool, &choke[i] );
|
||||
}
|
||||
}
|
||||
|
||||
if(( n = tr_ptrArraySize( randPool )))
|
||||
if(( n = tr_ptrArraySize( &randPool )))
|
||||
{
|
||||
c = tr_ptrArrayNth( randPool, tr_cryptoWeakRandInt( n ));
|
||||
c = tr_ptrArrayNth( &randPool, tr_cryptoWeakRandInt( n ));
|
||||
c->doUnchoke = 1;
|
||||
t->optimistic = c->peer;
|
||||
}
|
||||
|
||||
tr_ptrArrayFree( randPool, NULL );
|
||||
tr_ptrArrayDestruct( &randPool, NULL );
|
||||
}
|
||||
|
||||
for( i=0; i<size; ++i )
|
||||
|
@ -2133,7 +2135,7 @@ static tr_peer **
|
|||
getPeersToClose( Torrent * t, int * setmeSize )
|
||||
{
|
||||
int i, peerCount, outsize;
|
||||
tr_peer ** peers = (tr_peer**) tr_ptrArrayPeek( t->peers, &peerCount );
|
||||
tr_peer ** peers = (tr_peer**) tr_ptrArrayPeek( &t->peers, &peerCount );
|
||||
struct tr_peer ** ret = tr_new( tr_peer *, peerCount );
|
||||
|
||||
assert( torrentIsLocked( t ) );
|
||||
|
@ -2219,7 +2221,7 @@ getPeerCandidates( Torrent * t, int * setmeSize )
|
|||
|
||||
assert( torrentIsLocked( t ) );
|
||||
|
||||
atoms = (struct peer_atom**) tr_ptrArrayPeek( t->pool, &atomCount );
|
||||
atoms = (struct peer_atom**) tr_ptrArrayPeek( &t->pool, &atomCount );
|
||||
ret = tr_new( struct peer_atom*, atomCount );
|
||||
for( i = retCount = 0; i < atomCount; ++i )
|
||||
{
|
||||
|
@ -2298,7 +2300,7 @@ reconnectPulse( void * vtorrent )
|
|||
tordbg( t, "reconnect pulse for [%s]: %d bad connections, "
|
||||
"%d connection candidates, %d atoms, max per pulse is %d",
|
||||
t->tor->info.name, nBad, nCandidates,
|
||||
tr_ptrArraySize( t->pool ),
|
||||
tr_ptrArraySize( &t->pool ),
|
||||
(int)MAX_RECONNECTIONS_PER_PULSE );
|
||||
|
||||
/* disconnect some peers.
|
||||
|
@ -2345,7 +2347,7 @@ reconnectPulse( void * vtorrent )
|
|||
|
||||
++newConnectionsThisSecond;
|
||||
|
||||
tr_ptrArrayInsertSorted( t->outgoingHandshakes, handshake,
|
||||
tr_ptrArrayInsertSorted( &t->outgoingHandshakes, handshake,
|
||||
handshakeCompare );
|
||||
}
|
||||
|
||||
|
@ -2370,15 +2372,15 @@ reconnectPulse( void * vtorrent )
|
|||
static void
|
||||
pumpAllPeers( tr_peerMgr * mgr )
|
||||
{
|
||||
const int torrentCount = tr_ptrArraySize( mgr->torrents );
|
||||
const int torrentCount = tr_ptrArraySize( &mgr->torrents );
|
||||
int i, j;
|
||||
|
||||
for( i=0; i<torrentCount; ++i )
|
||||
{
|
||||
Torrent * t = tr_ptrArrayNth( mgr->torrents, i );
|
||||
for( j=0; j<tr_ptrArraySize( t->peers ); ++j )
|
||||
Torrent * t = tr_ptrArrayNth( &mgr->torrents, i );
|
||||
for( j=0; j<tr_ptrArraySize( &t->peers ); ++j )
|
||||
{
|
||||
tr_peer * peer = tr_ptrArrayNth( t->peers, j );
|
||||
tr_peer * peer = tr_ptrArrayNth( &t->peers, j );
|
||||
tr_peerMsgsPulse( peer->msgs );
|
||||
}
|
||||
}
|
||||
|
@ -2399,7 +2401,7 @@ bandwidthPulse( void * vmgr )
|
|||
tr_bandwidthAllocate( mgr->session->bandwidth, TR_DOWN, BANDWIDTH_PERIOD_MSEC );
|
||||
|
||||
/* free all the finished handshakes */
|
||||
while(( handshake = tr_ptrArrayPop( mgr->finishedHandshakes )))
|
||||
while(( handshake = tr_ptrArrayPop( &mgr->finishedHandshakes )))
|
||||
tr_handshakeFree( handshake );
|
||||
|
||||
managerUnlock( mgr );
|
||||
|
|
|
@ -19,23 +19,27 @@
|
|||
|
||||
#define GROW 32
|
||||
|
||||
struct tr_ptrArray
|
||||
const tr_ptrArray TR_PTR_ARRAY_INIT = { NULL, 0, 0 };
|
||||
|
||||
void
|
||||
tr_ptrArrayDestruct( tr_ptrArray * p, PtrArrayForeachFunc func )
|
||||
{
|
||||
void ** items;
|
||||
int n_items;
|
||||
int n_alloc;
|
||||
};
|
||||
assert( p );
|
||||
assert( p->items || !p->n_items );
|
||||
|
||||
if( func )
|
||||
tr_ptrArrayForeach( p, func );
|
||||
|
||||
tr_free( p->items );
|
||||
|
||||
memset( p, ~0, sizeof( tr_ptrArray ) );
|
||||
}
|
||||
|
||||
tr_ptrArray*
|
||||
tr_ptrArrayNew( void )
|
||||
{
|
||||
tr_ptrArray * p;
|
||||
|
||||
p = tr_new( tr_ptrArray, 1 );
|
||||
p->n_items = 0;
|
||||
p->n_alloc = 0;
|
||||
p->items = NULL;
|
||||
|
||||
tr_ptrArray * p = tr_new( tr_ptrArray, 1 );
|
||||
*p = TR_PTR_ARRAY_INIT;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -69,13 +73,7 @@ void
|
|||
tr_ptrArrayFree( tr_ptrArray * t,
|
||||
PtrArrayForeachFunc func )
|
||||
{
|
||||
assert( t );
|
||||
assert( t->items || !t->n_items );
|
||||
|
||||
if( func )
|
||||
tr_ptrArrayForeach( t, func );
|
||||
|
||||
tr_free( t->items );
|
||||
tr_ptrArrayDestruct( t, func );
|
||||
tr_free( t );
|
||||
}
|
||||
|
||||
|
|
|
@ -32,10 +32,23 @@
|
|||
/**
|
||||
* A simple pointer array that resizes itself dynamically.
|
||||
*/
|
||||
typedef struct tr_ptrArray tr_ptrArray;
|
||||
typedef struct tr_ptrArray
|
||||
{
|
||||
void ** items;
|
||||
int n_items;
|
||||
int n_alloc;
|
||||
}
|
||||
tr_ptrArray;
|
||||
|
||||
#define TR_PTR_ARRAY_DATA( A ) ((A)->items)
|
||||
#define TR_PTR_ARRAY_LENGTH( A ) ((A)->n_items)
|
||||
|
||||
typedef void ( *PtrArrayForeachFunc )( void * );
|
||||
|
||||
extern const tr_ptrArray TR_PTR_ARRAY_INIT;
|
||||
|
||||
void tr_ptrArrayDestruct( tr_ptrArray*, PtrArrayForeachFunc func );
|
||||
|
||||
tr_ptrArray * tr_ptrArrayNew( void );
|
||||
|
||||
tr_ptrArray * tr_ptrArrayDup( tr_ptrArray* );
|
||||
|
|
|
@ -1841,6 +1841,7 @@ addDirtyFile( const char * root,
|
|||
{
|
||||
char * tmp;
|
||||
tr_ptrArrayInsertSorted( dirtyFolders, tr_strdup( dir ), vstrcmp );
|
||||
|
||||
tmp = tr_dirname( dir );
|
||||
tr_free( dir );
|
||||
dir = tmp;
|
||||
|
@ -1895,9 +1896,9 @@ deleteLocalData( tr_torrent * tor, tr_fileFunc fileFunc )
|
|||
int i, n;
|
||||
char ** s;
|
||||
tr_file_index_t f;
|
||||
tr_ptrArray * torrentFiles = tr_ptrArrayNew( );
|
||||
tr_ptrArray * folders = tr_ptrArrayNew( );
|
||||
tr_ptrArray * dirtyFolders = tr_ptrArrayNew( ); /* dirty == contains non-torrent files */
|
||||
tr_ptrArray torrentFiles = TR_PTR_ARRAY_INIT;
|
||||
tr_ptrArray folders = TR_PTR_ARRAY_INIT;
|
||||
tr_ptrArray dirtyFolders = TR_PTR_ARRAY_INIT; /* dirty == contains non-torrent files */
|
||||
|
||||
const char * firstFile = tor->info.files[0].name;
|
||||
const char * cpch = strchr( firstFile, TR_PATH_DELIMITER );
|
||||
|
@ -1905,10 +1906,10 @@ deleteLocalData( tr_torrent * tor, tr_fileFunc fileFunc )
|
|||
char * root = tr_buildPath( tor->downloadDir, tmp, NULL );
|
||||
|
||||
for( f=0; f<tor->info.fileCount; ++f )
|
||||
tr_ptrArrayInsertSorted( torrentFiles, tor->info.files[f].name, vstrcmp );
|
||||
tr_ptrArrayInsertSorted( &torrentFiles, tor->info.files[f].name, vstrcmp );
|
||||
|
||||
/* build the set of folders and dirtyFolders */
|
||||
walkLocalData( tor, root, root, NULL, torrentFiles, folders, dirtyFolders );
|
||||
walkLocalData( tor, root, root, NULL, &torrentFiles, &folders, &dirtyFolders );
|
||||
|
||||
/* close all the files because we're about to delete them */
|
||||
for( f=0; f<tor->info.fileCount; ++f ) {
|
||||
|
@ -1918,12 +1919,12 @@ deleteLocalData( tr_torrent * tor, tr_fileFunc fileFunc )
|
|||
}
|
||||
|
||||
/* try to remove entire folders first, so that the recycle bin will be tidy */
|
||||
s = (char**) tr_ptrArrayPeek( folders, &n );
|
||||
s = (char**) tr_ptrArrayPeek( &folders, &n );
|
||||
for( i=0; i<n; ++i )
|
||||
if( tr_ptrArrayFindSorted( dirtyFolders, s[i], vstrcmp ) == NULL )
|
||||
if( tr_ptrArrayFindSorted( &dirtyFolders, s[i], vstrcmp ) == NULL )
|
||||
fileFunc( s[i] );
|
||||
|
||||
/* now blow away any remaining torrent files, such torrent files in dirty folders */
|
||||
/* now blow away any remaining torrent files, such as torrent files in dirty folders */
|
||||
for( f=0; f<tor->info.fileCount; ++f ) {
|
||||
char * path = tr_buildPath( tor->downloadDir, tor->info.files[f].name, NULL );
|
||||
fileFunc( path );
|
||||
|
@ -1934,21 +1935,21 @@ deleteLocalData( tr_torrent * tor, tr_fileFunc fileFunc )
|
|||
* Work from deepest to shallowest s.t. lower folders
|
||||
* won't prevent the upper folders from being deleted */
|
||||
{
|
||||
tr_ptrArray * cleanFolders = tr_ptrArrayNew( );
|
||||
s = (char**) tr_ptrArrayPeek( folders, &n );
|
||||
tr_ptrArray cleanFolders = TR_PTR_ARRAY_INIT;
|
||||
s = (char**) tr_ptrArrayPeek( &folders, &n );
|
||||
for( i=0; i<n; ++i )
|
||||
if( tr_ptrArrayFindSorted( dirtyFolders, s[i], vstrcmp ) == NULL )
|
||||
tr_ptrArrayInsertSorted( cleanFolders, s[i], compareLongestFirst );
|
||||
s = (char**) tr_ptrArrayPeek( cleanFolders, &n );
|
||||
if( tr_ptrArrayFindSorted( &dirtyFolders, s[i], vstrcmp ) == NULL )
|
||||
tr_ptrArrayInsertSorted( &cleanFolders, s[i], compareLongestFirst );
|
||||
s = (char**) tr_ptrArrayPeek( &cleanFolders, &n );
|
||||
for( i=0; i<n; ++i )
|
||||
fileFunc( s[i] );
|
||||
tr_ptrArrayFree( cleanFolders, NULL );
|
||||
tr_ptrArrayDestruct( &cleanFolders, NULL );
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
tr_ptrArrayFree( dirtyFolders, tr_free );
|
||||
tr_ptrArrayFree( folders, tr_free );
|
||||
tr_ptrArrayFree( torrentFiles, NULL );
|
||||
tr_ptrArrayDestruct( &dirtyFolders, tr_free );
|
||||
tr_ptrArrayDestruct( &folders, tr_free );
|
||||
tr_ptrArrayDestruct( &torrentFiles, NULL );
|
||||
tr_free( root );
|
||||
tr_free( tmp );
|
||||
}
|
||||
|
@ -1962,7 +1963,9 @@ tr_torrentDeleteLocalData( tr_torrent * tor, tr_fileFunc fileFunc )
|
|||
if( tor->info.fileCount > 1 )
|
||||
deleteLocalData( tor, fileFunc );
|
||||
else {
|
||||
/* torrent only has one file */
|
||||
char * path = tr_buildPath( tor->downloadDir, tor->info.files[0].name, NULL );
|
||||
tr_fdFileClose( path );
|
||||
fileFunc( path );
|
||||
tr_free( path );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue