Changeset 483

Show
Ignore:
Timestamp:
07/26/07 23:32:51 (1 year ago)
Author:
blackhedd
Message:

Patches by Kirk Haines to improve the send_file_to_connection mechanism

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • version_0/ext/cmain.cpp

    r433 r483  
    383383         * TODO, given that we want this to work only with small files, how about allocating 
    384384         * the buffer on the stack rather than the heap? 
     385         * 
     386         * Modified 25Jul07. This now returns -1 on file-too-large; 0 for success, and a positive 
     387         * errno in case of other errors. 
     388         * 
    385389        /* Contributed by Kirk Haines. 
    386390         */ 
    387391 
    388         char *data; 
     392        char data[32*1024]; 
     393        int r; 
    389394 
    390395        if (!EventMachine) 
     
    392397 
    393398        int Fd = open (filename, O_RDONLY); 
     399 
    394400        if (Fd < 0) 
    395                 throw runtime_error (strerror (errno)); 
     401                return errno; 
     402        // From here on, all early returns MUST close Fd. 
    396403 
    397404        struct stat st; 
    398         if (fstat (Fd, &st)) 
    399                 throw runtime_error (strerror (errno)); 
     405        if (fstat (Fd, &st)) { 
     406                int e = errno; 
     407                close (Fd); 
     408                return e; 
     409        } 
    400410 
    401411        int filesize = st.st_size; 
     
    404414                return 0; 
    405415        } 
    406  
    407         data = (char*) malloc (filesize); 
    408         if (!data) 
    409                 throw runtime_error ("No allocation"); 
    410         int r = read (Fd, data, filesize); 
    411         if (r < filesize) 
    412                 throw runtime_error (strerror (errno)); 
    413         int rd = evma_send_data_to_connection (binding, data, r); 
     416        else if (filesize > sizeof(data)) { 
     417                close (Fd); 
     418                return -1; 
     419        } 
     420 
     421 
     422        r = read (Fd, data, filesize); 
     423        if (r != filesize) { 
     424                int e = errno; 
     425                close (Fd); 
     426                return e; 
     427        } 
     428        evma_send_data_to_connection (binding, data, r); 
    414429        close (Fd); 
    415         free (data); 
    416  
    417         return rd; 
    418 
    419  
    420  
    421  
    422  
     430 
     431        return 0; 
     432
     433 
     434 
     435 
     436 
  • version_0/ext/rubymain.cpp

    r433 r483  
    380380static VALUE t_send_file_data (VALUE self, VALUE signature, VALUE filename) 
    381381{ 
     382 
     383        /* The current implementation of evma_send_file_data_to_connection enforces a strict 
     384         * upper limit on the file size it will transmit (currently 32K). The function returns 
     385         * zero on success, -1 if the requested file exceeds its size limit, and a positive 
     386         * number for other errors. 
     387         * TODO: Positive return values are actually errno's, which is probably the wrong way to 
     388         * do this. For one thing it's ugly. For another, we can't be sure zero is never a real errno. 
     389         */ 
     390 
    382391        int b = evma_send_file_data_to_connection (StringValuePtr(signature), StringValuePtr(filename)); 
    383         return INT2NUM (b); 
     392        if (b == -1) 
     393                rb_raise(rb_eRuntimeError, "File too large.  send_file_data() supports files under 32k."); 
     394        if (b > 0) { 
     395                char *err = strerror (b); 
     396                char buf[1024]; 
     397                memset (buf, 0, sizeof(buf)); 
     398                snprintf (buf, sizeof(buf)-1, ": %s %s", StringValuePtr(filename),(err?err:"???")); 
     399 
     400                rb_raise (rb_eIOError, buf); 
     401        } 
     402 
     403        return INT2NUM (0); 
    384404} 
    385405 
  • version_0/lib/em/streamer.rb

    r472 r483  
    2727module EventMachine 
    2828        class FileStreamer 
    29                 MappingThreshold = 8192 
     29                MappingThreshold = 16384 
    3030                BackpressureLevel = 50000 
    31                 ChunkSize = 4096 
     31                ChunkSize = 16384 
    3232 
    3333                include Deferrable 
     
    5050                def stream_without_mapping filename 
    5151                        if @http_chunks 
    52                                 @connection.send_data "#{format("%x",@size)}\r\n" 
     52                                #@connection.send_data "#{format("%x",@size)}\r\n" 
     53                                @connection.send_data "#{@size.to_s(16)}\r\n" 
    5354                                @connection.send_file_data filename 
    5455                                @connection.send_data "\r\n0\r\n\r\n" 
     
    7475                                        if @connection.get_outbound_data_size > BackpressureLevel 
    7576                                                EventMachine::next_tick {stream_one_chunk} 
     77                                                break 
    7678                                        else 
    7779                                                len = @size - @position 
    7880                                                len = ChunkSize if (len > ChunkSize) 
    7981 
    80                                                 @connection.send_data( "#{format("%x",len)}\r\n" ) if @http_chunks 
     82                                                #@connection.send_data( "#{format("%x",len)}\r\n" ) if @http_chunks 
     83                                                @connection.send_data( "#{len.to_s(16)}\r\n" ) if @http_chunks 
    8184                                                @connection.send_data( @mapping.get_chunk( @position, len )) 
    8285                                                @connection.send_data("\r\n") if @http_chunks