Skip to content

Commit

Permalink
[singlejar] Use Win32 API directly in OutputJar::AppendFile
Browse files Browse the repository at this point in the history
`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 bazelbuild#2241

Closes bazelbuild#6021.

PiperOrigin-RevId: 210714886
  • Loading branch information
rongjiecomputer authored and Copybara-Service committed Aug 29, 2018
1 parent 8253721 commit 1655933
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 31 deletions.
27 changes: 26 additions & 1 deletion src/tools/singlejar/output_jar.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@

#ifndef _WIN32
#include <unistd.h>
#endif
#else

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif // WIN32_LEAN_AND_MEAN
#include <windows.h>

#endif // _WIN32

#include "src/tools/singlejar/combiners.h"
#include "src/tools/singlejar/diag.h"
Expand Down Expand Up @@ -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<HANDLE>(_get_osfhandle(in_fd));
while (static_cast<size_t>(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<size_t>(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);
Expand All @@ -925,6 +949,7 @@ ssize_t OutputJar::AppendFile(int in_fd, off64_t offset, size_t count) {
return -1;
}
}
#endif // _WIN32

return total_written;
}
Expand Down
28 changes: 2 additions & 26 deletions src/tools/singlejar/port.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 <windows.h>

ssize_t pread(int fd, void *buf, size_t count, off64_t offset) {
DWORD ret = -1;
HANDLE hFile = reinterpret_cast<HANDLE>(_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.
4 changes: 0 additions & 4 deletions src/tools/singlejar/port.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_

0 comments on commit 1655933

Please sign in to comment.