summaryrefslogtreecommitdiff
path: root/file_io
diff options
context:
space:
mode:
Diffstat (limited to 'file_io')
-rw-r--r--file_io/win32/readwrite.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/file_io/win32/readwrite.c b/file_io/win32/readwrite.c
index 7e25b490d..310d7905a 100644
--- a/file_io/win32/readwrite.c
+++ b/file_io/win32/readwrite.c
@@ -80,14 +80,24 @@ static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t le
else {
rv = apr_get_os_error();
if (rv == APR_FROM_OS_ERROR(ERROR_IO_PENDING)) {
- /* Wait for the pending i/o, timeout converted from us to ms
- * Note that we loop if someone gives up the event.
- *
- * NOTE: We do not handle WAIT_ABANDONED here because they
- * can be returned only when waiting for mutex.
- */
- res = apr_wait_for_single_object(file->pOverlapped->hEvent,
- file->timeout);
+ /* It seems that ReadFile() return ERROR_IO_PENDING even
+ * when I/O operation completed syncronously.
+ * Use fast macro to check that overlapped I/O already
+ * completed to avoid kernel call.
+ */
+ if (HasOverlappedIoCompleted(file->pOverlapped)) {
+ res = WAIT_OBJECT_0;
+ }
+ else {
+ /* Wait for the pending i/o, timeout converted from us to ms
+ * Note that we loop if someone gives up the event.
+ *
+ * NOTE: We do not handle WAIT_ABANDONED here because they
+ * can be returned only when waiting for mutex.
+ */
+ res = apr_wait_for_single_object(file->pOverlapped->hEvent,
+ file->timeout);
+ }
/* There is one case that represents entirely
* successful operations, otherwise we will cancel
@@ -489,8 +499,18 @@ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, a
DWORD res;
- res = apr_wait_for_single_object(thefile->pOverlapped->hEvent,
- thefile->timeout);
+ /* It seems that WriteFile() return ERROR_IO_PENDING even
+ * when I/O operation completed syncronously.
+ * Use fast macro to check that overlapped I/O already
+ * completed to avoid kernel call.
+ */
+ if (HasOverlappedIoCompleted(thefile->pOverlapped)) {
+ res = WAIT_OBJECT_0;
+ }
+ else {
+ res = apr_wait_for_single_object(thefile->pOverlapped->hEvent,
+ thefile->timeout);
+ }
/* There is one case that represents entirely
* successful operations, otherwise we will cancel