You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by an...@apache.org on 2018/05/23 21:36:50 UTC
[06/10] mesos git commit: Windows: Added async version of
`os::sendfile`.
Windows: Added async version of `os::sendfile`.
Split the original `os::sendfile` implementation into an asynchronous
`os::sendfile_async`function and a synchronous `os::sendfile`
function. The synchronous version simply calls the asynchronous
version and waits.
Review: https://reviews.apache.org/r/66960/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/20beb52a
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/20beb52a
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/20beb52a
Branch: refs/heads/master
Commit: 20beb52afa8b698f87013f5fd56adaf4c9e4f824
Parents: 028bb60
Author: Akash Gupta <ak...@hotmail.com>
Authored: Wed May 23 14:03:46 2018 -0700
Committer: Andrew Schwartzmeyer <an...@schwartzmeyer.com>
Committed: Wed May 23 14:07:47 2018 -0700
----------------------------------------------------------------------
.../stout/include/stout/os/windows/sendfile.hpp | 80 +++++++++++++++-----
1 file changed, 61 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/20beb52a/3rdparty/stout/include/stout/os/windows/sendfile.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/os/windows/sendfile.hpp b/3rdparty/stout/include/stout/os/windows/sendfile.hpp
index 594d9c7..2c08bb7 100644
--- a/3rdparty/stout/include/stout/os/windows/sendfile.hpp
+++ b/3rdparty/stout/include/stout/os/windows/sendfile.hpp
@@ -14,40 +14,82 @@
#define __STOUT_OS_WINDOWS_SENDFILE_HPP__
#include <stout/error.hpp>
+#include <stout/result.hpp>
#include <stout/try.hpp>
#include <stout/windows.hpp> // For `winioctl.h`.
+#include <stout/internal/windows/overlapped.hpp>
+
#include <stout/os/int_fd.hpp>
namespace os {
+inline Result<size_t> sendfile_async(
+ const int_fd& s, const int_fd& fd, size_t length, OVERLAPPED* overlapped)
+{
+ // `::TransmitFile` can only send `INT_MAX - 1` bytes.
+ CHECK_LE(length, INT_MAX - 1);
+
+ const BOOL result = ::TransmitFile(
+ s, // Sending socket.
+ fd, // File to be sent.
+ static_cast<DWORD>(length), // Number of bytes to be sent from the file.
+ 0, // Bytes per send. 0 chooses system default.
+ overlapped, // Overlapped object with file offset.
+ nullptr, // Data before and after file send.
+ 0); // Flags.
+
+ const WindowsError error;
+ if (result == FALSE &&
+ (error.code == WSA_IO_PENDING || error.code == ERROR_IO_PENDING)) {
+ return None();
+ }
+
+ if (result == FALSE) {
+ return error;
+ }
+
+ return length;
+}
+
// Returns the amount of bytes written from the input file
// descriptor to the output socket.
// On error, `Try<ssize_t, SocketError>` contains the error.
inline Try<ssize_t, SocketError> sendfile(
const int_fd& s, const int_fd& fd, off_t offset, size_t length)
{
+ if (offset < 0) {
+ return SocketError(WSAEINVAL);
+ }
+
// NOTE: We convert the `offset` here to avoid potential data loss
// in the type casting and bitshifting below.
- uint64_t offset_ = offset;
-
- OVERLAPPED from = {
- 0,
- 0,
- {static_cast<DWORD>(offset_), static_cast<DWORD>(offset_ >> 32)},
- nullptr};
-
- CHECK_LE(length, MAXDWORD);
- if (::TransmitFile(s, fd, static_cast<DWORD>(length), 0, &from, nullptr, 0) ==
- FALSE &&
- (::WSAGetLastError() == WSA_IO_PENDING ||
- ::WSAGetLastError() == ERROR_IO_PENDING)) {
- DWORD sent = 0;
- DWORD flags = 0;
-
- if (::WSAGetOverlappedResult(s, &from, &sent, TRUE, &flags) == TRUE) {
- return sent;
- }
+ const uint64_t offset_ = offset;
+
+ const Try<OVERLAPPED> from_ =
+ ::internal::windows::init_overlapped_for_sync_io();
+
+ if (from_.isError()) {
+ return SocketError(from_.error());
+ }
+
+ OVERLAPPED from = from_.get();
+ from.Offset = static_cast<DWORD>(offset_);
+ from.OffsetHigh = static_cast<DWORD>(offset_ >> 32);
+
+ const Result<size_t> result = sendfile_async(s, fd, length, &from);
+ if (result.isError()) {
+ return SocketError(result.error());
+ }
+
+ if (result.isSome()) {
+ return result.get();
+ }
+
+ DWORD sent = 0;
+ DWORD flags = 0;
+ if (::WSAGetOverlappedResult(s, &from, &sent, TRUE, &flags) == TRUE) {
+ return sent;
}
return SocketError();