From 784464450a0b04ca0651bce09523bd945e62236c Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 13 Aug 2009 14:47:56 +0000 Subject: [PATCH] (trunk libT) fix #2162: .resume file doesn't get saved often enough when its contents change --- libtransmission/session.c | 39 +++++++++++++++++++++++++++++++++++++++ libtransmission/session.h | 1 + libtransmission/torrent.c | 18 +++++++++++++----- libtransmission/torrent.h | 3 +++ 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/libtransmission/session.c b/libtransmission/session.c index 7445a22a1..a515402e0 100644 --- a/libtransmission/session.c +++ b/libtransmission/session.c @@ -47,6 +47,12 @@ #include "version.h" #include "web.h" +enum +{ + SAVE_INTERVAL_SECS = 120 +}; + + #define dbgmsg( ... ) \ do { \ if( tr_deepLoggingIsActive( ) ) \ @@ -530,6 +536,31 @@ tr_sessionSaveSettings( tr_session * session, tr_bencFree( &settings ); } +/*** +**** +***/ + +/** + * Periodically save the .resume files of any torrents whose + * status has recently changed. This prevents loss of metadata + * in the case of a crash, unclean shutdown, clumsy user, etc. + */ +static void +onSaveTimer( int foo UNUSED, short bar UNUSED, void * vsession ) +{ + tr_torrent * tor = NULL; + tr_session * session = vsession; + + while(( tor = tr_torrentNext( session, tor ))) + tr_torrentSave( tor ); + + tr_timerAdd( session->saveTimer, SAVE_INTERVAL_SECS, 0 ); +} + +/*** +**** +***/ + static void tr_sessionInitImpl( void * ); static void onAltTimer( int, short, void* ); static void setAltTimer( tr_session * session ); @@ -834,6 +865,10 @@ tr_sessionInitImpl( void * vdata ) evtimer_set( session->altTimer, onAltTimer, session ); setAltTimer( session ); + session->saveTimer = tr_new0( struct event, 1 ); + evtimer_set( session->saveTimer, onSaveTimer, session ); + tr_timerAdd( session->saveTimer, SAVE_INTERVAL_SECS, 0 ); + /* first %s is the application name second %s is the version number */ tr_inf( _( "%s %s started" ), TR_NAME, LONG_VERSION_STRING ); @@ -1423,6 +1458,10 @@ sessionCloseImpl( void * vsession ) if( session->isDHTEnabled ) tr_dhtUninit( session ); + evtimer_del( session->saveTimer ); + tr_free( session->saveTimer ); + session->saveTimer = NULL; + evtimer_del( session->altTimer ); tr_free( session->altTimer ); session->altTimer = NULL; diff --git a/libtransmission/session.h b/libtransmission/session.h index ef960b7eb..d88b28c74 100644 --- a/libtransmission/session.h +++ b/libtransmission/session.h @@ -124,6 +124,7 @@ struct tr_session tr_benc * metainfoLookup; struct event * altTimer; + struct event * saveTimer; /* the size of the output buffer for peer connections */ int so_sndbuf; diff --git a/libtransmission/torrent.c b/libtransmission/torrent.c index 23ba274a2..928e3350a 100644 --- a/libtransmission/torrent.c +++ b/libtransmission/torrent.c @@ -1354,6 +1354,17 @@ tr_torrentVerify( tr_torrent * tor ) tr_runInEventThread( tor->session, verifyTorrent, tor ); } +void +tr_torrentSave( tr_torrent * tor ) +{ + assert( tr_isTorrent( tor ) ); + + if( tor->isDirty ) { + tor->isDirty = FALSE; + tr_torrentSaveResume( tor ); + } +} + static void stopTorrent( void * vtor ) { @@ -1367,11 +1378,8 @@ stopTorrent( void * vtor ) tr_fdTorrentClose( tor->uniqueId ); - if( tor->isDirty ) { - tor->isDirty = 0; - if( !tor->isDeleting ) - tr_torrentSaveResume( tor ); - } + if( !tor->isDeleting ) + tr_torrentSave( tor ); } void diff --git a/libtransmission/torrent.h b/libtransmission/torrent.h index c4bbf7eee..812d4fd1c 100644 --- a/libtransmission/torrent.h +++ b/libtransmission/torrent.h @@ -118,6 +118,9 @@ tr_torrent* tr_torrentNext( tr_session * session, void tr_torrentCheckSeedRatio( tr_torrent * tor ); +/** save a torrent's .resume file if it's changed since the last time it was saved */ +void tr_torrentSave( tr_torrent * tor ); + typedef enum