in gloo/transport/uv/device.cc [361:414]
void Device::connectAsInitiator(
const Address& remote,
std::chrono::milliseconds timeout,
ConnectCallback fn) {
defer([=] {
auto tcp = loop_->resource<libuv::TCP>();
auto timer = loop_->resource<libuv::Timer>();
// Enable TCP_NODELAY, which disables Nagle's algorithm.
tcp->noDelay(true);
// Call callback with error if an error event fired.
// In nominal operation, this listener will NOT fire.
// It must be cleared upon success.
auto errorListener = tcp->once<libuv::ErrorEvent>(
[=](const libuv::ErrorEvent& event, libuv::TCP& handle) {
// If a request against this handle was canceled,
// it must have been due to the timeout firing.
// The timeout will call the callback with the
// UV_ETIMEDOUT status and close the handle.
if (event.code() != UV_ECANCELED) {
fn(nullptr, event);
handle.close();
timer->close();
}
});
// Write sequence number as soon as the connection is made.
// In nominal operation, this listener will fire at least once.
tcp->once<libuv::ConnectEvent>(
[remote](const libuv::ConnectEvent&, libuv::TCP& handle) {
handle.write(remote.getSeq());
});
// Call callback with success if the sequence number was written.
// In nominal operation, this listener will fire at least once.
tcp->once<libuv::WriteEvent>(
[=](const libuv::WriteEvent&, libuv::TCP& handle) {
handle.erase(errorListener);
timer->close();
fn(handle.shared_from_this(), libuv::ErrorEvent(0));
});
timer->once<libuv::TimerEvent>(
[=](const libuv::TimerEvent&, libuv::Timer& handle) {
fn(nullptr, libuv::ErrorEvent(ETIMEDOUT));
tcp->close();
handle.close();
});
timer->start(timeout);
tcp->connect((const sockaddr&)remote.getSockaddr());
});
}