| 550 | |
| 551 | |
| 552 | Future<Nothing> accept(const int_fd& fd, const int_fd& accepted_socket) |
| 553 | { |
| 554 | process::initialize(); |
| 555 | |
| 556 | Promise<Nothing>* promise = new Promise<Nothing>(); |
| 557 | Future<Nothing> future = promise->future(); |
| 558 | |
| 559 | // We use a `std::shared_ptr`, so we can safely support canceling. |
| 560 | auto overlapped = std::make_shared<IOOverlappedAccept>( |
| 561 | IOOverlappedBase{OVERLAPPED{}, fd, IOType::ACCEPT}, promise); |
| 562 | |
| 563 | enable_cancellation(fd, future, overlapped); |
| 564 | |
| 565 | // The `overlapped->buf` passed into `::AcceptEx` will receive the first |
| 566 | // data block sent, the local address of the server and the remote address |
| 567 | // of the client. The (4th, 5th, 6th) arguments are |
| 568 | // (0, sizeof(buf)/2 , sizeof(buf) / 2), since we ignore the first block, |
| 569 | // and simply store the local and remote addresses. For more details, see |
| 570 | // https://msdn.microsoft.com/en-us/library/windows/desktop/ms737524(v=vs.85).aspx // NOLINT(whitespace/line_length) |
| 571 | DWORD bytes; |
| 572 | const BOOL success = ::AcceptEx( |
| 573 | fd, |
| 574 | accepted_socket, |
| 575 | overlapped->buf, |
| 576 | 0, |
| 577 | sizeof(overlapped->buf) / 2, |
| 578 | sizeof(overlapped->buf) / 2, |
| 579 | &bytes, |
| 580 | &overlapped->base.overlapped); |
| 581 | |
| 582 | const DWORD error = ::WSAGetLastError(); |
| 583 | |
| 584 | // If the request is pending, then we return immediately and have the |
| 585 | // callback free the promise and overlapped |
| 586 | if (!success && error == WSA_IO_PENDING) { |
| 587 | return future; |
| 588 | } |
| 589 | |
| 590 | // In an error or immediate success, we have to manually set the promise |
| 591 | // and free it. |
| 592 | if (success) { |
| 593 | promise->set(Nothing()); |
| 594 | } else { |
| 595 | promise->fail("AcceptEx failed: " + WindowsError(error).message); |
| 596 | } |
| 597 | delete promise; |
| 598 | return future; |
| 599 | } |
| 600 | |
| 601 | // The MSDN docs state that `::ConnectEx` must be retrieved through |
| 602 | // `::WSAIoctl`. See the remarks section of the docs: |
no test coverage detected