You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by je...@apache.org on 2004/08/02 11:47:48 UTC

cvs commit: apr/file_io/unix readwrite.c

jerenkrantz    2004/08/02 02:47:48

  Modified:    .        CHANGES
               file_io/unix readwrite.c
  Log:
  Improve apr_file_gets() performance on buffered files by not calling
  apr_file_read() on each byte if we don't have to.
  
  (mod_negotiation requests call apr_file_gets() for each line in the map file,
  which can get to be quite expensive to have repeated memcpy()'s for one byte!)
  
  Revision  Changes    Path
  1.487     +3 -0      apr/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apr/CHANGES,v
  retrieving revision 1.486
  retrieving revision 1.487
  diff -u -u -r1.486 -r1.487
  --- CHANGES	1 Aug 2004 00:52:20 -0000	1.486
  +++ CHANGES	2 Aug 2004 09:47:48 -0000	1.487
  @@ -1,4 +1,7 @@
   Changes for APR 1.1 [Deferring these features when 1.0 is rolled out.]
  +
  +  *) Improve apr_file_gets() performance on buffered files. [Justin Erenkrantz]
  +
     *) Win32: Fix bug in apr_socket_sendfile that interferred with
        Win32 LSPs. PR 23982 [Jan Bilek, Bill Stoddard]
   
  
  
  
  1.90      +55 -11    apr/file_io/unix/readwrite.c
  
  Index: readwrite.c
  ===================================================================
  RCS file: /home/cvs/apr/file_io/unix/readwrite.c,v
  retrieving revision 1.89
  retrieving revision 1.90
  diff -u -u -r1.89 -r1.90
  --- readwrite.c	27 Mar 2004 13:11:17 -0000	1.89
  +++ readwrite.c	2 Aug 2004 09:47:48 -0000	1.90
  @@ -24,9 +24,6 @@
   #define USE_WAIT_FOR_IO
   #endif
   
  -/* problems: 
  - * 1) ungetchar not used for buffered files
  - */
   APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size_t *nbytes)
   {
       apr_ssize_t rv;
  @@ -311,18 +308,65 @@
           return APR_SUCCESS;
       }
   
  -    while (str < final) { /* leave room for trailing '\0' */
  -        nbytes = 1;
  -        rv = apr_file_read(thefile, str, &nbytes);
  -        if (rv != APR_SUCCESS) {
  -            break;
  +    /* If we have an underlying buffer, we can be *much* more efficient
  +     * and skip over the apr_file_read calls.
  +     */
  +    if (thefile->buffered) {
  +
  +#if APR_HAS_THREADS
  +        if (thefile->thlock) {
  +            apr_thread_mutex_lock(thefile->thlock);
  +        }
  +#endif
  +
  +        if (thefile->direction == 1) {
  +            apr_file_flush(thefile);
  +            thefile->direction = 0;
  +            thefile->bufpos = 0;
  +            thefile->dataRead = 0;
  +        }
  +
  +        while (str < final) { /* leave room for trailing '\0' */
  +            /* Force ungetc leftover to call apr_file_read. */
  +            if (thefile->bufpos < thefile->dataRead &&
  +                thefile->ungetchar == -1) {
  +                *str = thefile->buffer[thefile->bufpos++];
  +            }
  +            else {
  +                nbytes = 1;
  +                rv = apr_file_read(thefile, str, &nbytes);
  +                if (rv != APR_SUCCESS) {
  +                    break;
  +                }
  +            }
  +            if (*str == '\n') {
  +                ++str;
  +                break;
  +            }
  +            ++str;
           }
  -        if (*str == '\n') {
  +
  +#if APR_HAS_THREADS
  +        if (thefile->thlock) {
  +            apr_thread_mutex_unlock(thefile->thlock);
  +        }
  +#endif
  +    }
  +    else {
  +        while (str < final) { /* leave room for trailing '\0' */
  +            nbytes = 1;
  +            rv = apr_file_read(thefile, str, &nbytes);
  +            if (rv != APR_SUCCESS) {
  +                break;
  +            }
  +            if (*str == '\n') {
  +                ++str;
  +                break;
  +            }
               ++str;
  -            break;
           }
  -        ++str;
       }
  +
       /* We must store a terminating '\0' if we've stored any chars. We can
        * get away with storing it if we hit an error first. 
        */