rbb 99/06/16 04:16:08
Modified: apr configure.in apr/network_io/unix networkio.h poll.c apr/test ab_apr.c testsock.c Log: Changes to put select based poll into the code. If the platform doesn't support poll, it will compile and run now anyway. Revision Changes Path 1.21 +1 -1 apache-apr/apr/configure.in Index: configure.in =================================================================== RCS file: /home/cvs/apache-apr/apr/configure.in,v retrieving revision 1.20 retrieving revision 1.21 diff -u -r1.20 -r1.21 --- configure.in 1999/06/15 19:43:03 1.20 +++ configure.in 1999/06/16 11:15:56 1.21 @@ -162,7 +162,7 @@ AC_FUNC_SETPGRP dnl Checks for library functions. -AC_CHECK_FUNCS(strcasecmp stricmp) +AC_CHECK_FUNCS(strcasecmp stricmp poll) dnl Start building stuff from our information AC_SUBST(LDLIBS) 1.11 +9 -1 apache-apr/apr/network_io/unix/networkio.h Index: networkio.h =================================================================== RCS file: /home/cvs/apache-apr/apr/network_io/unix/networkio.h,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- networkio.h 1999/06/14 12:43:10 1.10 +++ networkio.h 1999/06/16 11:15:58 1.11 @@ -70,10 +70,18 @@ struct pollfd_t { ap_context_t *cntxt; +#ifdef HAVE_POLL struct socket_t *sock; + int curpos; +#else + fd_set *read; + fd_set *write; + fd_set *except; + int highsock; +#endif ap_int16_t events; ap_int16_t revents; - int curpos; + }; ap_int16_t get_event(ap_int16_t); 1.13 +118 -1 apache-apr/apr/network_io/unix/poll.c Index: poll.c =================================================================== RCS file: /home/cvs/apache-apr/apr/network_io/unix/poll.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- poll.c 1999/06/14 12:43:10 1.12 +++ poll.c 1999/06/16 11:15:59 1.13 @@ -60,6 +60,7 @@ #include <errno.h> #include <sys/poll.h> +#ifdef HAVE_POLL /* We can just use poll to do our socket polling. */ ap_status_t ap_setup_poll(ap_context_t *cont, ap_int32_t num, struct pollfd_t **new) { @@ -173,4 +174,120 @@ (*event) = aprset[i].revents; return APR_SUCCESS; } - + +#else /* Use select to mimic poll */ + +ap_status_t ap_setup_poll(ap_context_t *cont, ap_int32_t num, struct pollfd_t ** +new) +{ + (*new) = (struct pollfd_t *)ap_palloc(cont, sizeof(struct pollfd_t) * num); + if ((*new) == NULL) { + return APR_ENOMEM; + } + (*new)->cntxt = cont; + (*new)->read = (fd_set *)ap_palloc(cont, sizeof(fd_set)); + (*new)->write = (fd_set *)ap_palloc(cont, sizeof(fd_set)); + (*new)->except = (fd_set *)ap_palloc(cont, sizeof(fd_set)); + FD_ZERO((*new)->read); + FD_ZERO((*new)->write); + FD_ZERO((*new)->except); + (*new)->highsock = -1; + return APR_SUCCESS; +} + +ap_status_t ap_add_poll_socket(struct pollfd_t *aprset, + struct socket_t *sock, ap_int16_t event) +{ + if (event & APR_POLLIN) { + FD_SET(sock->socketdes, aprset->read); + } + if (event & APR_POLLPRI) { + FD_SET(sock->socketdes, aprset->read); + } + if (event & APR_POLLOUT) { + FD_SET(sock->socketdes, aprset->write); + } + if (sock->socketdes > aprset->highsock) { + aprset->highsock = sock->socketdes; + } + return APR_SUCCESS; +} + +ap_status_t ap_poll(struct pollfd_t *aprset, ap_int32_t *nsds, ap_int32_t timeout) +{ + int rv; + struct timeval *thetime; + + if (timeout == -1) { + thetime = NULL; + } + else { + /* Convert milli-seconds into seconds and micro-seconds. */ + thetime = (struct timeval *)ap_palloc(aprset->cntxt, sizeof(struct timeval)); + thetime->tv_sec = timeout / (1000); + timeout = timeout % 1000; + thetime->tv_usec = timeout * 1000; + } + + rv = select(aprset->highsock + 1, aprset->read, aprset->write, + aprset->except, thetime); + + (*nsds) = rv; + if ((*nsds) == 0) { + return APR_TIMEUP; + } + if ((*nsds) < 0) { + return APR_EEXIST; + } + return APR_SUCCESS; +} + +ap_status_t ap_get_revents(struct pollfd_t *aprset, struct socket_t *sock, ap_int16_t *event) +{ + ap_int16_t revents = 0; + char data[256]; + int dummy = 256; + int flags = MSG_PEEK; + + /* We just want to PEEK at the data, so I am setting up a dummy WSABUF + * variable here. + */ + if (FD_ISSET(sock->socketdes, aprset->read)) { + revents |= APR_POLLIN; + if (recv(sock->socketdes, &data, dummy, flags) == -1) { + switch (errno) { + case ECONNRESET: + case ECONNABORTED: + case ESHUTDOWN: + case ENETRESET: { + revents ^= APR_POLLIN; + revents |= APR_POLLHUP; + break; + } + case ENOTSOCK: { + revents ^= APR_POLLIN; + revents |= APR_POLLNVAL; + } + default: { + revents ^= APR_POLLIN; + revents |= APR_POLLERR; + } + } + } + } + if (FD_ISSET(sock->socketdes, aprset->write)) { + revents |= APR_POLLOUT; + } + /* I am assuming that the except is for out of band data, not a failed + * connection on a non-blocking socket. Might be a bad assumption, but + * it works for now. rbb. + */ + if (FD_ISSET(sock->socketdes, aprset->except)) { + revents |= APR_POLLPRI; + } + + (*event) = revents; + return APR_SUCCESS; +} + +#endif 1.13 +3 -3 apache-apr/apr/test/ab_apr.c Index: ab_apr.c =================================================================== RCS file: /home/cvs/apache-apr/apr/test/ab_apr.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- ab_apr.c 1999/05/26 20:39:23 1.12 +++ ab_apr.c 1999/06/16 11:16:04 1.13 @@ -228,7 +228,7 @@ } c->state = STATE_READ; - ap_add_poll_socket(readbits, c->aprsock, APR_POLLIN, c->socknum); + ap_add_poll_socket(readbits, c->aprsock, APR_POLLIN); } /* --------------------------------------------------------- */ @@ -464,7 +464,7 @@ if (ap_connect(c->aprsock, hostname) != APR_SUCCESS) { if (errno == EINPROGRESS) { c->state = STATE_CONNECTING; - ap_add_poll_socket(readbits, c->aprsock, APR_POLLOUT, c->socknum); + ap_add_poll_socket(readbits, c->aprsock, APR_POLLOUT); return; } else { @@ -759,7 +759,7 @@ err("select"); for (i = 0; i < concurrency; i++) { - ap_get_revents(readbits, con[i].socknum, &rv); + ap_get_revents(readbits, con[i].aprsock, &rv); if ((rv & APR_POLLERR) || (rv & APR_POLLNVAL) || (rv & APR_POLLHUP)) { bad++; err_except++; 1.14 +0 -3 apache-apr/apr/test/testsock.c Index: testsock.c =================================================================== RCS file: /home/cvs/apache-apr/apr/test/testsock.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- testsock.c 1999/06/15 17:43:25 1.13 +++ testsock.c 1999/06/16 11:16:05 1.14 @@ -95,9 +95,6 @@ exit(-1); } - ap_setprocattr_detach(attr1, FALSE); - ap_setprocattr_detach(attr2, FALSE); - args[0] = ap_pstrdup(context, "server"); args[1] = NULL; s1 = ap_create_process(context, "./server", args, NULL, attr1, &proc1);