From 1655933373f92909206074b7f6932bd6cc0d5056 Mon Sep 17 00:00:00 2001 From: Loo Rong Jie Date: Wed, 29 Aug 2018 07:02:45 -0700 Subject: [PATCH] [singlejar] Use Win32 API directly in OutputJar::AppendFile `pread` is only used by `OutputJar::AppendFile`. Implementing `OutputJar::AppendFile` directly with Win32 API means better performance and no worry about whether `pread` polyfill follows POSIX spec correctly. Also remove unused `pread` polyfill. See #2241 Closes #6021. PiperOrigin-RevId: 210714886 --- src/tools/singlejar/output_jar.cc | 27 ++++++++++++++++++++++++++- src/tools/singlejar/port.cc | 28 ++-------------------------- src/tools/singlejar/port.h | 4 ---- 3 files changed, 28 insertions(+), 31 deletions(-) diff --git a/src/tools/singlejar/output_jar.cc b/src/tools/singlejar/output_jar.cc index 923894698d860c..52a80de256575d 100644 --- a/src/tools/singlejar/output_jar.cc +++ b/src/tools/singlejar/output_jar.cc @@ -26,7 +26,14 @@ #ifndef _WIN32 #include -#endif +#else + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif // WIN32_LEAN_AND_MEAN +#include + +#endif // _WIN32 #include "src/tools/singlejar/combiners.h" #include "src/tools/singlejar/diag.h" @@ -911,6 +918,23 @@ ssize_t OutputJar::AppendFile(int in_fd, off64_t offset, size_t count) { } ssize_t total_written = 0; +#ifdef _WIN32 + HANDLE hFile = reinterpret_cast(_get_osfhandle(in_fd)); + while (static_cast(total_written) < count) { + ssize_t len = std::min(kBufferSize, count - total_written); + DWORD n_read; + if (!::ReadFile(hFile, buffer.get(), len, &n_read, NULL)) { + return -1; + } + if (n_read == 0) { + break; + } + if (!WriteBytes(buffer.get(), n_read)) { + return -1; + } + total_written += n_read; + } +#else while (static_cast(total_written) < count) { size_t len = std::min(kBufferSize, count - total_written); ssize_t n_read = pread(in_fd, buffer.get(), len, offset + total_written); @@ -925,6 +949,7 @@ ssize_t OutputJar::AppendFile(int in_fd, off64_t offset, size_t count) { return -1; } } +#endif // _WIN32 return total_written; } diff --git a/src/tools/singlejar/port.cc b/src/tools/singlejar/port.cc index 3b096784a0d8df..3d091344c6f94b 100644 --- a/src/tools/singlejar/port.cc +++ b/src/tools/singlejar/port.cc @@ -12,29 +12,5 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifdef _WIN32 - -#include "src/tools/singlejar/port.h" - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif // WIN32_LEAN_AND_MEAN -#include - -ssize_t pread(int fd, void *buf, size_t count, off64_t offset) { - DWORD ret = -1; - HANDLE hFile = reinterpret_cast(_get_osfhandle(fd)); - if (hFile) { - OVERLAPPED overlap; - memset(&overlap, 0, sizeof(OVERLAPPED)); - overlap.Offset = offset; - if (!::ReadFile(hFile, buf, count, &ret, &overlap)) { - // For this simple implementation, we don't update errno. - // Just return -1 as error. - return -1; - } - } - return ret; -} - -#endif // _WIN32 +// TODO(rongjiecomputer) Remove this file if it is still unused when the +// porting work completes. diff --git a/src/tools/singlejar/port.h b/src/tools/singlejar/port.h index 5e017397fabd85..a8ba46c505c86e 100644 --- a/src/tools/singlejar/port.h +++ b/src/tools/singlejar/port.h @@ -59,10 +59,6 @@ inline tm* localtime_r(const time_t* tin, tm* tout) { return nullptr; } -// Make sure that the file HANDLE associated with |fd| is created by CreateFile -// with FILE_FLAG_OVERLAPPED flag for this function to work. -ssize_t pread(int fd, void* buf, size_t count, off64_t offset); - #endif // _WIN32 #endif // BAZEL_SRC_TOOLS_SINGLEJAR_PORT_H_