wrowe 01/06/06 09:05:31
Modified: . CHANGES
file_io/win32 open.c pipe.c readwrite.c seek.c
include apr.hw apr_mmap.h
include/arch/win32 fileio.h
mmap/win32 mmap.c
network_io/win32 sendrecv.c
Log:
*) Complete the implementation of LARGEFILE support on Win32, although
the mmap semantics still need a touch of work.
*) Fix the APR_XTHREAD support, and apr_sendfile mechanics, so we can
handle cross-threaded file handles on Win32.
Sorry, it's rather hard to untangle one from the other to create two
patches.
Revision Changes Path
1.110 +6 -0 apr/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apr/CHANGES,v
retrieving revision 1.109
retrieving revision 1.110
diff -u -r1.109 -r1.110
--- CHANGES 2001/05/31 03:29:50 1.109
+++ CHANGES 2001/06/06 16:04:44 1.110
@@ -1,5 +1,11 @@
Changes with APR b1
+ *) Complete the implementation of LARGEFILE support on Win32, although
+ the mmap semantics still need a touch of work.
+
+ *) Fix the APR_XTHREAD support, and apr_sendfile mechanics, so we can
+ handle cross-threaded file handles on Win32.
+
*) Implement APR_READWRITE locks on Unix with POSIX rwlocks.
Introduce new apr_lock_acquire_rw() function which takes in
APR_READER or APR_WRITER. [Justin Erenkrantz]
1.75 +9 -1 apr/file_io/win32/open.c
Index: open.c
===================================================================
RCS file: /home/cvs/apr/file_io/win32/open.c,v
retrieving revision 1.74
retrieving revision 1.75
diff -u -r1.74 -r1.75
--- open.c 2001/05/31 00:11:10 1.74
+++ open.c 2001/06/06 16:04:52 1.75
@@ -162,7 +162,7 @@
CloseHandle(file->filehand);
file->filehand = INVALID_HANDLE_VALUE;
}
- if (file->pOverlapped) {
+ if (file->pOverlapped && file->pOverlapped->hEvent) {
CloseHandle(file->pOverlapped->hEvent);
file->pOverlapped = NULL;
}
@@ -284,6 +284,14 @@
(*new)->buffered = 0;
(*new)->buffer = NULL;
(*new)->mutex = NULL;
+ }
+
+ if (flag & APR_XTHREAD) {
+ /* This win32 specific feature is required to pass
+ * the current offset for an overlaped file handle.
+ */
+ (*new)->pOverlapped = (OVERLAPPED*) apr_pcalloc(cont,
sizeof(OVERLAPPED));
+ (*new)->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
}
(*new)->pipe = 0;
1.37 +2 -3 apr/file_io/win32/pipe.c
Index: pipe.c
===================================================================
RCS file: /home/cvs/apr/file_io/win32/pipe.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- pipe.c 2001/02/16 04:15:39 1.36
+++ pipe.c 2001/06/06 16:04:54 1.37
@@ -161,7 +161,7 @@
(*in) = (apr_file_t *)apr_pcalloc(p, sizeof(apr_file_t));
(*in)->cntxt = p;
- (*in)->fname = "\0"; // What was this??? : apr_pstrdup(p, "PIPE"); */
+ (*in)->fname = ""; // What was this??? : apr_pstrdup(p, "PIPE"); */
(*in)->pipe = 1;
(*in)->timeout = -1;
(*in)->ungetchar = -1;
@@ -174,7 +174,7 @@
(*out) = (apr_file_t *)apr_pcalloc(p, sizeof(apr_file_t));
(*out)->cntxt = p;
- (*in)->fname = "\0"; // What was this??? : apr_pstrdup(p, "PIPE"); */
+ (*out)->fname = ""; // What was this??? : apr_pstrdup(p, "PIPE"); */
(*out)->pipe = 1;
(*out)->timeout = -1;
(*out)->ungetchar = -1;
@@ -192,7 +192,6 @@
dwOpenMode |= FILE_FLAG_OVERLAPPED;
(*in)->pOverlapped = (OVERLAPPED*) apr_pcalloc(p,
sizeof(OVERLAPPED));
(*in)->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE,
NULL);
- /* register a cleanup for the event handle... */
}
dwPipeMode = 0;
1.59 +46 -8 apr/file_io/win32/readwrite.c
Index: readwrite.c
===================================================================
RCS file: /home/cvs/apr/file_io/win32/readwrite.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -r1.58 -r1.59
--- readwrite.c 2001/05/16 05:33:26 1.58
+++ readwrite.c 2001/06/06 16:04:55 1.59
@@ -105,6 +105,11 @@
}
}
+ if (file->pOverlapped && !file->pipe) {
+ file->pOverlapped->Offset = (DWORD)file->filePtr;
+ file->pOverlapped->OffsetHigh = (DWORD)(file->filePtr >> 32);
+ }
+
rv = ReadFile(file->filehand, buf, len, nbytes, file->pOverlapped);
if (!rv) {
@@ -137,7 +142,7 @@
}
else if (rv == APR_FROM_OS_ERROR(ERROR_BROKEN_PIPE)) {
/* Assume ERROR_BROKEN_PIPE signals an EOF reading from a pipe */
- rv = APR_SUCCESS; /* APR_EOF? */
+ rv = APR_EOF;
}
} else {
/* OK and 0 bytes read ==> end of file */
@@ -146,6 +151,9 @@
else
rv = APR_SUCCESS;
}
+ if (rv == APR_SUCCESS && file->pOverlapped && !file->pipe) {
+ file->filePtr += *nbytes;
+ }
return rv;
}
@@ -229,16 +237,18 @@
if (thefile->buffered) {
char *pos = (char *)buf;
- int blocksize;
- int size = *nbytes;
+ apr_size_t blocksize;
+ apr_size_t size = *nbytes;
apr_lock_acquire(thefile->mutex);
if (thefile->direction == 0) {
// Position file pointer for writing at the offset we are
logically reading from
apr_off_t offset = thefile->filePtr - thefile->dataRead +
thefile->bufpos;
+ DWORD offlo = (DWORD)offset;
+ DWORD offhi = (DWORD)(offset >> 32);
if (offset != thefile->filePtr)
- SetFilePointer(thefile->filehand, offset, NULL, FILE_BEGIN);
+ SetFilePointer(thefile->filehand, offlo, &offhi, FILE_BEGIN);
thefile->bufpos = thefile->dataRead = 0;
thefile->direction = 1;
}
@@ -258,22 +268,50 @@
apr_lock_release(thefile->mutex);
return rv;
} else {
- if (!thefile->pipe && thefile->append) {
+ if (thefile->pOverlapped && !thefile->pipe) {
+ thefile->pOverlapped->Offset = (DWORD)thefile->filePtr;
+ thefile->pOverlapped->OffsetHigh = (DWORD)(thefile->filePtr >>
32);
+ }
+ else if (!thefile->pipe && thefile->append) {
SetFilePointer(thefile->filehand, 0, NULL, FILE_END);
}
- if (WriteFile(thefile->filehand, buf, *nbytes, &bwrote, NULL)) {
+ if (WriteFile(thefile->filehand, buf, *nbytes, &bwrote,
+ thefile->pOverlapped)) {
*nbytes = bwrote;
rv = APR_SUCCESS;
}
else {
(*nbytes) = 0;
rv = apr_get_os_error();
+ if (rv == APR_FROM_OS_ERROR(ERROR_IO_PENDING)) {
+ /* Wait for the pending i/o (put a timeout here?) */
+ rv = WaitForSingleObject(thefile->pOverlapped->hEvent,
INFINITE);
+ switch (rv) {
+ case WAIT_OBJECT_0:
+ GetOverlappedResult(thefile->filehand,
thefile->pOverlapped, nbytes, TRUE);
+ rv = APR_SUCCESS;
+ break;
+ case WAIT_TIMEOUT:
+ rv = APR_TIMEUP;
+ break;
+ case WAIT_FAILED:
+ rv = apr_get_os_error();
+ break;
+ default:
+ break;
+ }
+ if (rv != APR_SUCCESS) {
+ CancelIo(thefile->filehand);
+ }
+ }
}
+ if (rv == APR_SUCCESS && thefile->pOverlapped && !thefile->pipe) {
+ thefile->filePtr += *nbytes;
+ }
}
-
return rv;
}
-/*
+/* ToDo: Write for it anyway and test the oslevel!
* Too bad WriteFileGather() is not supported on 95&98 (or NT prior to SP2)
*/
APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile,
1.17 +59 -39 apr/file_io/win32/seek.c
Index: seek.c
===================================================================
RCS file: /home/cvs/apr/file_io/win32/seek.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- seek.c 2001/04/12 13:43:53 1.16
+++ seek.c 2001/06/06 16:04:56 1.17
@@ -57,9 +57,9 @@
#include <errno.h>
#include <string.h>
-static apr_status_t setptr(apr_file_t *thefile, unsigned long pos )
+static apr_status_t setptr(apr_file_t *thefile, apr_off_t pos )
{
- long newbufpos;
+ apr_off_t newbufpos;
DWORD rc;
if (thefile->direction == 1) {
@@ -70,15 +70,19 @@
newbufpos = pos - (thefile->filePtr - thefile->dataRead);
if (newbufpos >= 0 && newbufpos <= thefile->dataRead) {
- thefile->bufpos = newbufpos;
+ thefile->bufpos = (apr_size_t)newbufpos;
rc = 0;
} else {
- rc = SetFilePointer(thefile->filehand, pos, NULL, FILE_BEGIN);
+ DWORD offlo = (DWORD)pos;
+ DWORD offhi = (DWORD)(pos >> 32);
+ rc = SetFilePointer(thefile->filehand, offlo, &offhi, FILE_BEGIN);
- if ( rc == 0xFFFFFFFF )
+ if (rc == 0xFFFFFFFF)
rc = apr_get_os_error();
else
- rc = thefile->bufpos = thefile->dataRead = 0;
+ rc = APR_SUCCESS;
+ if (rc == APR_SUCCESS)
+ thefile->bufpos = thefile->dataRead = 0;
}
return rc;
@@ -88,57 +92,73 @@
APR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *thefile,
apr_seek_where_t where, apr_off_t *offset)
{
- DWORD howmove;
- DWORD rv;
+ apr_finfo_t finfo;
+ apr_status_t rc = APR_EINVAL;
if (thefile->buffered) {
- int rc = APR_EINVAL;
- apr_finfo_t finfo;
-
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 = apr_file_info_get(&finfo, APR_FINFO_SIZE, thefile);
- if (rc == APR_SUCCESS && (finfo.valid & APR_FINFO_SIZE))
- rc = setptr(thefile, finfo.size - *offset);
- break;
+ 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 = apr_file_info_get(&finfo, APR_FINFO_SIZE, thefile);
+ if (rc == APR_SUCCESS)
+ rc = setptr(thefile, finfo.size - *offset);
+ break;
}
*offset = thefile->filePtr + thefile->bufpos;
return rc;
- } else {
+ }
+ else if (thefile->pOverlapped) {
switch(where) {
case APR_SET:
- howmove = FILE_BEGIN;
+ thefile->filePtr = *offset;
break;
case APR_CUR:
- howmove = FILE_CURRENT;
+ thefile->filePtr += *offset;
break;
case APR_END:
- howmove = FILE_END;
+ rc = apr_file_info_get(&finfo, APR_FINFO_SIZE, thefile);
+ if (rc == APR_SUCCESS && finfo.size - *offset < 0)
+ thefile->filePtr = finfo.size - *offset;
break;
-
- default:
- return APR_BADARG;
}
+ *offset = thefile->filePtr;
+ return rc;
+ }
+ else {
+ DWORD howmove;
+ DWORD offlo = (DWORD)*offset;
+ DWORD offhi = (DWORD)(*offset >> 32);
- rv = SetFilePointer(thefile->filehand, *offset, NULL, howmove);
- if (rv == -1) {
- *offset = -1;
- return apr_get_os_error();
- }
- else {
- *offset = rv;
- return APR_SUCCESS;
+ switch(where) {
+ case APR_SET:
+ howmove = FILE_BEGIN; break;
+ case APR_CUR:
+ howmove = FILE_CURRENT; break;
+ case APR_END:
+ howmove = FILE_END; break;
+ default:
+ return APR_EINVAL;
}
+ offlo = SetFilePointer(thefile->filehand, (LONG)offlo,
+ (LONG*)&offhi, howmove);
+ if (offlo == 0xFFFFFFFF)
+ rc = apr_get_os_error();
+ else
+ rc = APR_SUCCESS;
+ /* Since we can land at 0xffffffff we will measure our APR_SUCCESS */
+ if (rc == APR_SUCCESS)
+ *offset = ((apr_off_t)offhi << 32) | offlo;
+ return rc;
}
}
1.68 +1 -1 apr/include/apr.hw
Index: apr.hw
===================================================================
RCS file: /home/cvs/apr/include/apr.hw,v
retrieving revision 1.67
retrieving revision 1.68
diff -u -r1.67 -r1.68
--- apr.hw 2001/06/06 00:07:45 1.67
+++ apr.hw 2001/06/06 16:05:05 1.68
@@ -228,7 +228,7 @@
typedef size_t apr_size_t;
typedef ptrdiff_t apr_ssize_t;
-typedef _off_t apr_off_t;
+typedef __int64 apr_off_t;
typedef int apr_socklen_t;
typedef int pid_t;
typedef int uid_t;
1.23 +3 -3 apr/include/apr_mmap.h
Index: apr_mmap.h
===================================================================
RCS file: /home/cvs/apr/include/apr_mmap.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- apr_mmap.h 2001/04/03 05:55:50 1.22
+++ apr_mmap.h 2001/06/06 16:05:08 1.23
@@ -96,9 +96,9 @@
/** The start of the real memory page area (mapped view) */
void *mv;
/** The physical start, size and offset */
- apr_off_t pstart;
- apr_off_t psize;
- apr_off_t poffset;
+ apr_off_t pstart;
+ apr_size_t psize;
+ apr_off_t poffset;
#endif
/** The start of the memory mapped area */
void *mm;
1.53 +4 -4 apr/include/arch/win32/fileio.h
Index: fileio.h
===================================================================
RCS file: /home/cvs/apr/include/arch/win32/fileio.h,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -r1.52 -r1.53
--- fileio.h 2001/05/16 03:47:59 1.52
+++ fileio.h 2001/06/06 16:05:16 1.53
@@ -184,10 +184,10 @@
/* Stuff for buffered mode */
char *buffer;
- apr_ssize_t bufpos; // Read/Write position in buffer
- apr_ssize_t dataRead; // amount of valid data read into buffer
- int direction; // buffer being used for 0 = read, 1 = write
- apr_ssize_t filePtr; // position in file of handle
+ apr_size_t bufpos; // Read/Write position in buffer
+ apr_size_t dataRead; // amount of valid data read into buffer
+ int direction; // buffer being used for 0 = read, 1 = write
+ apr_off_t filePtr; // position in file of handle
apr_lock_t *mutex; // mutex semaphore, must be owned to access
the above fields
/* Pipe specific info */
1.5 +12 -5 apr/mmap/win32/mmap.c
Index: mmap.c
===================================================================
RCS file: /home/cvs/apr/mmap/win32/mmap.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- mmap.c 2001/02/16 04:15:59 1.4
+++ mmap.c 2001/06/06 16:05:21 1.5
@@ -96,7 +96,10 @@
apr_int32_t flag, apr_pool_t *cont)
{
static DWORD memblock = 0;
- DWORD fmaccess = 0, mvaccess = 0;
+ DWORD fmaccess = 0;
+ DWORD mvaccess = 0;
+ DWORD offlo;
+ DWORD offhi;
if (flag & APR_MMAP_WRITE)
fmaccess |= PAGE_READWRITE;
@@ -121,19 +124,23 @@
*new = apr_pcalloc(cont, sizeof(apr_mmap_t));
(*new)->pstart = (offset / memblock) * memblock;
- (*new)->psize = (offset % memblock) + size;
+ (*new)->psize = (apr_size_t)(offset % memblock) + size;
(*new)->poffset = offset - (*new)->pstart;
+ offlo = (DWORD)(*new)->psize;
+ offhi = (DWORD)((*new)->psize << 32);
(*new)->mhandle = CreateFileMapping(file->filehand, NULL, fmaccess,
- 0, (*new)->psize, NULL);
+ offhi, offlo, NULL);
if (!(*new)->mhandle || (*new)->mhandle == INVALID_HANDLE_VALUE)
{
*new = NULL;
return apr_get_os_error();
}
- (*new)->mv = MapViewOfFile((*new)->mhandle, mvaccess, 0,
- (*new)->poffset, (*new)->psize);
+ offlo = (DWORD)(*new)->poffset;
+ offhi = (DWORD)((*new)->poffset << 32);
+ (*new)->mv = MapViewOfFile((*new)->mhandle, mvaccess, offhi,
+ offlo, (*new)->psize);
if (!(*new)->mv)
{
apr_status_t rv = apr_get_os_error();
1.40 +18 -14 apr/network_io/win32/sendrecv.c
Index: sendrecv.c
===================================================================
RCS file: /home/cvs/apr/network_io/win32/sendrecv.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- sendrecv.c 2001/05/16 05:33:27 1.39
+++ sendrecv.c 2001/06/06 16:05:26 1.40
@@ -258,12 +258,16 @@
/* Initialize the overlapped structure */
memset(&overlapped,'\0', sizeof(overlapped));
- if (offset && *offset) {
- overlapped.Offset = *offset;
- }
+ if (file->pOverlapped)
+ overlapped.hEvent = file->pOverlapped->hEvent;
#ifdef WAIT_FOR_EVENT
- overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ else
+ overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
#endif
+ if (offset && *offset) {
+ file->pOverlapped->Offset = (DWORD)*offset;
+ file->pOverlapped->OffsetHigh = (DWORD)(*offset >> 32);
+ }
/* Handle the goofy case of sending headers/trailers and a zero byte
file */
if (!bytes_to_send && hdtr) {
@@ -320,15 +324,14 @@
if (!rv) {
status = apr_get_netos_error();
if (status == APR_FROM_OS_ERROR(ERROR_IO_PENDING)) {
-#ifdef WAIT_FOR_EVENT
- rv = WaitForSingleObject(overlapped.hEvent,
- (DWORD)(sock->timeout >= 0
- ? sock->timeout : INFINITE));
-#else
- rv = WaitForSingleObject((HANDLE) sock->sock,
- (DWORD)(sock->timeout >= 0
- ? sock->timeout : INFINITE));
-#endif
+ if (overlapped.hEvent)
+ rv = WaitForSingleObject(overlapped.hEvent,
+ (DWORD)(sock->timeout >= 0
+ ? sock->timeout : INFINITE));
+ else
+ rv = WaitForSingleObject((HANDLE) sock->sock,
+ (DWORD)(sock->timeout >= 0
+ ? sock->timeout : INFINITE));
if (rv == WAIT_OBJECT_0)
status = APR_SUCCESS;
else if (rv == WAIT_TIMEOUT)
@@ -376,7 +379,8 @@
}
#ifdef WAIT_FOR_EVENT
- CloseHandle(overlapped.hEvent);
+ if (!file->pOverlapped || !file->pOverlapped->hEvent)
+ CloseHandle(overlapped.hEvent);
#endif
return status;
}