… | |
… | |
88 | ev.data.u64 = (uint64_t)(uint32_t)fd |
88 | ev.data.u64 = (uint64_t)(uint32_t)fd |
89 | | ((uint64_t)(uint32_t)++anfds [fd].egen << 32); |
89 | | ((uint64_t)(uint32_t)++anfds [fd].egen << 32); |
90 | ev.events = (nev & EV_READ ? EPOLLIN : 0) |
90 | ev.events = (nev & EV_READ ? EPOLLIN : 0) |
91 | | (nev & EV_WRITE ? EPOLLOUT : 0); |
91 | | (nev & EV_WRITE ? EPOLLOUT : 0); |
92 | |
92 | |
93 | if (expect_true (!epoll_ctl (backend_fd, oev ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, fd, &ev))) |
93 | if (expect_true (!epoll_ctl (backend_fd, oev && oldmask != nev ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, fd, &ev))) |
94 | return; |
94 | return; |
95 | |
95 | |
96 | if (expect_true (errno == ENOENT)) |
96 | if (expect_true (errno == ENOENT)) |
97 | { |
97 | { |
98 | /* if ENOENT then the fd went away, so try to do the right thing */ |
98 | /* if ENOENT then the fd went away, so try to do the right thing */ |
… | |
… | |
148 | int want = anfds [fd].events; |
148 | int want = anfds [fd].events; |
149 | int got = (ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0) |
149 | int got = (ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0) |
150 | | (ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0); |
150 | | (ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0); |
151 | |
151 | |
152 | /* check for spurious notification */ |
152 | /* check for spurious notification */ |
|
|
153 | /* we assume that fd is always in range, as we never shrink the anfds array */ |
153 | if (expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32))) |
154 | if (expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32))) |
154 | { |
155 | { |
155 | /* recreate kernel state */ |
156 | /* recreate kernel state */ |
156 | postfork = 1; |
157 | postfork = 1; |
157 | continue; |
158 | continue; |
… | |
… | |
168 | |
169 | |
169 | /* pre-2.6.9 kernels require a non-null pointer with EPOLL_CTL_DEL, */ |
170 | /* pre-2.6.9 kernels require a non-null pointer with EPOLL_CTL_DEL, */ |
170 | /* which is fortunately easy to do for us. */ |
171 | /* which is fortunately easy to do for us. */ |
171 | if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev)) |
172 | if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev)) |
172 | { |
173 | { |
173 | postfork = 1; /* an error occured, recreate kernel state */ |
174 | postfork = 1; /* an error occurred, recreate kernel state */ |
174 | continue; |
175 | continue; |
175 | } |
176 | } |
176 | } |
177 | } |
177 | |
178 | |
178 | fd_event (EV_A_ fd, got); |
179 | fd_event (EV_A_ fd, got); |