]> granicus.if.org Git - transmission/commitdiff
(trunk libT) have a pool of reusable evbuffers
authorCharles Kerr <charles@transmissionbt.com>
Tue, 30 Dec 2008 20:32:00 +0000 (20:32 +0000)
committerCharles Kerr <charles@transmissionbt.com>
Tue, 30 Dec 2008 20:32:00 +0000 (20:32 +0000)
libtransmission/bencode.c
libtransmission/clients.c
libtransmission/handshake.c
libtransmission/metainfo.c
libtransmission/peer-msgs.c
libtransmission/rpc-server.c
libtransmission/utils.c
libtransmission/utils.h
libtransmission/webseed.c

index 47e8774cba50f8bc4613ef76b408cd9a5f8ab8d5..459d6918836ef23eca681889df56533f4251952b 100644 (file)
@@ -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;
 }
 
index 626248621443d0da948f192251ce7e5d3e1bf50f..8eecb21414178b46d94dc41b0bcc763477bdbc32 100644 (file)
@@ -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 );
     }
 }
index 8ac2f064f2d0cf1402a0a0b149c40d533e1fa5f0..2e68eeb1f589c50e6386486ac456525b682f1b35 100644 (file)
@@ -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 );
index 9c573563ca35315c56804df0ab0ae4bb755c49c0..123fcac697ef5f5a2e644210d47fbe6cf7b00609 100644 (file)
@@ -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;
index 425645943bcc8fcd23686e97126bf5e222b9038e..0e4b63d7ab5dbe7e87619fbb4342fb172d18d183 100644 (file)
@@ -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 */
index 25256232a51a158c23c6cabee7b1bccd5bd1b251..9766b11cc687d4579ba31c64bd75a96f63022b2d 100644 (file)
@@ -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, "<h1>%d: %s</h1>", 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 );
 }
 
index d95a33e8efa67bcedff0fa097ae17f52a57c4fce..bdd1dc7026934a4e7665de2494440fd5b077b5ee 100644 (file)
@@ -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 );
+}
index 6665e36a37b5c52258202e320ef853da3b4ce935..20c751058849dff78c13f8440240c27b59b2a5f6 100644 (file)
@@ -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 );
+
+
 /***
 ****
 ***/
index 0b467be0a70d3abd27f870c347b4d8fe990d3fda..b9767f6127bc2b41b90a9055bf4b842ddc679f6f 100644 (file)
@@ -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;
 }