diff --git a/port/win/env_win.cc b/port/win/env_win.cc index 1da35c2698c..4dcfad54033 100644 --- a/port/win/env_win.cc +++ b/port/win/env_win.cc @@ -1227,13 +1227,13 @@ IOStatus WinFileSystem::Poll(std::vector& io_handles, } } + win_handle->is_finished = true; + win_handle->cb(req, win_handle->cb_arg); + if (win_handle->overlapped.hEvent != NULL) { CloseHandle(win_handle->overlapped.hEvent); win_handle->overlapped.hEvent = NULL; } - - win_handle->is_finished = true; - win_handle->cb(req, win_handle->cb_arg); } return IOStatus::OK(); } @@ -1245,6 +1245,12 @@ IOStatus WinFileSystem::AbortIO(std::vector& io_handles) { continue; } + if (win_handle->overlapped.hEvent == NULL) { + return IOStatus::InvalidArgument( + "AbortIO: Overlapped event is NULL for: " + + win_handle->file_data->GetName()); + } + if (FALSE == CancelIoEx(win_handle->file_data->GetFileHandle(), &win_handle->overlapped)) { auto err = GetLastError(); @@ -1254,17 +1260,27 @@ IOStatus WinFileSystem::AbortIO(std::vector& io_handles) { return IOErrorFromWindowsError( "CancelIoEx failed: " + win_handle->file_data->GetName(), err); } - } - - if (win_handle->overlapped.hEvent != NULL) { - CloseHandle(win_handle->overlapped.hEvent); - win_handle->overlapped.hEvent = NULL; + } else { + // CancelIoEx succeeded + // Wait for the operation to complete + DWORD bytes_read = 0; + if (!GetOverlappedResult(win_handle->file_data->GetFileHandle(), + &win_handle->overlapped, &bytes_read, TRUE)) { + if (GetLastError() != ERROR_OPERATION_ABORTED) { + return IOErrorFromWindowsError( + "AbortIO failed: " + win_handle->file_data->GetName(), + GetLastError()); + } + } } win_handle->is_finished = true; FSReadRequest req; req.status = IOStatus::Aborted(); win_handle->cb(req, win_handle->cb_arg); + + CloseHandle(win_handle->overlapped.hEvent); + win_handle->overlapped.hEvent = NULL; } return IOStatus::OK(); } diff --git a/port/win/io_win.cc b/port/win/io_win.cc index 039b43b3f76..79a03e0a60c 100644 --- a/port/win/io_win.cc +++ b/port/win/io_win.cc @@ -1015,6 +1015,11 @@ IOStatus WinRandomAccessFileAsyncIo::ReadAsync( file_base_->GetName()); } + HANDLE h_event = RX_CreateEvent(NULL, TRUE, FALSE, NULL); + if (h_event == NULL) { + return IOErrorFromWindowsError("CreateEvent failed", GetLastError()); + } + IOHandleDeleter deletefn = [](void* args) -> void { delete (static_cast(args)); args = nullptr; @@ -1022,28 +1027,18 @@ IOStatus WinRandomAccessFileAsyncIo::ReadAsync( Win_IOHandle* win_handle = new Win_IOHandle(cb, cb_arg, req.offset, req.len, req.scratch, file_base_); - - win_handle->overlapped.hEvent = RX_CreateEvent(NULL, TRUE, FALSE, NULL); - if (win_handle->overlapped.hEvent == NULL) { - return IOErrorFromWindowsError("CreateEvent failed", GetLastError()); - } + win_handle->overlapped.hEvent = h_event; *io_handle = static_cast(win_handle); *del_fn = deletefn; IOStatus ios = IOStatus::OK(); DWORD bytes_read = 0; - bool close_handle = true; if (FALSE == ReadFile(file_base_->GetFileHandle(), req.scratch, static_cast(req.len), &bytes_read, &win_handle->overlapped)) { DWORD last_error = GetLastError(); - // Too many outstanding asynchronous I/O requests - if (last_error == ERROR_NOT_ENOUGH_MEMORY) { - CancelIoEx(file_base_->GetFileHandle(), &win_handle->overlapped); - ios = IOErrorFromWindowsError("ReadFile failed: " + file_base_->GetName(), - last_error); - } else if (last_error == ERROR_HANDLE_EOF) { + if (last_error == ERROR_HANDLE_EOF) { win_handle->is_finished = true; req.result = Slice(req.scratch, 0); req.status = IOStatus::OK(); @@ -1051,10 +1046,8 @@ IOStatus WinRandomAccessFileAsyncIo::ReadAsync( } else if (last_error != ERROR_IO_PENDING) { ios = IOErrorFromWindowsError("ReadFile failed: " + file_base_->GetName(), last_error); - } else { - close_handle = false; } - + // else last_error is ERROR_IO_PENDING } else { win_handle->is_finished = true; req.result = Slice(req.scratch, bytes_read); @@ -1062,7 +1055,7 @@ IOStatus WinRandomAccessFileAsyncIo::ReadAsync( cb(req, cb_arg); } - if (close_handle && win_handle->overlapped.hEvent != NULL) { + if (win_handle->is_finished && win_handle->overlapped.hEvent != NULL) { CloseHandle(win_handle->overlapped.hEvent); win_handle->overlapped.hEvent = NULL; }