diff --git a/gloo/transport/tcp/attr.h b/gloo/transport/tcp/attr.h index ca302c5d7..21b91f6d3 100644 --- a/gloo/transport/tcp/attr.h +++ b/gloo/transport/tcp/attr.h @@ -11,11 +11,30 @@ #include #include +#include +#include namespace gloo { namespace transport { namespace tcp { +// RAII for fds so they'll close when all references to them are freed. +class FDHolder { + public: + explicit FDHolder(int fd) : fd_(fd) {} + ~FDHolder() { + close(fd_); + } + + FDHolder(const FDHolder&) = delete; + FDHolder& operator=(const FDHolder&) = delete; + FDHolder(FDHolder&&) = delete; + FDHolder& operator=(FDHolder&&) = delete; + + private: + const int fd_; +}; + struct attr { attr() {} /* implicit */ attr(const char* ptr) : hostname(ptr) {} @@ -31,6 +50,8 @@ struct attr { int ai_protocol; struct sockaddr_storage ai_addr; int ai_addrlen; + + std::shared_ptr fd{nullptr}; }; } // namespace tcp diff --git a/gloo/transport/tcp/device.cc b/gloo/transport/tcp/device.cc index becd0af30..a381ba331 100644 --- a/gloo/transport/tcp/device.cc +++ b/gloo/transport/tcp/device.cc @@ -117,7 +117,10 @@ static void lookupAddrForHostname(struct attr& attr) { attr.ai_protocol = rp->ai_protocol; memcpy(&attr.ai_addr, rp->ai_addr, rp->ai_addrlen); attr.ai_addrlen = rp->ai_addrlen; - close(fd); + + // We explicitly don't close this FD here as we want to hold on to it until + // the listener binds the server socket to the port. + attr.fd = std::make_shared(fd); break; }