| 49 | |
| 50 | |
| 51 | Future<std::shared_ptr<SocketImpl>> PollSocketImpl::accept() |
| 52 | { |
| 53 | // Need to hold a copy of `this` so that we can detect if the underlying |
| 54 | // socket has changed (i.e. closed) before we return from `io::poll`. |
| 55 | std::weak_ptr<SocketImpl> weak_self(shared(this)); |
| 56 | |
| 57 | Try<Address> address = network::address(get()); |
| 58 | if (address.isError()) { |
| 59 | return Failure("Failed to get address: " + address.error()); |
| 60 | } |
| 61 | |
| 62 | int family = 0; |
| 63 | if (address->family() == Address::Family::INET4) { |
| 64 | family = AF_INET; |
| 65 | } else if (address->family() == Address::Family::INET6) { |
| 66 | family = AF_INET6; |
| 67 | } else { |
| 68 | return Failure("Unsupported address family. Windows only supports IP."); |
| 69 | } |
| 70 | |
| 71 | Try<int_fd> accept_socket_ = net::socket(family, SOCK_STREAM, 0); |
| 72 | if (accept_socket_.isError()) { |
| 73 | return Failure(accept_socket_.error()); |
| 74 | } |
| 75 | |
| 76 | int_fd accept_socket = accept_socket_.get(); |
| 77 | |
| 78 | return windows::accept(get(), accept_socket) |
| 79 | .onAny([accept_socket](const Future<Nothing> future) { |
| 80 | if (!future.isReady()) { |
| 81 | os::close(accept_socket); |
| 82 | } |
| 83 | }) |
| 84 | .then([weak_self, accept_socket]() -> Future<std::shared_ptr<SocketImpl>> { |
| 85 | std::shared_ptr<SocketImpl> self(weak_self.lock()); |
| 86 | if (self == nullptr) { |
| 87 | return Failure("Socket destroyed while accepting"); |
| 88 | } |
| 89 | |
| 90 | SOCKET listen = self->get(); |
| 91 | |
| 92 | // Inherit from the listening socket. |
| 93 | int res = ::setsockopt( |
| 94 | accept_socket, |
| 95 | SOL_SOCKET, |
| 96 | SO_UPDATE_ACCEPT_CONTEXT, |
| 97 | reinterpret_cast<char*>(&listen), |
| 98 | sizeof(listen)); |
| 99 | |
| 100 | if (res != 0) { |
| 101 | const WindowsError error; |
| 102 | os::close(accept_socket); |
| 103 | return Failure("Failed to set accepted socket: " + error.message); |
| 104 | } |
| 105 | |
| 106 | // Disable Nagle algorithm, since we care about latency more than |
| 107 | // throughput. See https://en.wikipedia.org/wiki/Nagle%27s_algorithm |
| 108 | // for more info. |
nothing calls this directly
no test coverage detected