From b54c34742412af0001a69c2f7d909bc05e1ea71f Mon Sep 17 00:00:00 2001 From: PraveenSinghRao Date: Fri, 22 Apr 2016 13:27:33 -0700 Subject: [PATCH] Use async file handle for better parallelism (#1049) --- port/win/env_win.cc | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/port/win/env_win.cc b/port/win/env_win.cc index f0825651b..7dcb5a6de 100644 --- a/port/win/env_win.cc +++ b/port/win/env_win.cc @@ -124,6 +124,8 @@ SSIZE_T pwrite(HANDLE hFile, const char* src, size_t numBytes, } // See comments for pwrite above +// PLEASE NOTE: hFile is expected to be an async handle +// (i.e. opened with FILE_FLAG_OVERLAPPED) SSIZE_T pread(HANDLE hFile, char* src, size_t numBytes, uint64_t offset) { assert(numBytes <= std::numeric_limits::max()); OVERLAPPED overlapped = {0}; @@ -132,18 +134,33 @@ SSIZE_T pread(HANDLE hFile, char* src, size_t numBytes, uint64_t offset) { overlapped.Offset = offsetUnion.LowPart; overlapped.OffsetHigh = offsetUnion.HighPart; + overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + if (NULL == overlapped.hEvent) { + return -1; + } SSIZE_T result = 0; unsigned long bytesRead = 0; + DWORD lastError = ERROR_SUCCESS; - if (FALSE == ReadFile(hFile, src, static_cast(numBytes), &bytesRead, - &overlapped)) { - return -1; + if ((FALSE == ReadFile(hFile, src, static_cast(numBytes), &bytesRead, + &overlapped)) && ((lastError = GetLastError()) != ERROR_IO_PENDING)) { + result = (lastError == ERROR_HANDLE_EOF) ? 0 : -1; } else { - result = bytesRead; + if (lastError == ERROR_IO_PENDING) { //otherwise bytesRead already has the result + if (FALSE == GetOverlappedResult(hFile, &overlapped, &bytesRead, TRUE)) { + result = (GetLastError() == ERROR_HANDLE_EOF) ? 0 : -1; + } + else { + result = bytesRead; + } + } } + CloseHandle(overlapped.hEvent); + return result; } @@ -684,6 +701,8 @@ class WinSequentialFile : public SequentialFile { // pread() based random-access class WinRandomAccessFile : public RandomAccessFile { const std::string filename_; + // PLEASE NOTE: hFile is expected to be an async handle + // (i.e. opened with FILE_FLAG_OVERLAPPED) HANDLE hFile_; const bool use_os_buffer_; bool read_ahead_; @@ -1225,6 +1244,12 @@ class WinEnv : public Env { fileFlags |= FILE_FLAG_RANDOM_ACCESS; } + if (!options.use_mmap_reads) { + // Open in async mode which makes Windows allow more parallelism even + // if we need to do sync I/O on top of it. + fileFlags |= FILE_FLAG_OVERLAPPED; + } + /// Shared access is necessary for corruption test to pass // almost all tests would work with a possible exception of fault_injection HANDLE hFile = 0;