diff options
author | Brian Pane <brianp@apache.org> | 2002-08-01 22:54:25 +0000 |
---|---|---|
committer | Brian Pane <brianp@apache.org> | 2002-08-01 22:54:25 +0000 |
commit | c3223dfe938216a4f40211eb7acc6e5d9150783b (patch) | |
tree | d22a31e2751c63b6d4eab5e20701fa738ee9f019 /poll | |
parent | 607e19c393ed14e691fc1bc68d28e954a8cbefdd (diff) | |
download | apr-c3223dfe938216a4f40211eb7acc6e5d9150783b.tar.gz |
Added select-based pollset implementation for systems without poll
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@63756 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'poll')
-rw-r--r-- | poll/unix/poll.c | 140 |
1 files changed, 137 insertions, 3 deletions
diff --git a/poll/unix/poll.c b/poll/unix/poll.c index b551585f3..e316f9a38 100644 --- a/poll/unix/poll.c +++ b/poll/unix/poll.c @@ -240,7 +240,7 @@ APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, int num, apr_int32_t *n if (aprset[i].desc_type == APR_POLL_SOCKET) { fd = aprset[i].desc.s->socketdes; } - else if (aprset[i].desc_type == APR_POLL_FILE) { + else { fd = aprset[i].desc.f->filedes; } aprset[i].rtnevents = 0; @@ -264,7 +264,12 @@ APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, int num, apr_int32_t *n struct apr_pollset_t { apr_uint32_t nelts; apr_uint32_t nalloc; +#ifdef HAVE_POLL struct pollfd *pollset; +#else + fd_set readset, writeset, exceptset; + int maxfd; +#endif apr_pollfd_t *query_set; apr_pollfd_t *result_set; apr_pool_t *pool; @@ -277,7 +282,14 @@ APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, *pollset = apr_palloc(p, sizeof(**pollset)); (*pollset)->nelts = 0; (*pollset)->nalloc = size; +#ifdef HAVE_POLL (*pollset)->pollset = apr_palloc(p, size * sizeof(struct pollfd)); +#else + FD_ZERO(&((*pollset)->readset)); + FD_ZERO(&((*pollset)->writeset)); + FD_ZERO(&((*pollset)->exceptset)); + (*pollset)->maxfd = 0; +#endif (*pollset)->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); (*pollset)->pool = p; @@ -295,18 +307,36 @@ APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset) APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, const apr_pollfd_t *descriptor) { + int fd; if (pollset->nelts == pollset->nalloc) { return APR_ENOMEM; } pollset->query_set[pollset->nelts] = *descriptor; if (descriptor->desc_type == APR_POLL_SOCKET) { - pollset->pollset[pollset->nelts].fd = descriptor->desc.s->socketdes; + fd = descriptor->desc.s->socketdes; } else { - pollset->pollset[pollset->nelts].fd = descriptor->desc.f->filedes; + fd = descriptor->desc.f->filedes; } +#ifdef HAVE_POLL + pollset->pollset[pollset->nelts].fd = fd; pollset->pollset[pollset->nelts].events = get_event(descriptor->reqevents); +#else + if (descriptor->reqevents & APR_POLLIN) { + FD_SET(fd, &(pollset->readset)); + } + if (descriptor->reqevents & APR_POLLOUT) { + FD_SET(fd, &(pollset->writeset)); + } + if (descriptor->reqevents & + (APR_POLLPRI | APR_POLLERR | APR_POLLHUP | APR_POLLNVAL)) { + FD_SET(fd, &(pollset->exceptset)); + } + if (fd > pollset->maxfd) { + pollset->maxfd = fd; + } +#endif pollset->nelts++; return APR_SUCCESS; } @@ -324,6 +354,7 @@ APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, fd = descriptor->desc.f->filedes; } +#ifdef HAVE_POLL for (i = 0; i < pollset->nelts; i++) { if (fd == pollset->pollset[i].fd) { /* Found an instance of the fd: remove this and any other copies */ @@ -336,14 +367,49 @@ APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, } else { pollset->pollset[dst] = pollset->pollset[i]; + pollset->query_set[dst] = pollset->query_set[i]; + } + } + return APR_SUCCESS; + } + } + +#else /* no poll */ + for (i = 0; i < pollset->nelts; i++) { + if (((pollset->query_set[i].desc_type == APR_POLL_SOCKET) && + (fd == pollset->query_set[i].desc.s->socketdes)) || + ((pollset->query_set[i].desc_type == APR_POLL_FILE) && + (fd == pollset->query_set[i].desc.f->filedes))) { + /* Found an instance of the fd: remove this and any other copies */ + apr_uint32_t dst = i; + apr_uint32_t old_nelts = pollset->nelts; + pollset->nelts--; + for (i++; i < old_nelts; i++) { + if (((pollset->query_set[i].desc_type == APR_POLL_SOCKET) && + (fd == pollset->query_set[i].desc.s->socketdes)) || + ((pollset->query_set[i].desc_type == APR_POLL_FILE) && + (fd == pollset->query_set[i].desc.f->filedes))) { + pollset->nelts--; + } + else { + pollset->query_set[dst] = pollset->query_set[i]; } } + FD_CLR(fd, &(pollset->readset)); + FD_CLR(fd, &(pollset->writeset)); + FD_CLR(fd, &(pollset->exceptset)); + if ((fd == pollset->maxfd) && (pollset->maxfd > 0)) { + pollset->maxfd--; + } return APR_SUCCESS; } } +#endif /* no poll */ + return APR_NOTFOUND; } +#ifdef HAVE_POLL APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, apr_interval_time_t timeout, apr_int32_t *num, @@ -360,6 +426,9 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, if (rv < 0) { return errno; } + if (rv == 0) { + return APR_TIMEUP; + } j = 0; for (i = 0; i < pollset->nelts; i++) { if (pollset->pollset[i].revents != 0) { @@ -372,3 +441,68 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, *descriptors = pollset->result_set; return APR_SUCCESS; } + +#else /* no poll */ + +APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, + apr_interval_time_t timeout, + apr_int32_t *num, + const apr_pollfd_t **descriptors) +{ + int rv; + apr_uint32_t i, j; + struct timeval tv, *tvptr; + fd_set readset, writeset, exceptset; + + if (timeout < 0) { + tvptr = NULL; + } + else { + tv.tv_sec = (long)apr_time_sec(timeout); + tv.tv_usec = (long)apr_time_usec(timeout); + tvptr = &tv; + } + + memcpy(&readset, &(pollset->readset), sizeof(fd_set)); + memcpy(&writeset, &(pollset->writeset), sizeof(fd_set)); + memcpy(&exceptset, &(pollset->exceptset), sizeof(fd_set)); + + rv = select(pollset->maxfd + 1, &readset, &writeset, &exceptset, tvptr); + + (*num) = rv; + if (rv < 0) { + return errno; + } + if (rv == 0) { + return APR_TIMEUP; + } + j = 0; + for (i = 0; i < pollset->nelts; i++) { + int fd; + if (pollset->query_set[i].desc_type == APR_POLL_SOCKET) { + fd = pollset->query_set[i].desc.s->socketdes; + } + else { + fd = pollset->query_set[i].desc.s->socketdes; + } + if (FD_ISSET(fd, &readset) || FD_ISSET(fd, &writeset) || + FD_ISSET(fd, &exceptset)) { + pollset->result_set[j] = pollset->query_set[i]; + pollset->result_set[j].rtnevents = 0; + if (FD_ISSET(fd, &readset)) { + pollset->result_set[j].rtnevents |= APR_POLLIN; + } + if (FD_ISSET(fd, &writeset)) { + pollset->result_set[j].rtnevents |= APR_POLLOUT; + } + if (FD_ISSET(fd, &exceptset)) { + pollset->result_set[j].rtnevents |= APR_POLLERR; + } + j++; + } + } + + return APR_SUCCESS; +} + +#endif /* no poll */ |