Changeset 6424


Ignore:
Timestamp:
Aug 1, 2008, 1:46:03 PM (13 years ago)
Author:
charles
Message:

#1126: crash on quit

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/session.c

    r6421 r6424  
    490490
    491491static void
    492 tr_closeAllConnections( void * vh )
    493 {
    494     tr_handle * h = vh;
     492tr_closeAllConnections( void * vsession )
     493{
     494    tr_handle * session = vsession;
    495495    tr_torrent * tor;
    496496    int i, n;
    497497    tr_torrent ** torrents;
    498498
    499     tr_sharedShuttingDown( h->shared );
    500     tr_rpcClose( &h->rpcServer );
     499    tr_statsClose( session );
     500    tr_sharedShuttingDown( session->shared );
     501    tr_rpcClose( &session->rpcServer );
    501502
    502503    /* close the torrents.  get the most active ones first so that
     
    504505     * at least we get the most important ones first. */
    505506    tor = NULL;
    506     n = h->torrentCount;
    507     torrents = tr_new( tr_torrent*, h->torrentCount );
     507    n = session->torrentCount;
     508    torrents = tr_new( tr_torrent*, session->torrentCount );
    508509    for( i=0; i<n; ++i )
    509         torrents[i] = tor = tr_torrentNext( h, tor );
     510        torrents[i] = tor = tr_torrentNext( session, tor );
    510511    qsort( torrents, n, sizeof(tr_torrent*), compareTorrentByCur );
    511512    for( i=0; i<n; ++i )
     
    513514    tr_free( torrents );
    514515
    515     tr_peerMgrFree( h->peerMgr );
    516 
    517     tr_rcClose( h->upload );
    518     tr_rcClose( h->download );
     516    tr_peerMgrFree( session->peerMgr );
     517
     518    tr_rcClose( session->upload );
     519    tr_rcClose( session->download );
     520
     521    tr_trackerSessionClose( session );
     522    tr_list_free( &session->blocklists, (TrListForeachFunc)_tr_blocklistFree );
     523    tr_webClose( &session->web );
    519524   
    520     h->isClosed = TRUE;
     525    session->isClosed = TRUE;
    521526}
    522527
     
    529534#define SHUTDOWN_MAX_SECONDS 30
    530535
    531 void
    532 tr_sessionClose( tr_handle * h )
     536#define dbgmsg(fmt...) tr_deepLog( __FILE__, __LINE__, NULL, ##fmt )
     537
     538void
     539tr_sessionClose( tr_handle * session )
    533540{
    534541    int i;
     
    536543    const uint64_t deadline = tr_date( ) + maxwait_msec;
    537544
    538     tr_deepLog( __FILE__, __LINE__, NULL, "shutting down transmission session %p", h );
    539     tr_statsClose( h );
    540 
    541     tr_runInEventThread( h, tr_closeAllConnections, h );
    542     while( !h->isClosed && !deadlineReached( deadline ) )
     545    dbgmsg( "shutting down transmission session %p", session );
     546
     547    /* close the session */
     548    tr_runInEventThread( session, tr_closeAllConnections, session );
     549    while( !session->isClosed && !deadlineReached( deadline ) ) {
     550        dbgmsg( "waiting for the shutdown commands to run in the main thread" );
    543551        tr_wait( 100 );
    544 
    545     tr_trackerSessionClose( h );
    546     tr_list_free( &h->blocklists, (TrListForeachFunc)_tr_blocklistFree );
    547     tr_webClose( &h->web );
    548 
    549     tr_eventClose( h );
    550     while( h->events && !deadlineReached( deadline ) )
     552    }
     553
     554    /* "shared" and "tracker" have live sockets,
     555     * so we need to keep the transmission thread alive
     556     * for a bit while they tell the router & tracker
     557     * that we're closing now */
     558    while( ( session->shared || session->tracker ) && !deadlineReached( deadline ) ) {
     559        dbgmsg( "waiting on port unmap (%p) or tracker (%p)",
     560                session->shared, session->tracker );
    551561        tr_wait( 100 );
    552 
     562    }
    553563    tr_fdClose( );
    554     tr_lockFree( h->lock );
    555     for( i=0; i<h->metainfoLookupCount; ++i )
    556         tr_free( h->metainfoLookup[i].filename );
    557     tr_free( h->metainfoLookup );
    558     tr_free( h->tag );
    559     tr_free( h->configDir );
    560     tr_free( h->resumeDir );
    561     tr_free( h->torrentDir );
    562     tr_free( h->downloadDir );
    563     tr_free( h->proxy );
    564     tr_free( h->proxyUsername );
    565     tr_free( h->proxyPassword );
    566     free( h );
     564
     565    /* close the libtransmission thread */
     566    tr_eventClose( session );
     567    while( session->events && !deadlineReached( deadline ) ) {
     568        dbgmsg( "waiting for the libevent thread to shutdown cleanly" );
     569        tr_wait( 100 );
     570    }
     571
     572    /* free the session memory */
     573    tr_lockFree( session->lock );
     574    for( i=0; i<session->metainfoLookupCount; ++i )
     575        tr_free( session->metainfoLookup[i].filename );
     576    tr_free( session->metainfoLookup );
     577    tr_free( session->tag );
     578    tr_free( session->configDir );
     579    tr_free( session->resumeDir );
     580    tr_free( session->torrentDir );
     581    tr_free( session->downloadDir );
     582    tr_free( session->proxy );
     583    tr_free( session->proxyUsername );
     584    tr_free( session->proxyPassword );
     585    tr_free( session );
    567586}
    568587
Note: See TracChangeset for help on using the changeset viewer.