Skip to content

Commit 3199766

Browse files
authored
UBF is also required for synchronous name resolution (ruby#12156)
`rb_thread_call_without_gvl2` is used to wait for the results of name resolution and connection attempts. When there is only one address family to resolve, the necessary resources were not being passed to the UBF. With this change, the handling of resources has been revised and organized to work consistently, whether there are two address families to resolve or only one.
1 parent 8d575e4 commit 3199766

File tree

1 file changed

+29
-25
lines changed

1 file changed

+29
-25
lines changed

ext/socket/ipsocket.c

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,31 @@ init_fast_fallback_inetsock_internal(VALUE v)
593593
arg->connection_attempt_fds = allocate_connection_attempt_fds(additional_capacity);
594594
arg->connection_attempt_fds_size = 0;
595595

596+
if (pipe(pipefd) != 0) rb_syserr_fail(errno, "pipe(2)");
597+
hostname_resolution_waiter = pipefd[0];
598+
int waiter_flags = fcntl(hostname_resolution_waiter, F_GETFL, 0);
599+
if (waiter_flags < 0) rb_syserr_fail(errno, "fcntl(2)");
600+
if ((fcntl(hostname_resolution_waiter, F_SETFL, waiter_flags | O_NONBLOCK)) < 0) {
601+
rb_syserr_fail(errno, "fcntl(2)");
602+
}
603+
604+
hostname_resolution_notifier = pipefd[1];
605+
wait_arg.readfds = &readfds;
606+
607+
arg->getaddrinfo_shared = allocate_fast_fallback_getaddrinfo_shared();
608+
if (!arg->getaddrinfo_shared) rb_syserr_fail(errno, "calloc(3)");
609+
610+
arg->getaddrinfo_shared->lock = calloc(1, sizeof(rb_nativethread_lock_t));
611+
if (!arg->getaddrinfo_shared->lock) rb_syserr_fail(errno, "calloc(3)");
612+
rb_nativethread_lock_initialize(arg->getaddrinfo_shared->lock);
613+
614+
arg->getaddrinfo_shared->notify = hostname_resolution_notifier;
615+
arg->getaddrinfo_shared->wait = hostname_resolution_waiter;
616+
arg->getaddrinfo_shared->connection_attempt_fds = arg->connection_attempt_fds;
617+
arg->getaddrinfo_shared->connection_attempt_fds_size = arg->connection_attempt_fds_size;
618+
arg->getaddrinfo_shared->cancelled = false;
619+
wait_arg.cancelled = false;
620+
596621
struct timeval resolution_delay_storage;
597622
struct timeval *resolution_delay_expires_at = NULL;
598623
struct timeval connection_attempt_delay_strage;
@@ -605,6 +630,10 @@ init_fast_fallback_inetsock_internal(VALUE v)
605630

606631
/* start of hostname resolution */
607632
if (arg->family_size == 1) {
633+
arg->getaddrinfo_shared->node = NULL;
634+
arg->getaddrinfo_shared->service = NULL;
635+
arg->getaddrinfo_shared->refcount = 1;
636+
608637
int family = arg->families[0];
609638
arg->remote.res = rsock_addrinfo(
610639
arg->remote.host,
@@ -624,35 +653,10 @@ init_fast_fallback_inetsock_internal(VALUE v)
624653
resolution_store.v6.finished = true;
625654
}
626655
resolution_store.is_all_finised = true;
627-
wait_arg.readfds = NULL;
628656
} else {
629-
if (pipe(pipefd) != 0) rb_syserr_fail(errno, "pipe(2)");
630-
hostname_resolution_waiter = pipefd[0];
631-
int waiter_flags = fcntl(hostname_resolution_waiter, F_GETFL, 0);
632-
if (waiter_flags < 0) rb_syserr_fail(errno, "fcntl(2)");
633-
if ((fcntl(hostname_resolution_waiter, F_SETFL, waiter_flags | O_NONBLOCK)) < 0) {
634-
rb_syserr_fail(errno, "fcntl(2)");
635-
}
636-
637-
hostname_resolution_notifier = pipefd[1];
638-
wait_arg.readfds = &readfds;
639-
640-
arg->getaddrinfo_shared = allocate_fast_fallback_getaddrinfo_shared();
641-
if (!arg->getaddrinfo_shared) rb_syserr_fail(errno, "calloc(3)");
642-
643-
arg->getaddrinfo_shared->lock = calloc(1, sizeof(rb_nativethread_lock_t));
644-
if (!arg->getaddrinfo_shared->lock) rb_syserr_fail(errno, "calloc(3)");
645-
rb_nativethread_lock_initialize(arg->getaddrinfo_shared->lock);
646-
647657
arg->getaddrinfo_shared->node = arg->hostp ? strdup(arg->hostp) : NULL;
648658
arg->getaddrinfo_shared->service = strdup(arg->portp);
649659
arg->getaddrinfo_shared->refcount = arg->family_size + 1;
650-
arg->getaddrinfo_shared->notify = hostname_resolution_notifier;
651-
arg->getaddrinfo_shared->wait = hostname_resolution_waiter;
652-
arg->getaddrinfo_shared->connection_attempt_fds = arg->connection_attempt_fds;
653-
arg->getaddrinfo_shared->connection_attempt_fds_size = arg->connection_attempt_fds_size;
654-
arg->getaddrinfo_shared->cancelled = false;
655-
wait_arg.cancelled = false;
656660

657661
for (int i = 0; i < arg->family_size; i++) {
658662
arg->getaddrinfo_entries[i] = allocate_fast_fallback_getaddrinfo_entry();

0 commit comments

Comments
 (0)