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:48 UTC
[04/10] mesos git commit: Windows: Added overlapped support to
`os::write`.
Windows: Added overlapped support to `os::write`.
Added overlapped handle support to `os::write`. Now, `os::write` will do
a blocking write no matter the handle type. Also, `os::write_async` will
do an overlapped write on an overlapped handle.
Review: https://reviews.apache.org/r/66956/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/bd4a8008
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/bd4a8008
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/bd4a8008
Branch: refs/heads/master
Commit: bd4a8008e0eb1a286e9c45a8ff6cf4cf1792ad6c
Parents: 5cdd29f
Author: Akash Gupta <ak...@hotmail.com>
Authored: Wed May 23 14:01:17 2018 -0700
Committer: Andrew Schwartzmeyer <an...@schwartzmeyer.com>
Committed: Wed May 23 14:01:17 2018 -0700
----------------------------------------------------------------------
.../stout/include/stout/os/windows/write.hpp | 92 ++++++++++++++++++--
1 file changed, 87 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/bd4a8008/3rdparty/stout/include/stout/os/windows/write.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/os/windows/write.hpp b/3rdparty/stout/include/stout/os/windows/write.hpp
index 295c031..232218e 100644
--- a/3rdparty/stout/include/stout/os/windows/write.hpp
+++ b/3rdparty/stout/include/stout/os/windows/write.hpp
@@ -18,23 +18,105 @@
#include <stout/unreachable.hpp>
#include <stout/windows.hpp>
+#include <stout/internal/windows/overlapped.hpp>
+
#include <stout/os/int_fd.hpp>
#include <stout/os/socket.hpp>
namespace os {
+// Asynchronous write on a overlapped int_fd. Returns `Error` on fatal errors,
+// `None()` on a successful pending IO operation or number of bytes written on
+// a successful IO operation that finished immediately.
+inline Result<size_t> write_async(
+ const int_fd& fd,
+ const void* data,
+ size_t size,
+ OVERLAPPED* overlapped)
+{
+ CHECK_LE(size, UINT_MAX);
+
+ switch (fd.type()) {
+ case WindowsFD::Type::HANDLE: {
+ DWORD bytes;
+ const bool success =
+ ::WriteFile(fd, data, static_cast<DWORD>(size), &bytes, overlapped);
+
+ return ::internal::windows::process_async_io_result(success, bytes);
+ }
+ case WindowsFD::Type::SOCKET: {
+ static_assert(
+ std::is_same<OVERLAPPED, WSAOVERLAPPED>::value,
+ "Expected `WSAOVERLAPPED` to be of type `OVERLAPPED`.");
+
+ // Note that it's okay to allocate this on the stack, since the WinSock
+ // providers must copy the WSABUF to their internal buffers. See
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms741688(v=vs.85).aspx // NOLINT(whitespace/line_length)
+ WSABUF buf = {
+ static_cast<u_long>(size),
+ static_cast<char*>(const_cast<void*>(data))
+ };
+
+ DWORD bytes;
+ const int result =
+ ::WSASend(fd, &buf, 1, &bytes, 0, overlapped, nullptr);
+
+ return ::internal::windows::process_async_io_result(result == 0, bytes);
+ }
+ }
+
+ UNREACHABLE();
+}
+
+
inline ssize_t write(const int_fd& fd, const void* data, size_t size)
{
CHECK_LE(size, INT_MAX);
switch (fd.type()) {
case WindowsFD::Type::HANDLE: {
+ // Handle non-overlapped case. We just use the regular `WriteFile` since
+ // seekable overlapped files require an offset, which we don't track.
+ if (!fd.is_overlapped()) {
+ DWORD bytes;
+ const BOOL result =
+ ::WriteFile(fd, data, static_cast<DWORD>(size), &bytes, nullptr);
+
+ if (result == FALSE) {
+ // Indicates an error, but we can't return a `WindowsError`.
+ return -1;
+ }
+
+ return static_cast<ssize_t>(bytes);
+ }
+
+ // Asynchronous handle, we can use the `write_async` function
+ // and then wait on the overlapped object for a synchronous write.
+ Try<OVERLAPPED> overlapped_ =
+ ::internal::windows::init_overlapped_for_sync_io();
+
+ if (overlapped_.isError()) {
+ return -1;
+ }
+
+ OVERLAPPED overlapped = overlapped_.get();
+ Result<size_t> result = write_async(fd, data, size, &overlapped);
+
+ if (result.isError()) {
+ return -1;
+ }
+
+ if (result.isSome()) {
+ return result.get();
+ }
+
+ // IO is pending, so wait for the overlapped object.
DWORD bytes;
- // TODO(andschwa): Handle overlapped I/O.
- const BOOL result =
- ::WriteFile(fd, data, static_cast<DWORD>(size), &bytes, nullptr);
- if (result == FALSE) {
- return -1; // Indicates an error, but we can't return a `WindowsError`.
+ const BOOL wait_success =
+ ::GetOverlappedResult(fd, &overlapped, &bytes, TRUE);
+
+ if (wait_success == FALSE) {
+ return -1;
}
return static_cast<ssize_t>(bytes);