diff options
-rw-r--r-- | CHANGES | 6 | ||||
-rw-r--r-- | file_io/win32/open.c | 8 | ||||
-rw-r--r-- | file_io/win32/readwrite.c | 28 |
3 files changed, 34 insertions, 8 deletions
@@ -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; |