I have a strange behavior Mojo::IOLoop::Client while connect to localhost when it resolves in two addresses.
$ host localhost
localhost has address 127.0.0.1
localhost has IPv6 address ::1
$
When using EV via select or poll or Mojo::Reactor::Poll all is ok. But when using EV via epoll I get the error "connect timeout".
$ LIBEV_FLAGS=2 strace perl -MMojo::IOLoop -le 'Mojo::IOLoop->client({address => "localhost", port => 27017}, sub { my ($l, $err, $stream) = @_; warn $err; Mojo::IOLoop->stop }); Mojo::IOLoop->start'
socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP) = 3
...
connect(3, {sa_family=AF_INET6, sin6_port=htons(27017), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EINPROGRESS (Operation now in progress)
fcntl(3, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK)
poll([{fd=5, events=POLLIN}, {fd=3, events=POLLOUT}], 2, 9996) = 1 ([{fd=3, revents=POLLOUT|POLLERR|POLLHUP}])
getsockopt(3, SOL_SOCKET, SO_ERROR, [111], [4]) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 4
...
dup2(4, 3) = 3
close(4) = 0
fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(27017), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
poll([{fd=5, events=POLLIN}, {fd=3, events=POLLOUT}], 2, 9996) = 1 ([{fd=3, revents=POLLOUT}])
getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(27017), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
getpeername(3, {sa_family=AF_INET, sin_port=htons(27017), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0
...
$ LIBEV_FLAGS=4 strace perl -MMojo::IOLoop -le 'Mojo::IOLoop->client({address => "localhost", port => 27017}, sub { my ($l, $err, $stream) = @_; warn $err if $err; Mojo::IOLoop->stop }); Mojo::IOLoop->start'
socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP) = 3
...
connect(3, {sa_family=AF_INET6, sin6_port=htons(27017), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EINPROGRESS (Operation now in progress)
fcntl(3, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK)
epoll_ctl(5, EPOLL_CTL_ADD, 3, {EPOLLOUT, {u32=3, u64=4294967299}}) = 0
epoll_wait(5, {{EPOLLOUT|EPOLLERR|EPOLLHUP, {u32=3, u64=4294967299}}}, 64, 9996) = 1
epoll_ctl(5, EPOLL_CTL_MOD, 3, {EPOLLOUT, {u32=3, u64=4294967299}}) = 0
getsockopt(3, SOL_SOCKET, SO_ERROR, [111], [4]) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 4
...
dup2(4, 3) = 3
close(4) = 0
fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(27017), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
epoll_wait(5, {}, 64, 9995) = 0
write(2, "Connect timeout at -e line 1, <D"..., 48Connect timeout at -e line 1, <DATA> line 2231.
...
I see that the second time epoll_wait is not monitoring the descriptor(3) and therefore a connect event is missing.
Can you explain me this behavior?