httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From b..@locus.apache.org
Subject cvs commit: apache-2.0/src/lib/apr/file_io/win32 filedup.c fileio.h open.c readwrite.c seek.c
Date Tue, 23 May 2000 02:19:40 GMT
bjh         00/05/22 19:19:39

  Modified:    src/lib/apr/file_io/win32 filedup.c fileio.h open.c
                        readwrite.c seek.c
  Log:
  Win32: Add buffered file I/O
  Note that this code is tested to compile only. It needs some Win32 folk to
  have a bash on it to see if it works & fix if necessary.
  
  Revision  Changes    Path
  1.18      +1 -0      apache-2.0/src/lib/apr/file_io/win32/filedup.c
  
  Index: filedup.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/win32/filedup.c,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- filedup.c	2000/05/04 21:35:58	1.17
  +++ filedup.c	2000/05/23 02:19:36	1.18
  @@ -115,6 +115,7 @@
       (*new_file)->atime = old_file->atime;    
       (*new_file)->mtime = old_file->mtime;
       (*new_file)->ctime = old_file->ctime;
  +    (*new_file)->buffered = FALSE;
   
       if (!isStdHandle) {
           ap_register_cleanup((*new_file)->cntxt, (void *)(*new_file), file_cleanup,
  
  
  
  1.22      +11 -0     apache-2.0/src/lib/apr/file_io/win32/fileio.h
  
  Index: fileio.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/win32/fileio.h,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- fileio.h	2000/04/28 18:27:38	1.21
  +++ fileio.h	2000/05/23 02:19:36	1.22
  @@ -79,9 +79,12 @@
   #include "apr_private.h"
   #include "apr_pools.h"
   #include "apr_general.h"
  +#include "apr_lock.h"
   #include "apr_file_io.h"
   #include "apr_errno.h"
   
  +#define APR_FILE_BUFSIZE 4096
  +
   /* quick run-down of fields in windows' ap_file_t structure that may have 
    * obvious uses.
    * fname --  the filename as passed to the open call.
  @@ -114,6 +117,14 @@
       ap_time_t atime;
       ap_time_t mtime;
       ap_time_t ctime;
  +
  +    /* Stuff for buffered mode */
  +    char *buffer;
  +    int bufpos;               // Read/Write position in buffer
  +    unsigned long dataRead;   // amount of valid data read into buffer
  +    int direction;            // buffer being used for 0 = read, 1 = write
  +    unsigned long filePtr;    // position in file of handle
  +    ap_lock_t *mutex;         // mutex semaphore, must be owned to access the above fields
   };
   
   struct ap_dir_t {
  
  
  
  1.40      +15 -0     apache-2.0/src/lib/apr/file_io/win32/open.c
  
  Index: open.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/win32/open.c,v
  retrieving revision 1.39
  retrieving revision 1.40
  diff -u -r1.39 -r1.40
  --- open.c	2000/05/01 03:24:32	1.39
  +++ open.c	2000/05/23 02:19:36	1.40
  @@ -82,6 +82,7 @@
       DWORD attributes = 0;
       DWORD sharemode = FILE_SHARE_READ | FILE_SHARE_WRITE;
       ap_oslevel_e level;
  +    ap_status_t rv;
   
       (*dafile) = (ap_file_t *)ap_pcalloc(cont, sizeof(ap_file_t));
   
  @@ -98,6 +99,16 @@
           return APR_EACCES;
       }
   
  +    (*dafile)->buffered = (flag & APR_BUFFERED) > 0;
  +
  +    if ((*dafile)->buffered) {
  +        (*dafile)->buffer = ap_palloc(cont, APR_FILE_BUFSIZE);
  +        rv = ap_create_lock(&(*dafile)->mutex, APR_MUTEX, APR_INTRAPROCESS, NULL,
cont);
  +
  +        if (rv)
  +            return rv;
  +    }
  +
       (*dafile)->fname = ap_pstrdup(cont, fname);
   
       (*dafile)->demonfname = canonical_filename((*dafile)->cntxt, fname);
  @@ -164,6 +175,10 @@
       ap_status_t stat;
       if ((stat = file_cleanup(file)) == APR_SUCCESS) {
           ap_kill_cleanup(file->cntxt, file, file_cleanup);
  +
  +        if (file->buffered)
  +            ap_destroy_lock(file->mutex);
  +
           return APR_SUCCESS;
       }
       return stat;
  
  
  
  1.33      +122 -30   apache-2.0/src/lib/apr/file_io/win32/readwrite.c
  
  Index: readwrite.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/win32/readwrite.c,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- readwrite.c	2000/05/01 14:39:31	1.32
  +++ readwrite.c	2000/05/23 02:19:36	1.33
  @@ -67,19 +67,58 @@
       DWORD bread;
       int lasterror;
   
  -    if (ReadFile(thefile->filehand, buf, *nbytes, &bread, NULL)) {
  -        *nbytes = bread;
  -        return APR_SUCCESS;
  -    }
  +    if (thefile->buffered) {
  +        char *pos = (char *)buf;
  +        ULONG blocksize;
  +        ULONG size = *nbytes;
  +
  +        ap_lock(thefile->mutex);
  +
  +        if (thefile->direction == 1) {
  +            ap_flush(thefile);
  +            thefile->bufpos = 0;
  +            thefile->direction = 0;
  +            thefile->dataRead = 0;
  +        }
   
  -    *nbytes = 0;
  -    lasterror = GetLastError();
  -    if (lasterror == ERROR_BROKEN_PIPE) {
  -        /* Assume ERROR_BROKEN_PIPE signals an EOF reading from a pipe */
  -        return APR_SUCCESS;
  -    } else if (lasterror == ERROR_NO_DATA) {
  -        /* Receive this error on a read to a pipe in nonblocking mode */
  -        return APR_EAGAIN;
  +        while (lasterror == 0 && size > 0) {
  +            if (thefile->bufpos >= thefile->dataRead) {
  +                lasterror = ReadFile(thefile->filehand, thefile->buffer, APR_FILE_BUFSIZE,
&thefile->dataRead, NULL ) ? 0 : GetLastError();
  +
  +                if (thefile->dataRead == 0) {
  +                    if (lasterror == 0)
  +                        thefile->eof_hit = TRUE;
  +                    break;
  +                }
  +
  +                thefile->filePtr += thefile->dataRead;
  +                thefile->bufpos = 0;
  +            }
  +
  +            blocksize = size > thefile->dataRead - thefile->bufpos ? thefile->dataRead
- thefile->bufpos : size;
  +            memcpy(pos, thefile->buffer + thefile->bufpos, blocksize);
  +            thefile->bufpos += blocksize;
  +            pos += blocksize;
  +            size -= blocksize;
  +        }
  +
  +        *nbytes = lasterror == 0 ? pos - (char *)buf : 0;
  +        ap_unlock(thefile->mutex);
  +    } else {
  +        if (ReadFile(thefile->filehand, buf, *nbytes, &bread, NULL)) {
  +            *nbytes = bread;
  +            return APR_SUCCESS;
  +        }
  +
  +        *nbytes = 0;
  +        lasterror = GetLastError();
  +        if (lasterror == ERROR_BROKEN_PIPE) {
  +            /* Assume ERROR_BROKEN_PIPE signals an EOF reading from a pipe */
  +            return APR_SUCCESS;
  +        } else if (lasterror == ERROR_NO_DATA) {
  +            /* Receive this error on a read to a pipe in nonblocking mode */
  +            return APR_EAGAIN;
  +        }
       }
   
       return lasterror;
  @@ -90,22 +129,53 @@
       ap_status_t rv;
       DWORD bwrote;
   
  -    if (!thefile->pipe && thefile->append) {
  -        SetFilePointer(thefile->filehand, 0, NULL, FILE_END);
  -    }
  -    if (WriteFile(thefile->filehand, buf, *nbytes, &bwrote, NULL)) {
  -        *nbytes = bwrote;
  -        rv = APR_SUCCESS;
  -    } 
  -    else {
  -        (*nbytes) = 0;
  -        rv = GetLastError();
  +    if (thefile->buffered) {
  +        char *pos = (char *)buf;
  +        int blocksize;
  +        int size = *nbytes;
  +
  +        ap_lock(thefile->mutex);
  +
  +        if (thefile->direction == 0) {
  +            // Position file pointer for writing at the offset we are logically reading
from
  +            ULONG offset = thefile->filePtr - thefile->dataRead + thefile->bufpos;
  +            if (offset != thefile->filePtr)
  +                SetFilePointer(thefile->filehand, offset, NULL, FILE_BEGIN);
  +            thefile->bufpos = thefile->dataRead = 0;
  +            thefile->direction = 1;
  +        }
  +
  +        while (rv == 0 && size > 0) {
  +            if (thefile->bufpos == APR_FILE_BUFSIZE)   // write buffer is full
  +                rv = ap_flush(thefile);
  +
  +            blocksize = size > APR_FILE_BUFSIZE - thefile->bufpos ? APR_FILE_BUFSIZE
- thefile->bufpos : size;
  +            memcpy(thefile->buffer + thefile->bufpos, pos, blocksize);
  +            thefile->bufpos += blocksize;
  +            pos += blocksize;
  +            size -= blocksize;
  +        }
  +
  +        ap_unlock(thefile->mutex);
  +        return rv;
  +    } else {
  +        if (!thefile->pipe && thefile->append) {
  +            SetFilePointer(thefile->filehand, 0, NULL, FILE_END);
  +        }
  +        if (WriteFile(thefile->filehand, buf, *nbytes, &bwrote, NULL)) {
  +            *nbytes = bwrote;
  +            rv = APR_SUCCESS;
  +        }
  +        else {
  +            (*nbytes) = 0;
  +            rv = GetLastError();
  +        }
       }
   
       return rv;
   }
   /*
  - * Too bad WriteFileGather() is not supported on 95&98 (or NT prior to SP2) 
  + * Too bad WriteFileGather() is not supported on 95&98 (or NT prior to SP2)
    */
   ap_status_t ap_writev(ap_file_t *thefile, const struct iovec *vec, ap_size_t nvec, 
                         ap_ssize_t *nbytes)
  @@ -155,11 +225,18 @@
       if (GetFileType(thefile->filehand) != FILE_TYPE_DISK) {
           return GetLastError();
       }
  -    /* and the file pointer is not pointing to the start of the file. */
  -    if (GetFilePointer(thefile->filehand)) {
  -        if (SetFilePointer(thefile->filehand, -1, NULL, FILE_CURRENT) 
  -            == 0xFFFFFFFF) {
  -            return GetLastError();
  +
  +    if (thefile->buffered) {
  +        ap_off_t offset = -1;
  +        return ap_seek(thefile, APR_CUR, &offset);
  +    }
  +    else {
  +        /* and the file pointer is not pointing to the start of the file. */
  +        if (GetFilePointer(thefile->filehand)) {
  +            if (SetFilePointer(thefile->filehand, -1, NULL, FILE_CURRENT)
  +                == 0xFFFFFFFF) {
  +                return GetLastError();
  +            }
           }
       }
   
  @@ -218,8 +295,23 @@
   }
   ap_status_t ap_flush(ap_file_t *thefile)
   {
  -    FlushFileBuffers(thefile->filehand);
  -    return APR_SUCCESS; 
  +    if (thefile->buffered) {
  +        DWORD written = 0;
  +        ap_status_t rc = 0;
  +
  +        if (thefile->direction == 1 && thefile->bufpos) {
  +            rc = WriteFile(thefile->filehand, thefile->buffer, thefile->bufpos,
&written, NULL ) ? 0 : GetLastError();
  +            thefile->filePtr += written;
  +
  +            if (rc == 0)
  +                thefile->bufpos = 0;
  +        }
  +
  +        return rc;
  +    } else {
  +        FlushFileBuffers(thefile->filehand);
  +        return APR_SUCCESS;
  +    }
   }
   
   static int printf_flush(ap_vformatter_buff_t *vbuff)
  
  
  
  1.8       +75 -22    apache-2.0/src/lib/apr/file_io/win32/seek.c
  
  Index: seek.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/win32/seek.c,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- seek.c	2000/05/01 03:24:32	1.7
  +++ seek.c	2000/05/23 02:19:36	1.8
  @@ -57,33 +57,86 @@
   #include <errno.h>
   #include <string.h>
   
  +static ap_status_t setptr(ap_file_t *thefile, unsigned long pos )
  +{
  +    long newbufpos;
  +    DWORD rc;
  +
  +    if (thefile->direction == 1) {
  +        ap_flush(thefile);
  +        thefile->bufpos = thefile->direction = thefile->dataRead = 0;
  +    }
  +
  +    newbufpos = pos - (thefile->filePtr - thefile->dataRead);
  +
  +    if (newbufpos >= 0 && newbufpos <= thefile->dataRead) {
  +        thefile->bufpos = newbufpos;
  +        rc = 0;
  +    } else {
  +        rc = SetFilePointer(thefile->filehand, pos, NULL, FILE_BEGIN);
  +
  +        if ( rc == 0xFFFFFFFF )
  +            rc = GetLastError();
  +        else
  +            rc = thefile->bufpos = thefile->dataRead = 0;
  +    }
  +
  +    return rc;
  +}
  +
  +
  +
   ap_status_t ap_seek(ap_file_t *thefile, ap_seek_where_t where, ap_off_t *offset)
   {
       DWORD howmove;
       DWORD rv;
   
  -    switch(where) {
  -    case APR_SET: {
  -        howmove = FILE_BEGIN;
  -        break;
  -    }
  -    case APR_CUR: {
  -        howmove = FILE_CURRENT;
  -        break;
  -    }
  -    case APR_END: {
  -        howmove = FILE_END;
  -        break;
  -    }
  -    }
  +    if (thefile->buffered) {
  +        int rc = APR_EINVAL;
  +        ap_finfo_t finfo;
   
  -    rv = SetFilePointer(thefile->filehand, *offset, NULL, howmove);
  -    if (rv == -1) {
  -        *offset = -1;
  -        return GetLastError();
  -    }
  -    else {
  -        *offset = rv;
  -        return APR_SUCCESS;
  +        switch (where) {
  +        case APR_SET:
  +            rc = setptr(thefile, *offset);
  +            break;
  +
  +        case APR_CUR:
  +            rc = setptr(thefile, thefile->filePtr - thefile->dataRead + thefile->bufpos
+ *offset);
  +            break;
  +
  +        case APR_END:
  +            rc = ap_getfileinfo(&finfo, thefile);
  +            if (rc == APR_SUCCESS)
  +                rc = setptr(thefile, finfo.size - *offset);
  +            break;
  +        }
  +
  +        *offset = thefile->filePtr + thefile->bufpos;
  +        return rc;
  +    } else {
  +        switch(where) {
  +        case APR_SET: {
  +            howmove = FILE_BEGIN;
  +            break;
  +        }
  +        case APR_CUR: {
  +            howmove = FILE_CURRENT;
  +            break;
  +        }
  +        case APR_END: {
  +            howmove = FILE_END;
  +            break;
  +        }
  +        }
  +
  +        rv = SetFilePointer(thefile->filehand, *offset, NULL, howmove);
  +        if (rv == -1) {
  +            *offset = -1;
  +            return GetLastError();
  +        }
  +        else {
  +            *offset = rv;
  +            return APR_SUCCESS;
  +        }
       }
   }
  
  
  

Mime
View raw message