Apache Mesos
write.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 #ifndef __STOUT_OS_WINDOWS_WRITE_HPP__
14 #define __STOUT_OS_WINDOWS_WRITE_HPP__
15 
16 #include <stout/nothing.hpp>
17 #include <stout/try.hpp>
18 #include <stout/unreachable.hpp>
19 #include <stout/windows.hpp>
20 
22 
23 #include <stout/os/int_fd.hpp>
24 #include <stout/os/socket.hpp>
25 
26 namespace os {
27 
28 // Asynchronous write on a overlapped int_fd. Returns `Error` on fatal errors,
29 // `None()` on a successful pending IO operation or number of bytes written on
30 // a successful IO operation that finished immediately.
32  const int_fd& fd,
33  const void* data,
34  size_t size,
35  OVERLAPPED* overlapped)
36 {
37  CHECK_LE(size, UINT_MAX);
38 
39  switch (fd.type()) {
41  DWORD bytes;
42  const bool success =
43  ::WriteFile(fd, data, static_cast<DWORD>(size), &bytes, overlapped);
44 
46  }
48  static_assert(
49  std::is_same<OVERLAPPED, WSAOVERLAPPED>::value,
50  "Expected `WSAOVERLAPPED` to be of type `OVERLAPPED`.");
51 
52  // Note that it's okay to allocate this on the stack, since the WinSock
53  // providers must copy the WSABUF to their internal buffers. See
54  // https://msdn.microsoft.com/en-us/library/windows/desktop/ms741688(v=vs.85).aspx // NOLINT(whitespace/line_length)
55  WSABUF buf = {
56  static_cast<u_long>(size),
57  static_cast<char*>(const_cast<void*>(data))
58  };
59 
60  DWORD bytes;
61  const int result =
62  ::WSASend(fd, &buf, 1, &bytes, 0, overlapped, nullptr);
63 
65  }
66  }
67 
68  UNREACHABLE();
69 }
70 
71 
72 inline ssize_t write(const int_fd& fd, const void* data, size_t size)
73 {
74  CHECK_LE(size, INT_MAX);
75 
76  switch (fd.type()) {
78  // Handle non-overlapped case. We just use the regular `WriteFile` since
79  // seekable overlapped files require an offset, which we don't track.
80  if (!fd.is_overlapped()) {
81  DWORD bytes;
82  const BOOL result =
83  ::WriteFile(fd, data, static_cast<DWORD>(size), &bytes, nullptr);
84 
85  if (result == FALSE) {
86  // Indicates an error, but we can't return a `WindowsError`.
87  return -1;
88  }
89 
90  return static_cast<ssize_t>(bytes);
91  }
92 
93  // Asynchronous handle, we can use the `write_async` function
94  // and then wait on the overlapped object for a synchronous write.
95  Try<OVERLAPPED> overlapped_ =
97 
98  if (overlapped_.isError()) {
99  return -1;
100  }
101 
102  OVERLAPPED overlapped = overlapped_.get();
103  Result<size_t> result = write_async(fd, data, size, &overlapped);
104 
105  if (result.isError()) {
106  return -1;
107  }
108 
109  if (result.isSome()) {
110  return result.get();
111  }
112 
113  // IO is pending, so wait for the overlapped object.
114  DWORD bytes;
115  const BOOL wait_success =
116  ::GetOverlappedResult(fd, &overlapped, &bytes, TRUE);
117 
118  if (wait_success == FALSE) {
119  return -1;
120  }
121 
122  return static_cast<ssize_t>(bytes);
123  }
125  return ::send(fd, (const char*)data, static_cast<int>(size), 0);
126  }
127  }
128 
129  UNREACHABLE();
130 }
131 
132 } // namespace os {
133 
134 
135 #endif // __STOUT_OS_WINDOWS_WRITE_HPP__
SSIZE_T ssize_t
Definition: windows.hpp:186
Try< Bytes > size(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:130
T & get()&
Definition: try.hpp:80
ssize_t write(const int_fd &fd, const void *data, size_t size)
Definition: write.hpp:72
Definition: check.hpp:33
Try< OVERLAPPED > init_overlapped_for_sync_io()
Definition: overlapped.hpp:30
Result< size_t > process_async_io_result(bool successful_return_code, size_t bytes_transfered)
Definition: overlapped.hpp:71
Definition: posix_signalhandler.hpp:23
Definition: check.hpp:30
Result< size_t > write_async(const int_fd &fd, const void *data, size_t size, OVERLAPPED *overlapped)
Definition: write.hpp:31
#define UNREACHABLE()
Definition: unreachable.hpp:22
bool isError() const
Definition: try.hpp:78
T & get()&
Definition: result.hpp:116
bool isSome() const
Definition: result.hpp:112
bool isError() const
Definition: result.hpp:114
int int_fd
Definition: int_fd.hpp:35
Future< size_t > send(const int_fd &fd, const void *buf, size_t size)