In case anyone missed this on dev@apr:
dreid 2003/11/21 11:50:02
Modified: include apr_poll.h
poll/os2 pollset.c
poll/unix poll.c
Log:
Add back apr_poll as it shouldn't have been removed.
apr_poll is only intended for quick polling. More complex setups
should use the pollset structure that now exists.
testpoll commit coming shortly to reflect the change and test the
pollset code.
Brian - can you make sure the OS/2 code is OK?
Revision Changes Path
1.13 +22 -0 apr/include/apr_poll.h
Index: apr_poll.h
===================================================================
RCS file: /home/cvs/apr/include/apr_poll.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- apr_poll.h 17 Nov 2003 00:32:36 -0000 1.12
+++ apr_poll.h 21 Nov 2003 19:50:02 -0000 1.13
@@ -176,6 +176,28 @@
apr_int32_t *num,
const apr_pollfd_t **descriptors);
+
+/**
+ * Poll the sockets in the poll structure
+ * @param aprset The poll structure we will be using.
+ * @param numsock The number of sockets we are polling
+ * @param nsds The number of sockets signalled.
+ * @param timeout The amount of time in microseconds to wait. This is
+ * a maximum, not a minimum. If a socket is signalled, we
+ * will wake up before this time. A negative number means
+ * wait until a socket is signalled.
+ * @remark
+ * <PRE>
+ * The number of sockets signalled is returned in the second argument.
+ *
+ * This is a blocking call, and it will not return until either a
+ * socket has been signalled, or the timeout has expired.
+ * </PRE>
+ */
+APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t numsock,
+ apr_int32_t *nsds,
+ apr_interval_time_t timeout);
+
/** @} */
1.6 +87 -0 apr/poll/os2/pollset.c
Index: pollset.c
===================================================================
RCS file: /home/cvs/apr/poll/os2/pollset.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- pollset.c 6 Jan 2003 23:44:36 -0000 1.5
+++ pollset.c 21 Nov 2003 19:50:02 -0000 1.6
@@ -256,3 +256,90 @@
*descriptors = pollset->result_set;
return APR_SUCCESS;
}
+
+APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t num,
+ apr_int32_t *nsds, apr_interval_time_t timeout)
+{
+ int *pollset;
+ int i;
+ int num_read = 0, num_write = 0, num_except = 0, num_total;
+ int pos_read, pos_write, pos_except;
+
+ for (i = 0; i < num; i++) {
+ if (aprset[i].desc_type == APR_POLL_SOCKET) {
+ num_read += (aprset[i].reqevents & APR_POLLIN) != 0;
+ num_write += (aprset[i].reqevents & APR_POLLOUT) != 0;
+ num_except += (aprset[i].reqevents & APR_POLLPRI) != 0;
+ }
+ }
+
+ num_total = num_read + num_write + num_except;
+ pollset = alloca(sizeof(int) * num_total);
+ memset(pollset, 0, sizeof(int) * num_total);
+
+ pos_read = 0;
+ pos_write = num_read;
+ pos_except = pos_write + num_write;
+
+ for (i = 0; i < num; i++) {
+ if (aprset[i].desc_type == APR_POLL_SOCKET) {
+ if (aprset[i].reqevents & APR_POLLIN) {
+ pollset[pos_read++] = aprset[i].desc.s->socketdes;
+ }
+
+ if (aprset[i].reqevents & APR_POLLOUT) {
+ pollset[pos_write++] = aprset[i].desc.s->socketdes;
+ }
+
+ if (aprset[i].reqevents & APR_POLLPRI) {
+ pollset[pos_except++] = aprset[i].desc.s->socketdes;
+ }
+
+ aprset[i].rtnevents = 0;
+ }
+ }
+
+ if (timeout > 0) {
+ timeout /= 1000; /* convert microseconds to milliseconds */
+ }
+
+ i = select(pollset, num_read, num_write, num_except, timeout);
+ (*nsds) = i;
+
+ if ((*nsds) < 0) {
+ return APR_FROM_OS_ERROR(sock_errno());
+ }
+
+ if ((*nsds) == 0) {
+ return APR_TIMEUP;
+ }
+
+ pos_read = 0;
+ pos_write = num_read;
+ pos_except = pos_write + num_write;
+
+ for (i = 0; i < num; i++) {
+ if (aprset[i].desc_type == APR_POLL_SOCKET) {
+ if (aprset[i].reqevents & APR_POLLIN) {
+ if (pollset[pos_read++] > 0) {
+ aprset[i].rtnevents |= APR_POLLIN;
+ }
+ }
+
+ if (aprset[i].reqevents & APR_POLLOUT) {
+ if (pollset[pos_write++] > 0) {
+ aprset[i].rtnevents |= APR_POLLOUT;
+ }
+ }
+
+ if (aprset[i].reqevents & APR_POLLPRI) {
+ if (pollset[pos_except++] > 0) {
+ aprset[i].rtnevents |= APR_POLLPRI;
+ }
+ }
+ }
+ }
+
+ return APR_SUCCESS;
+}
+
1.41 +200 -1 apr/poll/unix/poll.c
Index: poll.c
===================================================================
RCS file: /home/cvs/apr/poll/unix/poll.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- poll.c 17 Nov 2003 00:32:36 -0000 1.40
+++ poll.c 21 Nov 2003 19:50:02 -0000 1.41
@@ -114,8 +114,207 @@
return rv;
}
-#endif /* HAVE_POLL */
+#define SMALL_POLLSET_LIMIT 8
+APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t num,
+ apr_int32_t *nsds, apr_interval_time_t timeout)
+{
+ int i, num_to_poll;
+#ifdef HAVE_VLA
+ /* XXX: I trust that this is a segv when insufficient stack exists? */
+ struct pollfd pollset[num];
+#elif defined(HAVE_ALLOCA)
+ struct pollfd *pollset = alloca(sizeof(struct pollfd) * num);
+ if (!pollset)
+ return APR_ENOMEM;
+#else
+ struct pollfd tmp_pollset[SMALL_POLLSET_LIMIT];
+ struct pollfd *pollset;
+
+ if (num <= SMALL_POLLSET_LIMIT) {
+ pollset = tmp_pollset;
+ }
+ else {
+ /* This does require O(n) to copy the descriptors to the internal
+ * mapping.
+ */
+ pollset = malloc(sizeof(struct pollfd) * num);
+ /* The other option is adding an apr_pool_abort() fn to invoke
+ * the pool's out of memory handler
+ */
+ if (!pollset)
+ return APR_ENOMEM;
+ }
+#endif
+ for (i = 0; i < num; i++) {
+ if (aprset[i].desc_type == APR_POLL_SOCKET) {
+ pollset[i].fd = aprset[i].desc.s->socketdes;
+ }
+ else if (aprset[i].desc_type == APR_POLL_FILE) {
+ pollset[i].fd = aprset[i].desc.f->filedes;
+ }
+ else {
+ break;
+ }
+ pollset[i].events = get_event(aprset[i].reqevents);
+ }
+ num_to_poll = i;
+
+ if (timeout > 0) {
+ timeout /= 1000; /* convert microseconds to milliseconds */
+ }
+
+ i = poll(pollset, num_to_poll, timeout);
+ (*nsds) = i;
+
+ for (i = 0; i < num; i++) {
+ aprset[i].rtnevents = get_revent(pollset[i].revents);
+ }
+
+#if !defined(HAVE_VLA) && !defined(HAVE_ALLOCA)
+ if (num > SMALL_POLLSET_LIMIT) {
+ free(pollset);
+ }
+#endif
+
+ if ((*nsds) < 0) {
+ return apr_get_netos_error();
+ }
+ if ((*nsds) == 0) {
+ return APR_TIMEUP;
+ }
+ return APR_SUCCESS;
+}
+
+
+#else /* Use select to mimic poll */
+
+APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, int num, apr_int32_t *nsds,
+ apr_interval_time_t timeout)
+{
+ fd_set readset, writeset, exceptset;
+ int rv, i;
+ int maxfd = -1;
+ struct timeval tv, *tvptr;
+#ifdef NETWARE
+ apr_datatype_e set_type = APR_NO_DESC;
+#endif
+
+ if (timeout < 0) {
+ tvptr = NULL;
+ }
+ else {
+ tv.tv_sec = (long)apr_time_sec(timeout);
+ tv.tv_usec = (long)apr_time_usec(timeout);
+ tvptr = &tv;
+ }
+
+ FD_ZERO(&readset);
+ FD_ZERO(&writeset);
+ FD_ZERO(&exceptset);
+
+ for (i = 0; i < num; i++) {
+ apr_os_sock_t fd;
+
+ aprset[i].rtnevents = 0;
+
+ if (aprset[i].desc_type == APR_POLL_SOCKET) {
+#ifdef NETWARE
+ if (HAS_PIPES(set_type)) {
+ return APR_EBADF;
+ }
+ else {
+ set_type = APR_POLL_SOCKET;
+ }
+#endif
+ fd = aprset[i].desc.s->socketdes;
+ }
+ else if (aprset[i].desc_type == APR_POLL_FILE) {
+#if !APR_FILES_AS_SOCKETS
+ return APR_EBADF;
+#else
+#ifdef NETWARE
+ if (aprset[i].desc.f->is_pipe && !HAS_SOCKETS(set_type)) {
+ set_type = APR_POLL_FILE;
+ }
+ else
+ return APR_EBADF;
+#endif /* NETWARE */
+
+ fd = aprset[i].desc.f->filedes;
+
+#endif /* APR_FILES_AS_SOCKETS */
+ }
+ else {
+ break;
+ }
+ if (aprset[i].reqevents & APR_POLLIN) {
+ FD_SET(fd, &readset);
+ }
+ if (aprset[i].reqevents & APR_POLLOUT) {
+ FD_SET(fd, &writeset);
+ }
+ if (aprset[i].reqevents &
+ (APR_POLLPRI | APR_POLLERR | APR_POLLHUP | APR_POLLNVAL)) {
+ FD_SET(fd, &exceptset);
+ }
+ if ((int)fd > maxfd) {
+ maxfd = (int)fd;
+ }
+ }
+
+#ifdef NETWARE
+ if (HAS_PIPES(set_type)) {
+ rv = pipe_select(maxfd + 1, &readset, &writeset, &exceptset, tvptr);
+ }
+ else {
+#endif
+
+ rv = select(maxfd + 1, &readset, &writeset, &exceptset, tvptr);
+
+#ifdef NETWARE
+ }
+#endif
+
+ (*nsds) = rv;
+ if ((*nsds) == 0) {
+ return APR_TIMEUP;
+ }
+ if ((*nsds) < 0) {
+ return apr_get_netos_error();
+ }
+
+ for (i = 0; i < num; i++) {
+ apr_os_sock_t fd;
+
+ if (aprset[i].desc_type == APR_POLL_SOCKET) {
+ fd = aprset[i].desc.s->socketdes;
+ }
+ else if (aprset[i].desc_type == APR_POLL_FILE) {
+#if !APR_FILES_AS_SOCKETS
+ return APR_EBADF;
+#else
+ fd = aprset[i].desc.f->filedes;
+#endif
+ }
+ else {
+ break;
+ }
+ if (FD_ISSET(fd, &readset)) {
+ aprset[i].rtnevents |= APR_POLLIN;
+ }
+ if (FD_ISSET(fd, &writeset)) {
+ aprset[i].rtnevents |= APR_POLLOUT;
+ }
+ if (FD_ISSET(fd, &exceptset)) {
+ aprset[i].rtnevents |= APR_POLLERR;
+ }
+ }
+
+ return APR_SUCCESS;
+}
+
+#endif
struct apr_pollset_t {
apr_uint32_t nelts;
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri Nov 21 21:03:03 2003