Skip to content

Commit 5c96bbf

Browse files
committed
Avoid spawning thread for trivial getnameinfo calls
When calling getnameinfo we spawn a thread because it may do a slow, blocking reverse-DNS lookup. Spawning a thread is relatively fast (~20µs on my Linux machine) but still an order of magnitude slower than when getnameinfo is simply translating to a numeric IP or port, which, at least in my tests on Linux, doesn't even make a syscall. This commit adds a fast path for when reverse DNS isn't required: either host isn't being fetched or NI_NUMERICHOST is set AND either the service name isn't required or NI_NUMERICSERV is set. The service name should only need to read /etc/services, which should be fast-ish, but is still I/O so I kept the existing behaviour (it could be on a network fs I guess). I tested with: s = TCPSocket.open("www.ruby-lang.org", 80) 500_000.times { Socket.unpack_sockaddr_in(s.getpeername) } Before: 12.935s After: 0.338s
1 parent 9d484e3 commit 5c96bbf

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

ext/socket/raddrinfo.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,10 @@ rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hint
578578

579579
#endif
580580

581+
#define GETNAMEINFO_WONT_BLOCK(host, serv, flags) \
582+
((!(host) || ((flags) & NI_NUMERICHOST)) && \
583+
(!(serv) || ((flags) & NI_NUMERICSERV)))
584+
581585
#if GETADDRINFO_IMPL == 0
582586

583587
int
@@ -615,6 +619,10 @@ rb_getnameinfo(const struct sockaddr *sa, socklen_t salen,
615619
char *host, size_t hostlen,
616620
char *serv, size_t servlen, int flags)
617621
{
622+
if (GETNAMEINFO_WONT_BLOCK(host, serv, flags)) {
623+
return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
624+
}
625+
618626
struct getnameinfo_arg arg;
619627
int ret;
620628
arg.sa = sa;
@@ -743,6 +751,10 @@ rb_getnameinfo(const struct sockaddr *sa, socklen_t salen,
743751
struct getnameinfo_arg *arg;
744752
int err = 0, gni_errno = 0;
745753

754+
if (GETNAMEINFO_WONT_BLOCK(host, serv, flags)) {
755+
return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
756+
}
757+
746758
start:
747759
retry = 0;
748760

0 commit comments

Comments
 (0)