mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
Speed up DNS by avoiding a system call if possible
This commit is contained in:
@ -1,5 +1,8 @@
|
|||||||
2012-03-30 Ulrich Drepper <drepper@gmail.com>
|
2012-03-30 Ulrich Drepper <drepper@gmail.com>
|
||||||
|
|
||||||
|
* resolv/res_send.c (send_dg): Use sendmmsg if we have to write two
|
||||||
|
requests to save a system call.
|
||||||
|
|
||||||
* sysdeps/unix/sysv/linux/bits/socket.h (struct mmsghdr): Fix up
|
* sysdeps/unix/sysv/linux/bits/socket.h (struct mmsghdr): Fix up
|
||||||
comments for sendmmsg.
|
comments for sendmmsg.
|
||||||
|
|
||||||
|
@ -1013,8 +1013,9 @@ send_dg(res_state statp,
|
|||||||
seconds /= statp->nscount;
|
seconds /= statp->nscount;
|
||||||
if (seconds <= 0)
|
if (seconds <= 0)
|
||||||
seconds = 1;
|
seconds = 1;
|
||||||
bool single_request = (statp->options & RES_SNGLKUP) != 0;
|
|
||||||
bool single_request_reopen = (statp->options & RES_SNGLKUPREOP) != 0;
|
bool single_request_reopen = (statp->options & RES_SNGLKUPREOP) != 0;
|
||||||
|
bool single_request = (((statp->options & RES_SNGLKUP) != 0)
|
||||||
|
| single_request_reopen);
|
||||||
int save_gotsomewhere = *gotsomewhere;
|
int save_gotsomewhere = *gotsomewhere;
|
||||||
|
|
||||||
int retval;
|
int retval;
|
||||||
@ -1100,24 +1101,89 @@ send_dg(res_state statp,
|
|||||||
}
|
}
|
||||||
__set_errno (0);
|
__set_errno (0);
|
||||||
if (pfd[0].revents & POLLOUT) {
|
if (pfd[0].revents & POLLOUT) {
|
||||||
ssize_t sr;
|
#ifndef __ASSUME_SENDMMSG
|
||||||
if (nwritten != 0)
|
static int have_sendmmsg;
|
||||||
sr = send (pfd[0].fd, buf2, buflen2, MSG_NOSIGNAL);
|
#else
|
||||||
else
|
# define have_sendmmsg 1
|
||||||
sr = send (pfd[0].fd, buf, buflen, MSG_NOSIGNAL);
|
#endif
|
||||||
|
if (have_sendmmsg >= 0 && nwritten == 0 && buf2 != NULL
|
||||||
|
&& !single_request)
|
||||||
|
{
|
||||||
|
struct iovec iov[2];
|
||||||
|
struct mmsghdr reqs[2];
|
||||||
|
reqs[0].msg_hdr.msg_name = NULL;
|
||||||
|
reqs[0].msg_hdr.msg_namelen = 0;
|
||||||
|
reqs[0].msg_hdr.msg_iov = &iov[0];
|
||||||
|
reqs[0].msg_hdr.msg_iovlen = 1;
|
||||||
|
iov[0].iov_base = (void *) buf;
|
||||||
|
iov[0].iov_len = buflen;
|
||||||
|
reqs[0].msg_hdr.msg_control = NULL;
|
||||||
|
reqs[0].msg_hdr.msg_controllen = 0;
|
||||||
|
|
||||||
if (sr != buflen) {
|
reqs[1].msg_hdr.msg_name = NULL;
|
||||||
if (errno == EINTR || errno == EAGAIN)
|
reqs[1].msg_hdr.msg_namelen = 0;
|
||||||
goto recompute_resend;
|
reqs[1].msg_hdr.msg_iov = &iov[1];
|
||||||
Perror(statp, stderr, "send", errno);
|
reqs[1].msg_hdr.msg_iovlen = 1;
|
||||||
|
iov[1].iov_base = (void *) buf2;
|
||||||
|
iov[1].iov_len = buflen2;
|
||||||
|
reqs[1].msg_hdr.msg_control = NULL;
|
||||||
|
reqs[1].msg_hdr.msg_controllen = 0;
|
||||||
|
|
||||||
|
int ndg = sendmmsg (pfd[0].fd, reqs, 2, MSG_NOSIGNAL);
|
||||||
|
if (__builtin_expect (ndg == 2, 1))
|
||||||
|
{
|
||||||
|
assert (reqs[0].msg_len == buflen);
|
||||||
|
assert (reqs[1].msg_len == buflen2);
|
||||||
|
|
||||||
|
pfd[0].events = POLLIN;
|
||||||
|
nwritten += 2;
|
||||||
|
}
|
||||||
|
else if (ndg == 1 && reqs[0].msg_len == buflen)
|
||||||
|
goto just_one;
|
||||||
|
else if (errno == EINTR || errno == EAGAIN)
|
||||||
|
goto recompute_resend;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifndef __ASSUME_SENDMMSG
|
||||||
|
if (have_sendmmsg == 0)
|
||||||
|
{
|
||||||
|
if (errno == ENOSYS)
|
||||||
|
{
|
||||||
|
have_sendmmsg = -1;
|
||||||
|
goto try_send;
|
||||||
|
}
|
||||||
|
have_sendmmsg = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Perror(statp, stderr, "sendmmsg", errno);
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
if (nwritten != 0 || buf2 == NULL
|
}
|
||||||
|| single_request || single_request_reopen)
|
|
||||||
pfd[0].events = POLLIN;
|
|
||||||
else
|
else
|
||||||
pfd[0].events = POLLIN | POLLOUT;
|
{
|
||||||
++nwritten;
|
ssize_t sr;
|
||||||
|
#ifndef __ASSUME_SENDMMSG
|
||||||
|
try_send:
|
||||||
|
#endif
|
||||||
|
if (nwritten != 0)
|
||||||
|
sr = send (pfd[0].fd, buf2, buflen2, MSG_NOSIGNAL);
|
||||||
|
else
|
||||||
|
sr = send (pfd[0].fd, buf, buflen, MSG_NOSIGNAL);
|
||||||
|
|
||||||
|
if (sr != buflen) {
|
||||||
|
if (errno == EINTR || errno == EAGAIN)
|
||||||
|
goto recompute_resend;
|
||||||
|
Perror(statp, stderr, "send", errno);
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
just_one:
|
||||||
|
if (nwritten != 0 || buf2 == NULL || single_request)
|
||||||
|
pfd[0].events = POLLIN;
|
||||||
|
else
|
||||||
|
pfd[0].events = POLLIN | POLLOUT;
|
||||||
|
++nwritten;
|
||||||
|
}
|
||||||
goto wait;
|
goto wait;
|
||||||
} else if (pfd[0].revents & POLLIN) {
|
} else if (pfd[0].revents & POLLIN) {
|
||||||
int *thisanssizp;
|
int *thisanssizp;
|
||||||
@ -1327,7 +1393,7 @@ send_dg(res_state statp,
|
|||||||
recvresp2 = 1;
|
recvresp2 = 1;
|
||||||
/* Repeat waiting if we have a second answer to arrive. */
|
/* Repeat waiting if we have a second answer to arrive. */
|
||||||
if ((recvresp1 & recvresp2) == 0) {
|
if ((recvresp1 & recvresp2) == 0) {
|
||||||
if (single_request || single_request_reopen) {
|
if (single_request) {
|
||||||
pfd[0].events = POLLOUT;
|
pfd[0].events = POLLOUT;
|
||||||
if (single_request_reopen) {
|
if (single_request_reopen) {
|
||||||
__res_iclose (statp, false);
|
__res_iclose (statp, false);
|
||||||
|
Reference in New Issue
Block a user