Project

General

Profile

Feature #16597 » 0004-thread-use-poll-in-rb_fd_select.patch

michals (Michal Suchánek), 05/29/2020 05:52 PM

View differences:

thread.c
memcpy(dst->fdset, src->fdset, size);
}
#if USE_POLL
struct rb_pollfdset {
int n_fds;
struct pollfd *fds;
};
static void
pollfdset_init(struct rb_pollfdset *pollfdset)
{
memset(pollfdset, 0, sizeof(*pollfdset));
}
static void
pollfdset_term(struct rb_pollfdset *pollfdset)
{
pollfdset->fds = xrealloc(pollfdset->fds, 0);
pollfdset->n_fds = 0;
}
static void
pollfdset_inc(struct rb_pollfdset *pollfdset)
{
pollfdset->fds = xrealloc(pollfdset->fds,sizeof(*pollfdset->fds) * (pollfdset->n_fds + 1));
memset(&pollfdset->fds[pollfdset->n_fds], 0, sizeof(*pollfdset->fds));
pollfdset->n_fds++;
}
static int
pollfdset_get_index(struct rb_pollfdset *pollfdset, int fd)
{
int i;
for (i = 0; i < pollfdset->n_fds ; i++)
if (pollfdset->fds[i].fd == fd)
return i;
return -1;
}
static int
pollfdset_index(struct rb_pollfdset *pollfdset, int fd)
{
int ret = pollfdset_get_index(pollfdset, fd);
if (ret < 0) {
ret = pollfdset->n_fds;
pollfdset_inc(pollfdset);
pollfdset->fds[ret].fd = fd;
}
return ret;
}
static void
pollfdset_set_flags(struct rb_pollfdset *pollfdset, int fd, int flags)
{
/* this is tricky - fds might get reallocated as a sideeffect of obtaining the index */
int idx = pollfdset_index(pollfdset, fd);
pollfdset->fds[idx].events |= flags;
}
static void
pollfdset_add(struct rb_pollfdset *pollfdset, rb_fdset_t *fds, int flags)
{
int i;
for (i = 0; i < fds->maxfd ; i++)
if (rb_fd_isset(i, fds))
pollfdset_set_flags(pollfdset, i, flags);
}
static void
pollfdset_extract(struct rb_pollfdset *pollfdset, rb_fdset_t *fds, int flags)
{
int i;
rb_fd_zero(fds);
for (i = 0; i < pollfdset->n_fds; i++)
if (pollfdset->fds[i].revents & (flags | POLLERR_SET))
rb_fd_set(pollfdset->fds[i].fd, fds);
}
int
rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, rb_fdset_t *errorfds, struct timeval *timeout)
{
struct rb_pollfdset pollfdset;
int timeout_ms = timeout ? timeout->tv_sec * 1000 + timeout->tv_usec / 1000 : -1;
int ret;
pollfdset_init(&pollfdset);
if (readfds) pollfdset_add(&pollfdset, readfds, POLLIN_SET);
if (writefds) pollfdset_add(&pollfdset, writefds, POLLOUT_SET);
if (exceptfds) pollfdset_add(&pollfdset, exceptfds, POLLEX_SET);
if (errorfds) pollfdset_add(&pollfdset, errorfds, POLLERR_SET);
ret = poll(pollfdset.fds, pollfdset.n_fds, timeout_ms);
if (readfds) pollfdset_extract(&pollfdset, readfds, POLLIN_SET);
if (writefds) pollfdset_extract(&pollfdset, writefds, POLLOUT_SET);
if (exceptfds) pollfdset_extract(&pollfdset, exceptfds, POLLEX_SET);
if (errorfds) pollfdset_extract(&pollfdset, errorfds, POLLERR_SET);
pollfdset_term(&pollfdset);
return ret;
}
#else /* USE_POLL */
int
rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, rb_fdset_t *errorfds, struct timeval *timeout)
{
......
rb_fd_zero(errorfds);
return select(n, r, w, e, timeout);
}
#endif /* USE_POLL */
#define rb_fd_no_init(fds) ((void)((fds)->fdset = 0), (void)((fds)->maxfd = 0))
(6-6/14)