diff options
author | bjh <bjh@13f79535-47bb-0310-9956-ffa450edef68> | 2002-09-26 13:05:39 +0000 |
---|---|---|
committer | bjh <bjh@13f79535-47bb-0310-9956-ffa450edef68> | 2002-09-26 13:05:39 +0000 |
commit | 69d76bff4f53903c0c6f6fae6a068343fc858629 (patch) | |
tree | 5b454d46f09b970a9070bc1ea8a9c90e508a902f /poll/os2 | |
parent | e1b3630d1a06488f9978392d8d80de71a34ad473 (diff) | |
download | libapr-69d76bff4f53903c0c6f6fae6a068343fc858629.tar.gz |
OS/2: Implement apr_pollset_*()
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@63884 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'poll/os2')
-rw-r--r-- | poll/os2/pollset.c | 164 |
1 files changed, 159 insertions, 5 deletions
diff --git a/poll/os2/pollset.c b/poll/os2/pollset.c index bd6e30dd4..a9c5cf1ba 100644 --- a/poll/os2/pollset.c +++ b/poll/os2/pollset.c @@ -60,21 +60,43 @@ struct apr_pollset_t { apr_pool_t *pool; + apr_uint32_t nelts; + apr_uint32_t nalloc; + int *pollset; + int num_read; + int num_write; + int num_except; + int num_total; + apr_pollfd_t *query_set; + apr_pollfd_t *result_set; }; + + APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, apr_uint32_t size, apr_pool_t *p, apr_uint32_t flags) { - return APR_ENOTIMPL; + *pollset = apr_palloc(p, sizeof(**pollset)); + (*pollset)->pool = p; + (*pollset)->nelts = 0; + (*pollset)->nalloc = size; + (*pollset)->pollset = apr_palloc(p, size * sizeof(int) * 3); + (*pollset)->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); + (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); + (*pollset)->num_read = -1; + return APR_SUCCESS; } APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset) { - return APR_ENOTIMPL; + /* A no-op function for now. If we later implement /dev/poll + * support, we'll need to close the /dev/poll fd here + */ + return APR_SUCCESS; } @@ -82,7 +104,19 @@ 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) { - return APR_ENOTIMPL; + if (pollset->nelts == pollset->nalloc) { + return APR_ENOMEM; + } + + pollset->query_set[pollset->nelts] = *descriptor; + + if (descriptor->desc_type != APR_POLL_SOCKET) { + return APR_EBADF; + } + + pollset->nelts++; + pollset->num_read = -1; + return APR_SUCCESS; } @@ -90,7 +124,67 @@ APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, const apr_pollfd_t *descriptor) { - return APR_ENOTIMPL; + apr_uint32_t i; + + for (i = 0; i < pollset->nelts; i++) { + if (descriptor->desc.s == pollset->query_set[i].desc.s) { + /* 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 (descriptor->desc.s == pollset->query_set[i].desc.s) { + pollset->nelts--; + } + else { + pollset->pollset[dst] = pollset->pollset[i]; + pollset->query_set[dst] = pollset->query_set[i]; + dst++; + } + } + + pollset->num_read = -1; + return APR_SUCCESS; + } + } + + return APR_NOTFOUND; +} + + + +static void make_pollset(apr_pollset_t *pollset) +{ + int i; + int pos = 0; + + pollset->num_read = 0; + pollset->num_write = 0; + pollset->num_except = 0; + + for (i = 0; i < pollset->nelts; i++) { + if (pollset->query_set[i].reqevents & APR_POLLIN) { + pollset->pollset[pos++] = pollset->query_set[i].desc.s->socketdes; + pollset->num_read++; + } + } + + for (i = 0; i < pollset->nelts; i++) { + if (pollset->query_set[i].reqevents & APR_POLLOUT) { + pollset->pollset[pos++] = pollset->query_set[i].desc.s->socketdes; + pollset->num_write++; + } + } + + for (i = 0; i < pollset->nelts; i++) { + if (pollset->query_set[i].reqevents & APR_POLLPRI) { + pollset->pollset[pos++] = pollset->query_set[i].desc.s->socketdes; + pollset->num_except++; + } + } + + pollset->num_total = pollset->num_read + pollset->num_write + pollset->num_except; } @@ -100,5 +194,65 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, apr_int32_t *num, const apr_pollfd_t **descriptors) { - return APR_ENOTIMPL; + int rv; + apr_uint32_t i; + int *pollresult; + int read_pos, write_pos, except_pos; + + if (pollset->num_read < 0) { + make_pollset(pollset); + } + + pollresult = alloca(sizeof(int) * pollset->num_total); + memcpy(pollresult, pollset->pollset, sizeof(int) * pollset->num_total); + + if (timeout > 0) { + timeout /= 1000; + } + + rv = select(pollresult, pollset->num_read, pollset->num_write, pollset->num_except, timeout); + + if (rv < 0) { + return APR_FROM_OS_ERROR(sock_errno()); + } + + if (rv == 0) { + return APR_TIMEUP; + } + + read_pos = 0; + write_pos = pollset->num_read; + except_pos = pollset->num_read + pollset->num_write; + (*num) = 0; + + for (i = 0; i < pollset->nelts; i++) { + int rtnevents = 0; + + if (pollset->query_set[i].reqevents & APR_POLLIN) { + if (pollresult[read_pos++] != -1) { + rtnevents |= APR_POLLIN; + } + } + + if (pollset->query_set[i].reqevents & APR_POLLOUT) { + if (pollresult[write_pos++] != -1) { + rtnevents |= APR_POLLOUT; + } + } + + if (pollset->query_set[i].reqevents & APR_POLLPRI) { + if (pollresult[except_pos++] != -1) { + rtnevents |= APR_POLLPRI; + } + } + + if (rtnevents) { + pollset->result_set[*num] = pollset->query_set[i]; + pollset->result_set[*num].rtnevents = rtnevents; + (*num)++; + } + } + + *descriptors = pollset->result_set; + return APR_SUCCESS; } |