summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES6
-rw-r--r--file_io/win32/open.c8
-rw-r--r--file_io/win32/readwrite.c28
3 files changed, 34 insertions, 8 deletions
diff --git a/CHANGES b/CHANGES
index f7a3dd1fe..5222599de 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,10 @@
Changes with APR b1
+ *) Win32: Fix APR_XTHREAD problems in apr_file_read()
+ and apr_file_write(). Multiple threads were using the
+ same overlapped structure and io event handle created
+ in the open call, which could cause unpredictable
+ file i/o results. [Bill Stoddard]
+
*) Win32: apr_proc_mutex_trylock and apr_proc_mutex_lock were
incorrectly returning APR_BUSY if the lock was previously
held by a thread that exited before releasing the lock
diff --git a/file_io/win32/open.c b/file_io/win32/open.c
index cf91d106c..6281a3d6e 100644
--- a/file_io/win32/open.c
+++ b/file_io/win32/open.c
@@ -392,14 +392,6 @@ APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new, const char *fname,
(*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;
(*new)->timeout = -1;
(*new)->ungetchar = -1;
diff --git a/file_io/win32/readwrite.c b/file_io/win32/readwrite.c
index d8c3c3fcf..0ee980466 100644
--- a/file_io/win32/readwrite.c
+++ b/file_io/win32/readwrite.c
@@ -168,6 +168,20 @@ APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size
return APR_SUCCESS;
}
+ /* If the file is open for xthread support, allocate and
+ * initialize the overlapped and io completion event (hEvent).
+ * Threads should NOT share an apr_file_t or its hEvent.
+ */
+ if ((thefile->flags & APR_XTHREAD) && !thefile->pOverlapped ) {
+ thefile->pOverlapped = (OVERLAPPED*) apr_pcalloc(thefile->cntxt,
+ sizeof(OVERLAPPED));
+ thefile->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (!thefile->pOverlapped->hEvent) {
+ rv = apr_get_os_error();
+ return rv;
+ }
+ }
+
/* Handle the ungetchar if there is one */
if (thefile->ungetchar != -1) {
bytes_read = 1;
@@ -239,6 +253,20 @@ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, a
apr_status_t rv;
DWORD bwrote;
+ /* If the file is open for xthread support, allocate and
+ * initialize the overlapped and io completion event (hEvent).
+ * Threads should NOT share an apr_file_t or its hEvent.
+ */
+ if ((thefile->flags & APR_XTHREAD) && !thefile->pOverlapped ) {
+ thefile->pOverlapped = (OVERLAPPED*) apr_pcalloc(thefile->cntxt,
+ sizeof(OVERLAPPED));
+ thefile->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (!thefile->pOverlapped->hEvent) {
+ rv = apr_get_os_error();
+ return rv;
+ }
+ }
+
if (thefile->buffered) {
char *pos = (char *)buf;
apr_size_t blocksize;