1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-27 10:07:40 +00:00

#1126: crash on quit

This commit is contained in:
Charles Kerr 2008-08-01 13:46:03 +00:00
parent 61258969c2
commit 28de948233

View file

@ -489,35 +489,40 @@ compareTorrentByCur( const void * va, const void * vb )
} }
static void static void
tr_closeAllConnections( void * vh ) tr_closeAllConnections( void * vsession )
{ {
tr_handle * h = vh; tr_handle * session = vsession;
tr_torrent * tor; tr_torrent * tor;
int i, n; int i, n;
tr_torrent ** torrents; tr_torrent ** torrents;
tr_sharedShuttingDown( h->shared ); tr_statsClose( session );
tr_rpcClose( &h->rpcServer ); tr_sharedShuttingDown( session->shared );
tr_rpcClose( &session->rpcServer );
/* close the torrents. get the most active ones first so that /* close the torrents. get the most active ones first so that
* if we can't get them all closed in a reasonable amount of time, * if we can't get them all closed in a reasonable amount of time,
* at least we get the most important ones first. */ * at least we get the most important ones first. */
tor = NULL; tor = NULL;
n = h->torrentCount; n = session->torrentCount;
torrents = tr_new( tr_torrent*, h->torrentCount ); torrents = tr_new( tr_torrent*, session->torrentCount );
for( i=0; i<n; ++i ) for( i=0; i<n; ++i )
torrents[i] = tor = tr_torrentNext( h, tor ); torrents[i] = tor = tr_torrentNext( session, tor );
qsort( torrents, n, sizeof(tr_torrent*), compareTorrentByCur ); qsort( torrents, n, sizeof(tr_torrent*), compareTorrentByCur );
for( i=0; i<n; ++i ) for( i=0; i<n; ++i )
tr_torrentFree( torrents[i] ); tr_torrentFree( torrents[i] );
tr_free( torrents ); tr_free( torrents );
tr_peerMgrFree( h->peerMgr ); tr_peerMgrFree( session->peerMgr );
tr_rcClose( h->upload ); tr_rcClose( session->upload );
tr_rcClose( h->download ); tr_rcClose( session->download );
tr_trackerSessionClose( session );
tr_list_free( &session->blocklists, (TrListForeachFunc)_tr_blocklistFree );
tr_webClose( &session->web );
h->isClosed = TRUE; session->isClosed = TRUE;
} }
static int static int
@ -528,42 +533,56 @@ deadlineReached( const uint64_t deadline )
#define SHUTDOWN_MAX_SECONDS 30 #define SHUTDOWN_MAX_SECONDS 30
#define dbgmsg(fmt...) tr_deepLog( __FILE__, __LINE__, NULL, ##fmt )
void void
tr_sessionClose( tr_handle * h ) tr_sessionClose( tr_handle * session )
{ {
int i; int i;
const int maxwait_msec = SHUTDOWN_MAX_SECONDS * 1000; const int maxwait_msec = SHUTDOWN_MAX_SECONDS * 1000;
const uint64_t deadline = tr_date( ) + maxwait_msec; const uint64_t deadline = tr_date( ) + maxwait_msec;
tr_deepLog( __FILE__, __LINE__, NULL, "shutting down transmission session %p", h ); dbgmsg( "shutting down transmission session %p", session );
tr_statsClose( h );
tr_runInEventThread( h, tr_closeAllConnections, h ); /* close the session */
while( !h->isClosed && !deadlineReached( deadline ) ) tr_runInEventThread( session, tr_closeAllConnections, session );
while( !session->isClosed && !deadlineReached( deadline ) ) {
dbgmsg( "waiting for the shutdown commands to run in the main thread" );
tr_wait( 100 ); tr_wait( 100 );
}
tr_trackerSessionClose( h ); /* "shared" and "tracker" have live sockets,
tr_list_free( &h->blocklists, (TrListForeachFunc)_tr_blocklistFree ); * so we need to keep the transmission thread alive
tr_webClose( &h->web ); * for a bit while they tell the router & tracker
* that we're closing now */
tr_eventClose( h ); while( ( session->shared || session->tracker ) && !deadlineReached( deadline ) ) {
while( h->events && !deadlineReached( deadline ) ) dbgmsg( "waiting on port unmap (%p) or tracker (%p)",
session->shared, session->tracker );
tr_wait( 100 ); tr_wait( 100 );
}
tr_fdClose( ); tr_fdClose( );
tr_lockFree( h->lock );
for( i=0; i<h->metainfoLookupCount; ++i ) /* close the libtransmission thread */
tr_free( h->metainfoLookup[i].filename ); tr_eventClose( session );
tr_free( h->metainfoLookup ); while( session->events && !deadlineReached( deadline ) ) {
tr_free( h->tag ); dbgmsg( "waiting for the libevent thread to shutdown cleanly" );
tr_free( h->configDir ); tr_wait( 100 );
tr_free( h->resumeDir ); }
tr_free( h->torrentDir );
tr_free( h->downloadDir ); /* free the session memory */
tr_free( h->proxy ); tr_lockFree( session->lock );
tr_free( h->proxyUsername ); for( i=0; i<session->metainfoLookupCount; ++i )
tr_free( h->proxyPassword ); tr_free( session->metainfoLookup[i].filename );
free( h ); tr_free( session->metainfoLookup );
tr_free( session->tag );
tr_free( session->configDir );
tr_free( session->resumeDir );
tr_free( session->torrentDir );
tr_free( session->downloadDir );
tr_free( session->proxy );
tr_free( session->proxyUsername );
tr_free( session->proxyPassword );
tr_free( session );
} }
tr_torrent ** tr_torrent **