unix: only set SO_REUSEADDR when bind() fails
Only call setsockopt() when the initial bind() fails with EADDRINUSE, then retry. Saves a system call in what is normally the common case. PR-URL: https://github.com/libuv/libuv/pull/88 Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
parent
025602da13
commit
a9e95a33bc
@ -62,6 +62,7 @@ int uv__tcp_bind(uv_tcp_t* tcp,
|
||||
unsigned int flags) {
|
||||
int err;
|
||||
int on;
|
||||
int fd;
|
||||
|
||||
/* Cannot set IPv6-only mode on non-IPv6 socket. */
|
||||
if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6)
|
||||
@ -73,26 +74,29 @@ int uv__tcp_bind(uv_tcp_t* tcp,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
on = 1;
|
||||
if (setsockopt(tcp->io_watcher.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
|
||||
return -errno;
|
||||
fd = tcp->io_watcher.fd;
|
||||
|
||||
#ifdef IPV6_V6ONLY
|
||||
if (addr->sa_family == AF_INET6) {
|
||||
on = (flags & UV_TCP_IPV6ONLY) != 0;
|
||||
if (setsockopt(tcp->io_watcher.fd,
|
||||
IPPROTO_IPV6,
|
||||
IPV6_V6ONLY,
|
||||
&on,
|
||||
sizeof on) == -1) {
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)))
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
errno = 0;
|
||||
if (bind(tcp->io_watcher.fd, addr, addrlen) && errno != EADDRINUSE)
|
||||
return -errno;
|
||||
if (bind(fd, addr, addrlen)) {
|
||||
if (errno != EADDRINUSE)
|
||||
return -errno;
|
||||
|
||||
on = 1;
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
|
||||
return -errno;
|
||||
|
||||
errno = 0;
|
||||
if (bind(fd, addr, addrlen) && errno != EADDRINUSE)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
tcp->delayed_error = -errno;
|
||||
|
||||
if (addr->sa_family == AF_INET6)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user