int picoev_update_events_internal(picoev_loop* _loop, int fd, int events) { picoev_loop_kqueue* loop = (picoev_loop_kqueue*)_loop; picoev_fd* target = picoev.fds + fd; assert(PICOEV_FD_BELONGS_TO_LOOP(&loop->loop, fd)); /* initialize if adding the fd */ if ((events & PICOEV_ADD) != 0) { target->_backend = -1; } /* return if nothing to do */ if (events == PICOEV_DEL ? target->_backend == -1 : (events & PICOEV_READWRITE) == target->events) { return 0; } /* add to changed list if not yet being done */ if (target->_backend == -1) { target->_backend = BACKEND_BUILD(loop->changed_fds, target->events); loop->changed_fds = fd; } /* update events */ target->events = events & PICOEV_READWRITE; /* apply immediately if is a DELETE */ if ((events & PICOEV_DEL) != 0) { apply_pending_changes(loop, 1); } return 0; }
int picoev_update_events_internal(picoev_loop* _loop, int fd, int events) { picoev_loop_epoll* loop = (picoev_loop_epoll*)_loop; picoev_fd* target = picoev.fds + fd; struct epoll_event ev; int epoll_ret; assert(PICOEV_FD_BELONGS_TO_LOOP(&loop->loop, fd)); if ((events & PICOEV_READWRITE) == target->events) return 0; ev.events = ((events & PICOEV_READ) != 0 ? EPOLLIN : 0) | ((events & PICOEV_WRITE) != 0 ? EPOLLOUT : 0); ev.data.fd = fd; #define SET(op, check_error) do { \ epoll_ret = epoll_ctl(loop->epfd, op, fd, &ev); \ assert(! check_error || epoll_ret == 0); \ } while (0) #if PICOEV_EPOLL_DEFER_DELETES if ((events & PICOEV_DEL) != 0) { /* nothing to do */ } else if ((events & PICOEV_READWRITE) == 0) { SET(EPOLL_CTL_DEL, 1); } else { SET(EPOLL_CTL_MOD, 0); if (epoll_ret != 0) { assert(errno == ENOENT); SET(EPOLL_CTL_ADD, 1); } } #else if ((events & PICOEV_READWRITE) == 0) SET(EPOLL_CTL_DEL, 1); else SET(target->events == 0 ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, 1); #endif #undef SET target->events = events; return 0; }