Check that the call to epoll_ctl() succeeds, and if it does not, if
we're adding a new event and it fails with EEXIST, then delete and
re-add the event. There are a few cases where we may already have events
for a fd. If epoll_ctl() fails for any reason, use BUG_ON to make sure
we immediately crash, as this should not happen.
done:
ev.events &= ~epoll_mask;
ev.data.u64 = ((u64)fdtab[fd].generation << 32) + fd;
- epoll_ctl(epoll_fd[tid], opcode, fd, &ev);
+ if (epoll_ctl(epoll_fd[tid], opcode, fd, &ev) != 0) {
+ if (opcode == EPOLL_CTL_ADD && errno == EEXIST) {
+ BUG_ON(epoll_ctl(epoll_fd[tid], EPOLL_CTL_DEL, fd, &ev) != 0);
+ BUG_ON(epoll_ctl(epoll_fd[tid], EPOLL_CTL_ADD, fd, &ev) != 0);
+ } else {
+ BUG_ON(1, "epoll_ctl() failed when it should not");
+ }
+ }
}
/*