From 17e76707f29dfa22d7ec7c17e3a78563b538ec1b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 4 Feb 2008 19:54:47 +0000 Subject: [PATCH] make the stats code a little more difficult to corrupt --- libtransmission/stats.c | 67 ++++++++++++++++++++++------------ libtransmission/transmission.c | 3 +- 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/libtransmission/stats.c b/libtransmission/stats.c index b1a581ca7..53fc2e89a 100644 --- a/libtransmission/stats.c +++ b/libtransmission/stats.c @@ -24,7 +24,7 @@ struct tr_stats_handle { tr_session_stats single; - tr_session_stats cumulative; + tr_session_stats old; time_t startTime; }; @@ -115,36 +115,64 @@ void tr_statsInit( tr_handle * handle ) { struct tr_stats_handle * stats = tr_new0( struct tr_stats_handle, 1 ); - loadCumulativeStats( &stats->cumulative ); - stats->cumulative.sessionCount++; - stats->startTime = time(NULL); + loadCumulativeStats( &stats->old ); + stats->single.sessionCount = 1; + stats->startTime = time( NULL ); handle->sessionStats = stats; } void tr_statsClose( tr_handle * handle ) { - tr_session_stats tmp; - tr_getCumulativeSessionStats( handle, &tmp ); - saveCumulativeStats( &tmp ); + tr_session_stats cumulative; + tr_getCumulativeSessionStats( handle, &cumulative ); + saveCumulativeStats( &cumulative ); tr_free( handle->sessionStats ); handle->sessionStats = NULL; } +static struct tr_stats_handle * +getStats( const tr_handle * handle ) +{ + static struct tr_stats_handle nullObject; + + return handle && handle->sessionStats + ? handle->sessionStats + : &nullObject; +} + +/*** +**** +***/ + static void updateRatio( tr_session_stats * setme ) { - setme->ratio = tr_getRatio( setme->uploadedBytes, setme->downloadedBytes ); + setme->ratio = tr_getRatio( setme->uploadedBytes, + setme->downloadedBytes ); +} + +static void +addStats( tr_session_stats * setme, + const tr_session_stats * a, + const tr_session_stats * b ) +{ + setme->uploadedBytes = a->uploadedBytes + b->uploadedBytes; + setme->downloadedBytes = a->downloadedBytes + b->downloadedBytes; + setme->filesAdded = a->filesAdded + b->filesAdded; + setme->sessionCount = a->sessionCount + b->sessionCount; + setme->secondsActive = a->secondsActive + b->secondsActive; + updateRatio( setme ); } void tr_getSessionStats( const tr_handle * handle, tr_session_stats * setme ) { - const struct tr_stats_handle * stats = handle->sessionStats; + const struct tr_stats_handle * stats = getStats( handle ); *setme = stats->single; - setme->secondsActive += ( time(NULL) - stats->startTime ); + setme->secondsActive = time( NULL ) - stats->startTime; updateRatio( setme ); } @@ -152,10 +180,9 @@ void tr_getCumulativeSessionStats( const tr_handle * handle, tr_session_stats * setme ) { - const struct tr_stats_handle * stats = handle->sessionStats; - *setme = stats->cumulative; - setme->secondsActive += ( time(NULL) - stats->startTime ); - updateRatio( setme ); + tr_session_stats current; + tr_getSessionStats( handle, ¤t ); + addStats( setme, &getStats(handle)->old, ¤t ); } /** @@ -165,23 +192,17 @@ tr_getCumulativeSessionStats( const tr_handle * handle, void tr_statsAddUploaded( tr_handle * handle, uint32_t bytes ) { - struct tr_stats_handle * stats = handle->sessionStats; - stats->single.uploadedBytes += bytes; - stats->cumulative.uploadedBytes += bytes; + getStats(handle)->single.uploadedBytes += bytes; } void tr_statsAddDownloaded( tr_handle * handle, uint32_t bytes ) { - struct tr_stats_handle * stats = handle->sessionStats; - stats->single.downloadedBytes += bytes; - stats->cumulative.downloadedBytes += bytes; + getStats(handle)->single.downloadedBytes += bytes; } void tr_statsFileCreated( tr_handle * handle ) { - struct tr_stats_handle * stats = handle->sessionStats; - ++stats->cumulative.filesAdded; - ++stats->single.filesAdded; + getStats(handle)->single.filesAdded++; } diff --git a/libtransmission/transmission.c b/libtransmission/transmission.c index 074df7917..5277e164c 100644 --- a/libtransmission/transmission.c +++ b/libtransmission/transmission.c @@ -393,6 +393,8 @@ tr_close( tr_handle * h ) const int maxwait_msec = SHUTDOWN_MAX_SECONDS * 1000; const uint64_t deadline = tr_date( ) + maxwait_msec; + tr_statsClose( h ); + tr_runInEventThread( h, tr_closeImpl, h ); while( !h->isClosed && !deadlineReached( deadline ) ) tr_wait( 100 ); @@ -402,7 +404,6 @@ tr_close( tr_handle * h ) tr_wait( 100 ); tr_fdClose( ); - tr_statsClose( h ); tr_lockFree( h->lock ); free( h->tag ); free( h );