Future<std::shared_ptr<SocketImpl>> PollSocketImpl::accept() { // Need to hold a copy of `this` so that the underlying socket // doesn't end up getting reused before we return from the call to // `io::poll` and end up accepting a socket incorrectly. auto self = shared(this); Try<Address> address = network::address(get()); if (address.isError()) { return Failure("Failed to get address: " + address.error()); } int family = 0; if (address->family() == Address::Family::INET4) { family = AF_INET; } else if (address->family() == Address::Family::INET6) { family = AF_INET6; } else { return Failure("Unsupported address family. Windows only supports IP."); } Try<int_fd> accept_socket_ = net::socket(family, SOCK_STREAM, 0); if (accept_socket_.isError()) { return Failure(accept_socket_.error()); } int_fd accept_socket = accept_socket_.get(); return windows::accept(self->get(), accept_socket) .onAny([accept_socket](const Future<Nothing> future) { if (!future.isReady()) { os::close(accept_socket); } }) .then([self, accept_socket]() -> Future<std::shared_ptr<SocketImpl>> { SOCKET listen = self->get(); // Inherit from the listening socket. int res = ::setsockopt( accept_socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, reinterpret_cast<char*>(&listen), sizeof(listen)); if (res != 0) { const WindowsError error; os::close(accept_socket); return Failure("Failed to set accepted socket: " + error.message); } // Disable Nagle algorithm, since we care about latency more than // throughput. See https://en.wikipedia.org/wiki/Nagle%27s_algorithm // for more info. const int on = 1; res = ::setsockopt( accept_socket, SOL_TCP, TCP_NODELAY, reinterpret_cast<const char*>(&on), sizeof(on)); if (res != 0) { const WindowsError error; os::close(accept_socket); return Failure( "Failed to turn off the Nagle algorithm: " + error.message); } Try<Nothing> error = io::prepare_async(accept_socket); if (error.isError()) { os::close(accept_socket); return Failure( "Failed to set socket for asynchronous IO: " + error.error()); } Try<std::shared_ptr<SocketImpl>> impl = create(accept_socket); if (impl.isError()) { os::close(accept_socket); return Failure("Failed to create socket: " + impl.error()); } return impl.get(); }); }