NOTE: The following functions use `int_fd` instead of the native Win32 `HANDLE`, because they are the more "public" libwinio APIs that interface directly with the libprocess IO, socket and event loop code.
| 399 | // `HANDLE`, because they are the more "public" libwinio APIs that interface |
| 400 | // directly with the libprocess IO, socket and event loop code. |
| 401 | Try<Nothing> EventLoop::registerHandle(const int_fd& fd) |
| 402 | { |
| 403 | Try<HANDLE> assigned_handle = fd.assign_iocp(iocp_handle_.get(), KEY_IO); |
| 404 | if (assigned_handle.isError()) { |
| 405 | return Error(assigned_handle.error()); |
| 406 | } |
| 407 | |
| 408 | // In this case, the IOCP handle was already assigned. So, we check if the |
| 409 | // right one is assigned. |
| 410 | if (assigned_handle.get() != nullptr) { |
| 411 | if (assigned_handle.get() != iocp_handle_.get()) { |
| 412 | return Error( |
| 413 | "fd is already registered to a different Windows Event Loop"); |
| 414 | } |
| 415 | return Nothing(); |
| 416 | } |
| 417 | |
| 418 | // This is the first time the handle was assigned. We continue the |
| 419 | // initialization. These are some optimizations that prevent IOCP |
| 420 | // notifications on success and event notifications, so that we have less |
| 421 | // context switches. |
| 422 | BOOL success = ::SetFileCompletionNotificationModes( |
| 423 | fd, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS | FILE_SKIP_SET_EVENT_ON_HANDLE); |
| 424 | |
| 425 | if (!success) { |
| 426 | return WindowsError(); |
| 427 | } |
| 428 | |
| 429 | return Nothing(); |
| 430 | } |
| 431 | |
| 432 | |
| 433 | template <typename T, typename O> |
no test coverage detected