summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/socket/raddrinfo.c29
-rw-r--r--ext/socket/rubysocket.h4
-rw-r--r--ext/socket/socket.c7
3 files changed, 23 insertions, 17 deletions
diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c
index 079f66dddc..b601b1b297 100644
--- a/ext/socket/raddrinfo.c
+++ b/ext/socket/raddrinfo.c
@@ -369,15 +369,16 @@ rb_getaddrinfo_a(const char *node, const char *service,
arg.timeout = timeout;
ret = (int)(VALUE)rb_thread_call_without_gvl(nogvl_gai_suspend, &arg, RUBY_UBF_IO, 0);
+ if (ret && ret != EAI_ALLDONE) {
+ /* EAI_ALLDONE indicates that the request already completed and gai_suspend was redundant */
+ /* on Ubuntu 18.04 (or other systems), gai_suspend(3) returns EAI_SYSTEM/ENOENT on timeout */
+ if (ret == EAI_SYSTEM && errno == ENOENT) {
+ return EAI_AGAIN;
+ } else {
+ return ret;
+ }
+ }
- if (ret) {
- /* on Ubuntu 18.04 (or other systems), gai_suspend(3) returns EAI_SYSTEM/ENOENT on timeout */
- if (ret == EAI_SYSTEM && errno == ENOENT) {
- return EAI_AGAIN;
- } else {
- return ret;
- }
- }
ret = gai_error(reqs[0]);
ai = reqs[0]->ar_result;
@@ -601,7 +602,7 @@ rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_h
}
#ifdef HAVE_GETADDRINFO_A
-static struct rb_addrinfo*
+struct rb_addrinfo*
rsock_getaddrinfo_a(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack, VALUE timeout)
{
struct rb_addrinfo* res = NULL;
@@ -619,10 +620,10 @@ rsock_getaddrinfo_a(VALUE host, VALUE port, struct addrinfo *hints, int socktype
hints->ai_flags |= additional_flags;
if (NIL_P(timeout)) {
- error = rb_getaddrinfo(hostp, portp, hints, &res);
+ error = rb_getaddrinfo_a(hostp, portp, hints, &res, (struct timespec *)NULL);
} else {
- struct timespec _timeout = rb_time_timespec_interval(timeout);
- error = rb_getaddrinfo_a(hostp, portp, hints, &res, &_timeout);
+ struct timespec _timeout = rb_time_timespec_interval(timeout);
+ error = rb_getaddrinfo_a(hostp, portp, hints, &res, &_timeout);
}
if (error) {
@@ -942,11 +943,7 @@ call_getaddrinfo(VALUE node, VALUE service,
}
#ifdef HAVE_GETADDRINFO_A
- if (NIL_P(timeout)) {
- res = rsock_getaddrinfo(node, service, &hints, socktype_hack);
- } else {
res = rsock_getaddrinfo_a(node, service, &hints, socktype_hack, timeout);
- }
#else
res = rsock_getaddrinfo(node, service, &hints, socktype_hack);
#endif
diff --git a/ext/socket/rubysocket.h b/ext/socket/rubysocket.h
index fcea2a5a05..30b7a7777a 100644
--- a/ext/socket/rubysocket.h
+++ b/ext/socket/rubysocket.h
@@ -320,6 +320,10 @@ int rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_
int rsock_fd_family(int fd);
struct rb_addrinfo *rsock_addrinfo(VALUE host, VALUE port, int family, int socktype, int flags);
struct rb_addrinfo *rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack);
+#ifdef HAVE_GETADDRINFO_A
+struct rb_addrinfo *rsock_getaddrinfo_a(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack, VALUE timeout);
+#endif
+
VALUE rsock_fd_socket_addrinfo(int fd, struct sockaddr *addr, socklen_t len);
VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len);
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index e4504620fb..3212467863 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -1181,7 +1181,12 @@ sock_s_getaddrinfo(int argc, VALUE *argv, VALUE _)
if (NIL_P(revlookup) || !rsock_revlookup_flag(revlookup, &norevlookup)) {
norevlookup = rsock_do_not_reverse_lookup;
}
- res = rsock_getaddrinfo(host, port, &hints, 0);
+
+ #ifdef HAVE_GETADDRINFO_A
+ res = rsock_getaddrinfo_a(host, port, &hints, 0, Qnil);
+ #else
+ res = rsock_getaddrinfo(host, port, &hints, 0);
+ #endif
ret = make_addrinfo(res, norevlookup);
rb_freeaddrinfo(res);