diff --git a/libtransmission/bencode.c b/libtransmission/bencode.c index 47e8774cb..459d69188 100644 --- a/libtransmission/bencode.c +++ b/libtransmission/bencode.c @@ -1043,7 +1043,7 @@ tr_bencSave( const tr_benc * top, { char * ret; struct WalkFuncs walkFuncs; - struct evbuffer * out = evbuffer_new( ); + struct evbuffer * out = tr_getBuffer( ); walkFuncs.intFunc = saveIntFunc; walkFuncs.stringFunc = saveStringFunc; @@ -1055,7 +1055,8 @@ tr_bencSave( const tr_benc * top, if( len ) *len = EVBUFFER_LENGTH( out ); ret = tr_strndup( EVBUFFER_DATA( out ), EVBUFFER_LENGTH( out ) ); - evbuffer_free( out ); + + tr_releaseBuffer( out ); return ret; } @@ -1317,7 +1318,7 @@ tr_bencSaveAsJSON( const tr_benc * top, struct WalkFuncs walkFuncs; struct jsonWalk data; - data.out = evbuffer_new( ); + data.out = tr_getBuffer( ); data.parents = NULL; walkFuncs.intFunc = jsonIntFunc; @@ -1333,7 +1334,8 @@ tr_bencSaveAsJSON( const tr_benc * top, if( len ) *len = EVBUFFER_LENGTH( data.out ); ret = tr_strndup( EVBUFFER_DATA( data.out ), EVBUFFER_LENGTH( data.out ) ); - evbuffer_free( data.out ); + + tr_releaseBuffer( data.out ); return ret; } diff --git a/libtransmission/clients.c b/libtransmission/clients.c index 626248621..8eecb2141 100644 --- a/libtransmission/clients.c +++ b/libtransmission/clients.c @@ -410,7 +410,7 @@ tr_clientForId( char * buf, size_t buflen, const void * id_in ) /* No match */ if( !*buf ) { - struct evbuffer * out = evbuffer_new( ); + struct evbuffer * out = tr_getBuffer( ); const char *in, *in_end; for( in=(const char*)id, in_end=in+8; in!=in_end; ++in ) { if( isprint( *in ) ) @@ -420,6 +420,6 @@ tr_clientForId( char * buf, size_t buflen, const void * id_in ) } tr_strlcpy( buf, EVBUFFER_DATA( out ), buflen ); - evbuffer_free( out ); + tr_releaseBuffer( out ); } } diff --git a/libtransmission/handshake.c b/libtransmission/handshake.c index 8ac2f064f..2e68eeb1f 100644 --- a/libtransmission/handshake.c +++ b/libtransmission/handshake.c @@ -314,7 +314,7 @@ sendYa( tr_handshake * handshake ) { int len; const uint8_t * public_key; - struct evbuffer * outbuf = evbuffer_new( ); + struct evbuffer * outbuf = tr_getBuffer( ); uint8_t pad_a[PadA_MAXLEN]; /* add our public key (Ya) */ @@ -333,7 +333,7 @@ sendYa( tr_handshake * handshake ) tr_peerIoWriteBuf( handshake->io, outbuf, FALSE ); /* cleanup */ - evbuffer_free( outbuf ); + tr_releaseBuffer( outbuf ); } static uint32_t @@ -426,7 +426,7 @@ readYb( tr_handshake * handshake, /* now send these: HASH('req1', S), HASH('req2', SKEY) xor HASH('req3', S), * ENCRYPT(VC, crypto_provide, len(PadC), PadC, len(IA)), ENCRYPT(IA) */ - outbuf = evbuffer_new( ); + outbuf = tr_getBuffer( ); /* HASH('req1', S) */ { @@ -483,7 +483,7 @@ readYb( tr_handshake * handshake, tr_peerIoWriteBuf( handshake->io, outbuf, FALSE ); /* cleanup */ - evbuffer_free( outbuf ); + tr_releaseBuffer( outbuf ); return READ_LATER; } @@ -919,7 +919,7 @@ readIA( tr_handshake * handshake, **/ tr_cryptoEncryptInit( handshake->crypto ); - outbuf = evbuffer_new( ); + outbuf = tr_getBuffer( ); dbgmsg( handshake, "sending vc" ); /* send VC */ @@ -968,7 +968,7 @@ readIA( tr_handshake * handshake, /* send it out */ tr_peerIoWriteBuf( handshake->io, outbuf, FALSE ); - evbuffer_free( outbuf ); + tr_releaseBuffer( outbuf ); /* now await the handshake */ setState( handshake, AWAITING_PAYLOAD_STREAM ); diff --git a/libtransmission/metainfo.c b/libtransmission/metainfo.c index 9c573563c..123fcac69 100644 --- a/libtransmission/metainfo.c +++ b/libtransmission/metainfo.c @@ -61,7 +61,7 @@ getOldTorrentFilename( const tr_session * session, const tr_info * inf ) { char * ret; - struct evbuffer * buf = evbuffer_new( ); + struct evbuffer * buf = tr_getBuffer( ); evbuffer_add_printf( buf, "%s%c%s", tr_getTorrentDir( session ), TR_PATH_DELIMITER, @@ -70,7 +70,7 @@ getOldTorrentFilename( const tr_session * session, evbuffer_add_printf( buf, "-%s", session->tag ); ret = tr_strndup( EVBUFFER_DATA( buf ), EVBUFFER_LENGTH( buf ) ); - evbuffer_free( buf ); + tr_releaseBuffer( buf ); return ret; } @@ -136,7 +136,7 @@ getfile( char ** setme, } else { - struct evbuffer * buf = evbuffer_new( ); + struct evbuffer * buf = tr_getBuffer( ); int n = tr_bencListSize( path ); int i; @@ -154,7 +154,7 @@ getfile( char ** setme, *setme = tr_strndup( EVBUFFER_DATA( buf ), EVBUFFER_LENGTH( buf ) ); /* fprintf( stderr, "[%s]\n", *setme ); */ - evbuffer_free( buf ); + tr_releaseBuffer( buf ); err = 0; } @@ -234,12 +234,12 @@ announceToScrape( const char * announce ) if( ( ( s = strrchr( announce, '/' ) ) ) && !strncmp( ++s, "announce", 8 ) ) { - struct evbuffer * buf = evbuffer_new( ); + struct evbuffer * buf = tr_getBuffer( ); evbuffer_add( buf, announce, s - announce ); evbuffer_add( buf, "scrape", 6 ); evbuffer_add_printf( buf, "%s", s + 8 ); scrape = tr_strdup( EVBUFFER_DATA( buf ) ); - evbuffer_free( buf ); + tr_releaseBuffer( buf ); } return scrape; diff --git a/libtransmission/peer-msgs.c b/libtransmission/peer-msgs.c index 425645943..0e4b63d7a 100644 --- a/libtransmission/peer-msgs.c +++ b/libtransmission/peer-msgs.c @@ -329,7 +329,7 @@ myDebug( const char * file, int line, { va_list args; char timestr[64]; - struct evbuffer * buf = evbuffer_new( ); + struct evbuffer * buf = tr_getBuffer( ); char * base = tr_basename( file ); evbuffer_add_printf( buf, "[%s] %s - %s [%s]: ", @@ -344,7 +344,7 @@ myDebug( const char * file, int line, fwrite( EVBUFFER_DATA( buf ), 1, EVBUFFER_LENGTH( buf ), fp ); tr_free( base ); - evbuffer_free( buf ); + tr_releaseBuffer( buf ); } } @@ -1758,14 +1758,9 @@ fillOutputBuffer( tr_peermsgs * msgs, time_t now ) { int err; static uint8_t * buf = NULL; - static struct evbuffer * out = NULL; if( buf == NULL ) buf = tr_new( uint8_t, MAX_BLOCK_SIZE ); - if( out == NULL ) - out = evbuffer_new( ); - - assert( !EVBUFFER_LENGTH( out ) ); /* send a block */ if(( err = tr_ioRead( msgs->torrent, req.index, req.offset, req.length, buf ))) { @@ -1774,6 +1769,7 @@ fillOutputBuffer( tr_peermsgs * msgs, time_t now ) msgs = NULL; } else { tr_peerIo * io = msgs->peer->io; + struct evbuffer * out = tr_getBuffer( ); dbgmsg( msgs, "sending block %u:%u->%u", req.index, req.offset, req.length ); tr_peerIoWriteUint32( io, out, sizeof( uint8_t ) + 2 * sizeof( uint32_t ) + req.length ); tr_peerIoWriteUint8 ( io, out, BT_PIECE ); @@ -1783,6 +1779,7 @@ fillOutputBuffer( tr_peermsgs * msgs, time_t now ) tr_peerIoWriteBuf( io, out, TRUE ); bytesWritten += EVBUFFER_LENGTH( out ); msgs->clientSentAnythingAt = now; + tr_releaseBuffer( out ); } } else if( fext ) /* peer needs a reject message */ diff --git a/libtransmission/rpc-server.c b/libtransmission/rpc-server.c index 25256232a..9766b11cc 100644 --- a/libtransmission/rpc-server.c +++ b/libtransmission/rpc-server.c @@ -76,13 +76,14 @@ send_simple_response( struct evhttp_request * req, const char * text ) { const char * code_text = tr_webGetResponseStr( code ); - struct evbuffer * body = evbuffer_new( ); + struct evbuffer * body = tr_getBuffer( ); evbuffer_add_printf( body, "

%d: %s

", code, code_text ); if( text ) evbuffer_add_printf( body, "%s", text ); evhttp_send_reply( req, code, code_text, body ); - evbuffer_free( body ); + + tr_releaseBuffer( body ); } static const char* @@ -319,13 +320,13 @@ serve_file( struct evhttp_request * req, struct evbuffer * out; errno = error; - out = evbuffer_new( ); + out = tr_getBuffer( ); evhttp_add_header( req->output_headers, "Content-Type", mimetype_guess( filename ) ); add_response( req, out, content, content_len ); evhttp_send_reply( req, HTTP_OK, "OK", out ); - evbuffer_free( out ); + tr_releaseBuffer( out ); tr_free( content ); } } @@ -398,14 +399,14 @@ handle_rpc( struct evhttp_request * req, &len ); } - buf = evbuffer_new( ); + buf = tr_getBuffer( ); add_response( req, buf, out, len ); evhttp_add_header( req->output_headers, "Content-Type", "application/json; charset=UTF-8" ); evhttp_send_reply( req, HTTP_OK, "OK", buf ); /* cleanup */ - evbuffer_free( buf ); + tr_releaseBuffer( buf ); tr_free( out ); } diff --git a/libtransmission/utils.c b/libtransmission/utils.c index d95a33e8e..bdd1dc702 100644 --- a/libtransmission/utils.c +++ b/libtransmission/utils.c @@ -44,6 +44,7 @@ #endif #include "transmission.h" +#include "list.h" #include "utils.h" #include "platform.h" @@ -239,7 +240,7 @@ tr_deepLog( const char * file, { va_list args; char timestr[64]; - struct evbuffer * buf = evbuffer_new( ); + struct evbuffer * buf = tr_getBuffer( ); char * base = tr_basename( file ); evbuffer_add_printf( buf, "[%s] ", @@ -255,7 +256,7 @@ tr_deepLog( const char * file, (void) fwrite( EVBUFFER_DATA( buf ), 1, EVBUFFER_LENGTH( buf ), fp ); tr_free( base ); - evbuffer_free( buf ); + tr_releaseBuffer( buf ); } } @@ -684,14 +685,14 @@ tr_strdup_printf( const char * fmt, ... ) struct evbuffer * buf; va_list ap; - buf = evbuffer_new( ); + buf = tr_getBuffer( ); va_start( ap, fmt ); if( evbuffer_add_vprintf( buf, fmt, ap ) != -1 ) ret = tr_strdup( EVBUFFER_DATA( buf ) ); va_end( ap ); - evbuffer_free( buf ); + tr_releaseBuffer( buf ); return ret; } @@ -1293,3 +1294,26 @@ tr_int2ptr( int i ) { return (void*)(intptr_t)i; } + +/*** +**** +***/ + +static tr_list * _bufferList = NULL; + +struct evbuffer* +tr_getBuffer( void ) +{ + struct evbuffer * buf = tr_list_pop_front( &_bufferList ); + if( buf == NULL ) + buf = evbuffer_new( ); + assert( !EVBUFFER_LENGTH( buf ) ); + return buf; +} + +void +tr_releaseBuffer( struct evbuffer * buf ) +{ + evbuffer_drain( buf, EVBUFFER_LENGTH( buf ) ); + tr_list_prepend( &_bufferList, buf ); +} diff --git a/libtransmission/utils.h b/libtransmission/utils.h index 6665e36a3..20c751058 100644 --- a/libtransmission/utils.h +++ b/libtransmission/utils.h @@ -245,6 +245,21 @@ uint64_t tr_date( void ); /* wait the specified number of milliseconds */ void tr_wait( uint64_t delay_milliseconds ); +/*** +**** +***/ + +struct evbuffer; + +/** @brief pool of reusable buffers + @see tr_releaseBuffer() */ +struct evbuffer * tr_getBuffer( void ); + +/** @brief return a buffer to the pool + @see tr_getBuffer() */ +void tr_releaseBuffer( struct evbuffer * buf ); + + /*** **** ***/ diff --git a/libtransmission/webseed.c b/libtransmission/webseed.c index 0b467be0a..b9767f612 100644 --- a/libtransmission/webseed.c +++ b/libtransmission/webseed.c @@ -99,7 +99,7 @@ makeURL( tr_webseed * w, const tr_file * file ) { char * ret; - struct evbuffer * out = evbuffer_new( ); + struct evbuffer * out = tr_getBuffer( ); const char * url = w->url; const size_t url_len = strlen( url ); @@ -140,7 +140,7 @@ makeURL( tr_webseed * w, } ret = tr_strndup( EVBUFFER_DATA( out ), EVBUFFER_LENGTH( out ) ); - evbuffer_free( out ); + tr_releaseBuffer( out ); return ret; }