From 9d484e3412750580c85a6950a8304d8ad0b4d8d5 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Wed, 20 Aug 2025 10:57:47 -0400 Subject: [PATCH 1/2] Fix indentation in clear_method_cache_by_id_in_class [ci skip] --- vm_method.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm_method.c b/vm_method.c index c1793c102c4b8a..722daf0a6a902c 100644 --- a/vm_method.c +++ b/vm_method.c @@ -510,7 +510,7 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) } rb_gccct_clear_table(Qnil); -} + } } static void From 5c96bbf36a73e29561b2b1a0e42c6f3341a4e542 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Tue, 19 Aug 2025 19:13:00 -0700 Subject: [PATCH 2/2] Avoid spawning thread for trivial getnameinfo calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- ext/socket/raddrinfo.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c index bc6c303c36b628..ca00e51ee72fa3 100644 --- a/ext/socket/raddrinfo.c +++ b/ext/socket/raddrinfo.c @@ -578,6 +578,10 @@ rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hint #endif +#define GETNAMEINFO_WONT_BLOCK(host, serv, flags) \ + ((!(host) || ((flags) & NI_NUMERICHOST)) && \ + (!(serv) || ((flags) & NI_NUMERICSERV))) + #if GETADDRINFO_IMPL == 0 int @@ -615,6 +619,10 @@ rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { + if (GETNAMEINFO_WONT_BLOCK(host, serv, flags)) { + return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); + } + struct getnameinfo_arg arg; int ret; arg.sa = sa; @@ -743,6 +751,10 @@ rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, struct getnameinfo_arg *arg; int err = 0, gni_errno = 0; + if (GETNAMEINFO_WONT_BLOCK(host, serv, flags)) { + return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); + } + start: retry = 0;