Return-Path: Delivered-To: apmail-apache-cvs-archive@apache.org Received: (qmail 38244 invoked by uid 500); 23 May 2000 02:19:42 -0000 Mailing-List: contact apache-cvs-help@apache.org; run by ezmlm Precedence: bulk X-No-Archive: yes Reply-To: new-httpd@apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list apache-cvs@apache.org Received: (qmail 38231 invoked by uid 500); 23 May 2000 02:19:41 -0000 Delivered-To: apmail-apache-2.0-cvs@apache.org Date: 23 May 2000 02:19:40 -0000 Message-ID: <20000523021940.38217.qmail@locus.apache.org> From: bjh@locus.apache.org To: apache-2.0-cvs@apache.org Subject: cvs commit: apache-2.0/src/lib/apr/file_io/win32 filedup.c fileio.h open.c readwrite.c seek.c 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 #include +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; + } } }