Apache Mesos
overlapped.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_INTERNAL_WINDOWS_OVERLAPPED_HPP__
14 #define __STOUT_INTERNAL_WINDOWS_OVERLAPPED_HPP__
15 
16 #include <climits>
17 #include <type_traits>
18 
19 #include <stout/result.hpp>
20 #include <stout/windows.hpp>
21 
22 #include <stout/os/int_fd.hpp>
23 
24 namespace internal {
25 
26 namespace windows {
27 
28 // Helper function that creates an overlapped object that can be used
29 // safely for synchronous IO.
31 {
32  OVERLAPPED overlapped = {};
33 
34  // Creating the event is a defensive measure in the case where multiple
35  // simultaneous overlapped operations are happening on the same file.
36  // If there is no event, then any IO completion on the file can signal
37  // the overlapped object, instead of just the requested IO event.
38  // For more details, see
39  // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686358(v=vs.85).aspx // NOLINT(whitespace/line_length)
40  //
41  // The parameters to `::CreateEventW` will create a non-inheritable,
42  // auto-resetting, non-signaled, unamed event.
43  overlapped.hEvent = ::CreateEventW(nullptr, FALSE, FALSE, nullptr);
44  if (overlapped.hEvent == nullptr) {
45  return WindowsError();
46  }
47 
48  // According to the MSDN docs, "a valid event handle whose low-order bit
49  // is set keeps I/O completion from being queued to the completion port" [1].
50  // This is another defensive measure to prevent memory corruption if this
51  // function is called when the fd is associated with a completion port.
52  //
53  // [1] https://msdn.microsoft.com/en-us/library/windows/desktop/aa364986(v=vs.85).aspx // NOLINT(whitespace/line_length)
54  overlapped.hEvent = reinterpret_cast<HANDLE>(
55  reinterpret_cast<uintptr_t>(overlapped.hEvent) | 1);
56 
57  return overlapped;
58 }
59 
60 
61 // Windows uses a combination of the return code and the Win32 error code to
62 // determine that status of the overlapped IO functions (success, failure,
63 // pending). This function wraps that logic into a `Result` type so it's
64 // easier to process.
65 //
66 // This function returns:
67 // - `Some`: The number of bytes read/written if the async function had
68 // finished synchronously.
69 // - `Error`: The error code of the failed asynchronous function.
70 // - `None`: None if the asynchronous function was scheduled and is pending.
72  bool successful_return_code, size_t bytes_transfered)
73 {
74  // IO is already complete, so the result is already in `bytes_transfered`.
75  if (successful_return_code) {
76  return bytes_transfered;
77  }
78 
79  const WindowsError error;
80  if (error.code == ERROR_IO_PENDING) {
81  // IO is pending.
82  return None();
83  }
84 
85  // Other errors are fatal errors.
86  return error;
87 }
88 
89 } // namespace windows {
90 
91 } // namespace internal {
92 
93 #endif // __STOUT_INTERNAL_WINDOWS_OVERLAPPED_HPP__
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: error.hpp:108
Definition: check.hpp:30
const DWORD code
Definition: error.hpp:29
constexpr Handle HANDLE
Definition: ingress.hpp:37
Definition: none.hpp:27
Definition: attributes.hpp:24
std::string error(const std::string &msg, uint32_t code)