static void fdw_poll_handle(void) { register unsigned i; int changed; t_fdwatch_fd *cfd; for(i = 0; i < nofds && sr; i++) { changed = 0; cfd = fdw_fds + _rridx[i]; if (fdw_rw(cfd) & fdwatch_type_read && fds[i].revents & (POLLIN | POLLERR | POLLHUP | POLLNVAL)) { if (fdw_hnd(cfd)(fdw_data(cfd), fdwatch_type_read) == -2) { sr--; continue; } changed = 1; } if (fdw_rw(cfd) & fdwatch_type_write && fds[i].revents & (POLLOUT | POLLERR | POLLHUP | POLLNVAL)) { fdw_hnd(cfd)(fdw_data(cfd), fdwatch_type_write); changed = 1; } if (changed) sr--; } }
static int fdw_select_cb(t_fdwatch_fd *cfd, void *data) { // eventlog(eventlog_level_trace, __FUNCTION__, "idx: %d fd: %d", idx, fdw_fd->fd); if (fdw_rw(cfd) & fdwatch_type_read && PSOCK_FD_ISSET(fdw_fd(cfd), rfds) && fdw_hnd(cfd)(fdw_data(cfd), fdwatch_type_read) == -2) return 0; if (fdw_rw(cfd) & fdwatch_type_write && PSOCK_FD_ISSET(fdw_fd(cfd), wfds)) fdw_hnd(cfd)(fdw_data(cfd), fdwatch_type_write); return 0; }
extern int fdwatch_del_fd(int idx) { if (idx < 0 || idx >= fdw_maxcons) { ERROR2("out of bounds idx [{}] (max: {})", idx, fdw_maxcons); return -1; } t_fdwatch_fd *cfd = fdw_fds + idx; if (!fdw_rw(cfd)) { ERROR0("found reseted rw"); return -1; } fdw->del(idx); /* remove it from uselist, add it to freelist */ uselist.remove(*cfd); freelist.push_back(*cfd); fdw_fd(cfd) = 0; fdw_rw(cfd) = 0; fdw_data(cfd) = NULL; fdw_hnd(cfd) = NULL; return 0; }
void FDWKqueueBackend::handle() { /* eventlog(eventlog_level_trace, __FUNCTION__, "called"); */ for (unsigned i = 0; i < sr; i++) { /* eventlog(eventlog_level_trace, __FUNCTION__, "checking %d ident: %d read: %d write: %d", i, kqevents[i].ident, kqevents[i].filter & EVFILT_READ, kqevents[i].filter & EVFILT_WRITE); */ t_fdwatch_fd *cfd = fdw_fds + (unsigned long)kqevents[i].udata; if (fdw_rw(cfd) & fdwatch_type_read && kqevents[i].filter == EVFILT_READ) if (fdw_hnd(cfd) (fdw_data(cfd), fdwatch_type_read) == -2) continue; if (fdw_rw(cfd) & fdwatch_type_write && kqevents[i].filter == EVFILT_WRITE) fdw_hnd(cfd) (fdw_data(cfd), fdwatch_type_write); } sr = 0; }
void FDWEpollBackend::handle() { // eventlog(eventlog_level_trace, __FUNCTION__, "called"); for (struct epoll_event *ev = epevents.get(); sr; sr--, ev++) { // eventlog(eventlog_level_trace, __FUNCTION__, "checking %d ident: %d read: %d write: %d", i, kqevents[i].ident, kqevents[i].filter & EVFILT_READ, kqevents[i].filter & EVFILT_WRITE); t_fdwatch_fd *cfd = fdw_fds + ev->data.fd; if (fdw_rw(cfd) & fdwatch_type_read && ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP)) if (fdw_hnd(cfd) (fdw_data(cfd), fdwatch_type_read) == -2) continue; if (fdw_rw(cfd) & fdwatch_type_write && ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP)) fdw_hnd(cfd) (fdw_data(cfd), fdwatch_type_write); } sr = 0; }
extern int fdwatch_add_fd(int fd, unsigned rw, fdwatch_handler h, void *data) { /* max sockets reached */ if (freelist.empty()) return -1; t_fdwatch_fd *cfd = &freelist.front(); fdw_fd(cfd) = fd; if (fdw->add(fdw_idx(cfd), rw)) return -1; /* add it to used sockets list, remove it from free list */ uselist.push_back(*cfd); freelist.remove(*cfd); fdw_rw(cfd) = rw; fdw_data(cfd) = data; fdw_hnd(cfd) = h; return fdw_idx(cfd); }