mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-11 07:19:59 -04:00
3860. [bug] ioctl(DP_POLL) array size needs to be determined
at run time as it is limited to {OPEN_MAX}.
[RT #35878]
(cherry picked from commit a569e1b321)
This commit is contained in:
parent
a4b09947f6
commit
8fd8dd56fe
2 changed files with 87 additions and 25 deletions
4
CHANGES
4
CHANGES
|
|
@ -1,3 +1,7 @@
|
|||
3860. [bug] ioctl(DP_POLL) array size needs to be determined
|
||||
at run time as it is limited to {OPEN_MAX}.
|
||||
[RT #35878]
|
||||
|
||||
3858. [bug] Disable GCC 4.9 "delete null pointer check".
|
||||
[RT #35968]
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
#include <isc/platform.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/region.h>
|
||||
#include <isc/resource.h>
|
||||
#include <isc/socket.h>
|
||||
#include <isc/stats.h>
|
||||
#include <isc/strerror.h>
|
||||
|
|
@ -402,6 +403,8 @@ struct isc__socketmgr {
|
|||
#endif /* USE_EPOLL */
|
||||
#ifdef USE_DEVPOLL
|
||||
int devpoll_fd;
|
||||
isc_resourcevalue_t open_max;
|
||||
unsigned int calls;
|
||||
int nevents;
|
||||
struct pollfd *events;
|
||||
#endif /* USE_DEVPOLL */
|
||||
|
|
@ -1168,8 +1171,6 @@ select_readmsg(isc__socketmgr_t *mgr, int *fd, int *msg) {
|
|||
"read() failed "
|
||||
"during watcher poke: %s"),
|
||||
strbuf);
|
||||
|
||||
return;
|
||||
}
|
||||
INSIST(cc == sizeof(buf));
|
||||
|
||||
|
|
@ -4098,8 +4099,10 @@ watcher(void *uap) {
|
|||
#elif defined (USE_EPOLL)
|
||||
const char *fnname = "epoll_wait()";
|
||||
#elif defined(USE_DEVPOLL)
|
||||
isc_result_t result;
|
||||
const char *fnname = "ioctl(DP_POLL)";
|
||||
struct dvpoll dvp;
|
||||
int pass;
|
||||
#elif defined (USE_SELECT)
|
||||
const char *fnname = "select()";
|
||||
int maxfd;
|
||||
|
|
@ -4126,17 +4129,45 @@ watcher(void *uap) {
|
|||
cc = epoll_wait(manager->epoll_fd, manager->events,
|
||||
manager->nevents, -1);
|
||||
#elif defined(USE_DEVPOLL)
|
||||
dvp.dp_fds = manager->events;
|
||||
dvp.dp_nfds = manager->nevents;
|
||||
/*
|
||||
* Re-probe every thousand calls.
|
||||
*/
|
||||
if (manager->calls++ > 1000U) {
|
||||
result = isc_resource_getcurlimit(
|
||||
isc_resource_openfiles,
|
||||
&manager->open_max);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
manager->open_max = 64;
|
||||
manager->calls == 0;
|
||||
}
|
||||
for (pass = 0; pass < 2; pass++) {
|
||||
dvp.dp_fds = manager->events;
|
||||
dvp.dp_nfds = manager->nevents;
|
||||
if (dvp.dp_nfds >= manager->open_max)
|
||||
dvp.dp_nfds = manager->open_max - 1;
|
||||
#ifndef ISC_SOCKET_USE_POLLWATCH
|
||||
dvp.dp_timeout = -1;
|
||||
#else
|
||||
if (pollstate == poll_idle)
|
||||
dvp.dp_timeout = -1;
|
||||
else
|
||||
dvp.dp_timeout = ISC_SOCKET_POLLWATCH_TIMEOUT;
|
||||
#else
|
||||
if (pollstate == poll_idle)
|
||||
dvp.dp_timeout = -1;
|
||||
else
|
||||
dvp.dp_timeout =
|
||||
ISC_SOCKET_POLLWATCH_TIMEOUT;
|
||||
#endif /* ISC_SOCKET_USE_POLLWATCH */
|
||||
cc = ioctl(manager->devpoll_fd, DP_POLL, &dvp);
|
||||
cc = ioctl(manager->devpoll_fd, DP_POLL, &dvp);
|
||||
if (cc == -1 && errno == EINVAL) {
|
||||
/*
|
||||
* {OPEN_MAX} may have dropped. Look
|
||||
* up the current value and try again.
|
||||
*/
|
||||
result = isc_resource_getcurlimit(
|
||||
isc_resource_openfiles,
|
||||
&manager->open_max);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
manager->open_max = 64;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
#elif defined(USE_SELECT)
|
||||
LOCK(&manager->lock);
|
||||
memmove(manager->read_fds_copy, manager->read_fds,
|
||||
|
|
@ -4296,11 +4327,12 @@ setup_watcher(isc_mem_t *mctx, isc__socketmgr_t *manager) {
|
|||
}
|
||||
#endif /* USE_WATCHER_THREAD */
|
||||
#elif defined(USE_DEVPOLL)
|
||||
/*
|
||||
* XXXJT: /dev/poll seems to reject large numbers of events,
|
||||
* so we should be careful about redefining ISC_SOCKET_MAXEVENTS.
|
||||
*/
|
||||
manager->nevents = ISC_SOCKET_MAXEVENTS;
|
||||
result = isc_resource_getcurlimit(isc_resource_openfiles,
|
||||
&manager->open_max);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
manager->open_max = 64;
|
||||
manager->calls = 0;
|
||||
manager->events = isc_mem_get(mctx, sizeof(struct pollfd) *
|
||||
manager->nevents);
|
||||
if (manager->events == NULL)
|
||||
|
|
@ -6149,8 +6181,6 @@ isc__socketmgr_waitevents(isc_socketmgr_t *manager0, struct timeval *tvp,
|
|||
isc_socketwait_t **swaitp)
|
||||
{
|
||||
isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
|
||||
|
||||
|
||||
int n;
|
||||
#ifdef USE_KQUEUE
|
||||
struct timespec ts, *tsp;
|
||||
|
|
@ -6159,6 +6189,8 @@ isc__socketmgr_waitevents(isc_socketmgr_t *manager0, struct timeval *tvp,
|
|||
int timeout;
|
||||
#endif
|
||||
#ifdef USE_DEVPOLL
|
||||
isc_result_t result;
|
||||
int pass;
|
||||
struct dvpoll dvp;
|
||||
#endif
|
||||
|
||||
|
|
@ -6192,15 +6224,41 @@ isc__socketmgr_waitevents(isc_socketmgr_t *manager0, struct timeval *tvp,
|
|||
manager->nevents, timeout);
|
||||
n = swait_private.nevents;
|
||||
#elif defined(USE_DEVPOLL)
|
||||
dvp.dp_fds = manager->events;
|
||||
dvp.dp_nfds = manager->nevents;
|
||||
if (tvp != NULL) {
|
||||
dvp.dp_timeout = tvp->tv_sec * 1000 +
|
||||
(tvp->tv_usec + 999) / 1000;
|
||||
} else
|
||||
dvp.dp_timeout = -1;
|
||||
swait_private.nevents = ioctl(manager->devpoll_fd, DP_POLL, &dvp);
|
||||
n = swait_private.nevents;
|
||||
/*
|
||||
* Re-probe every thousand calls.
|
||||
*/
|
||||
if (manager->calls++ > 1000U) {
|
||||
result = isc_resource_getcurlimit(isc_resource_openfiles,
|
||||
&manager->open_max);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
manager->open_max = 64;
|
||||
manager->calls == 0;
|
||||
}
|
||||
for (pass = 0; pass < 2; pass++) {
|
||||
dvp.dp_fds = manager->events;
|
||||
dvp.dp_nfds = manager->nevents;
|
||||
if (dvp.dp_nfds >= manager->open_max)
|
||||
dvp.dp_nfds = manager->open_max - 1;
|
||||
if (tvp != NULL) {
|
||||
dvp.dp_timeout = tvp->tv_sec * 1000 +
|
||||
(tvp->tv_usec + 999) / 1000;
|
||||
} else
|
||||
dvp.dp_timeout = -1;
|
||||
n = ioctl(manager->devpoll_fd, DP_POLL, &dvp);
|
||||
if (n == -1 && errno == EINVAL) {
|
||||
/*
|
||||
* {OPEN_MAX} may have dropped. Look
|
||||
* up the current value and try again.
|
||||
*/
|
||||
result = isc_resource_getcurlimit(
|
||||
isc_resource_openfiles,
|
||||
&manager->open_max);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
manager->open_max = 64;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
swait_private.nevents = n;
|
||||
#elif defined(USE_SELECT)
|
||||
memmove(manager->read_fds_copy, manager->read_fds, manager->fd_bufsize);
|
||||
memmove(manager->write_fds_copy, manager->write_fds,
|
||||
|
|
|
|||
Loading…
Reference in a new issue