/* Locked by fdlock. */
isc__socket_t **fds;
int *fdstate;
+#if defined(USE_EPOLL)
+ uint32_t *epoll_events;
+#endif
#ifdef USE_DEVPOLL
pollinfo_t *fdpollinfo;
#endif
return (result);
#elif defined(USE_EPOLL)
struct epoll_event event;
+ uint32_t oldevents;
+ int ret;
+ int op;
+ oldevents = manager->epoll_events[fd];
if (msg == SELECT_POKE_READ)
- event.events = EPOLLIN;
+ manager->epoll_events[fd] |= EPOLLIN;
else
- event.events = EPOLLOUT;
+ manager->epoll_events[fd] |= EPOLLOUT;
+
+ event.events = manager->epoll_events[fd];
memset(&event.data, 0, sizeof(event.data));
event.data.fd = fd;
- if (epoll_ctl(manager->epoll_fd, EPOLL_CTL_ADD, fd, &event) == -1 &&
- errno != EEXIST) {
+
+ op = (oldevents == 0U) ? EPOLL_CTL_ADD : EPOLL_CTL_MOD;
+ ret = epoll_ctl(manager->epoll_fd, op, fd, &event);
+ if (ret == -1) {
+ if (errno == EEXIST)
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "epoll_ctl(ADD/MOD) returned "
+ "EEXIST for fd %d", fd);
result = isc__errno2result(errno);
}
return (result);
#elif defined(USE_EPOLL)
struct epoll_event event;
+ int ret;
+ int op;
if (msg == SELECT_POKE_READ)
- event.events = EPOLLIN;
+ manager->epoll_events[fd] &= ~(EPOLLIN);
else
- event.events = EPOLLOUT;
+ manager->epoll_events[fd] &= ~(EPOLLOUT);
+
+ event.events = manager->epoll_events[fd];
memset(&event.data, 0, sizeof(event.data));
event.data.fd = fd;
- if (epoll_ctl(manager->epoll_fd, EPOLL_CTL_DEL, fd, &event) == -1 &&
- errno != ENOENT) {
+
+ op = (event.events == 0U) ? EPOLL_CTL_DEL : EPOLL_CTL_MOD;
+ ret = epoll_ctl(manager->epoll_fd, op, fd, &event);
+ if (ret == -1 && errno != ENOENT) {
char strbuf[ISC_STRERRORSIZE];
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
LOCK(&manager->fdlock[lockid]);
manager->fds[sock->fd] = sock;
manager->fdstate[sock->fd] = MANAGED;
+#if defined(USE_EPOLL)
+ manager->epoll_events[sock->fd] = 0;
+#endif
#ifdef USE_DEVPOLL
INSIST(sock->manager->fdpollinfo[sock->fd].want_read == 0 &&
sock->manager->fdpollinfo[sock->fd].want_write == 0);
LOCK(&sock->manager->fdlock[lockid]);
sock->manager->fds[sock->fd] = sock;
sock->manager->fdstate[sock->fd] = MANAGED;
+#if defined(USE_EPOLL)
+ sock->manager->epoll_events[sock->fd] = 0;
+#endif
#ifdef USE_DEVPOLL
INSIST(sock->manager->fdpollinfo[sock->fd].want_read == 0 &&
sock->manager->fdpollinfo[sock->fd].want_write == 0);
LOCK(&manager->fdlock[lockid]);
manager->fds[sock->fd] = sock;
manager->fdstate[sock->fd] = MANAGED;
+#if defined(USE_EPOLL)
+ manager->epoll_events[sock->fd] = 0;
+#endif
UNLOCK(&manager->fdlock[lockid]);
LOCK(&manager->lock);
LOCK(&manager->fdlock[lockid]);
manager->fds[fd] = NEWCONNSOCK(dev);
manager->fdstate[fd] = MANAGED;
+#if defined(USE_EPOLL)
+ manager->epoll_events[fd] = 0;
+#endif
UNLOCK(&manager->fdlock[lockid]);
LOCK(&manager->lock);
result = ISC_R_NOMEMORY;
goto free_manager;
}
+#if defined(USE_EPOLL)
+ manager->epoll_events = isc_mem_get(mctx, (manager->maxsocks *
+ sizeof(uint32_t)));
+ if (manager->epoll_events == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto free_manager;
+ }
+ memset(manager->epoll_events, 0, manager->maxsocks * sizeof(uint32_t));
+#endif
manager->stats = NULL;
manager->common.methods = &socketmgrmethods;
result = setup_watcher(mctx, manager);
if (result != ISC_R_SUCCESS)
goto cleanup;
+
memset(manager->fdstate, 0, manager->maxsocks * sizeof(int));
+
#ifdef USE_WATCHER_THREAD
/*
* Start up the select/poll thread.
isc_mem_put(mctx, manager->fdlock,
FDLOCK_COUNT * sizeof(isc_mutex_t));
}
+#if defined(USE_EPOLL)
+ if (manager->epoll_events != NULL) {
+ isc_mem_put(mctx, manager->epoll_events,
+ manager->maxsocks * sizeof(uint32_t));
+ }
+#endif
if (manager->fdstate != NULL) {
isc_mem_put(mctx, manager->fdstate,
manager->maxsocks * sizeof(int));
if (manager->fdstate[i] == CLOSE_PENDING) /* no need to lock */
(void)close(i);
+#if defined(USE_EPOLL)
+ isc_mem_put(manager->mctx, manager->epoll_events,
+ manager->maxsocks * sizeof(uint32_t));
+#endif
isc_mem_put(manager->mctx, manager->fds,
manager->maxsocks * sizeof(isc__socket_t *));
isc_mem_put(manager->mctx, manager->fdstate,