rbb 99/06/21 10:37:34
Modified: apr/network_io/beos networkio.h poll.c Log: Update the boes stuff. Revision Changes Path 1.4 +4 -8 apache-apr/apr/network_io/beos/networkio.h Index: networkio.h =================================================================== RCS file: /home/cvs/apache-apr/apr/network_io/beos/networkio.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- networkio.h 1999/05/27 19:02:34 1.3 +++ networkio.h 1999/06/21 17:37:33 1.4 @@ -78,14 +78,10 @@ struct pollfd_t { ap_context_t *cntxt; struct socket_t *sock; - int16 events; - int16 revents; -}; - -struct beos_pollfd_t { - int fd; - int16 events; - int16 revents; + fd_set *read; + fd_set *write; + fd_set *except; + int highsock; }; ap_int16_t get_event(ap_int16_t); 1.5 +91 -142 apache-apr/apr/network_io/beos/poll.c Index: poll.c =================================================================== RCS file: /home/cvs/apache-apr/apr/network_io/beos/poll.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- poll.c 1999/06/02 18:44:49 1.4 +++ poll.c 1999/06/21 17:37:33 1.5 @@ -63,169 +63,118 @@ /* so for the time being we try our best with an implementaion that */ /* uses select. However, select on beos isn't that hot either, so */ /* until R5 we have to live with a less than perfect implementation */ - -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); + +/* Apparently those sneaky people at Be included support for write in */ +/* select for R4.5 of BeOS. So here we use code that uses the write */ +/* bits. */ + +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_int16_t get_event(ap_int16_t event) -{ - ap_int16_t rv = 0; - - if (event & APR_POLLIN) - rv |= POLLIN; - if (event & APR_POLLPRI) - rv |= POLLPRI; - if (event & APR_POLLOUT) - rv |= POLLOUT; - if (event & APR_POLLERR) - rv |= POLLERR; - if (event & APR_POLLHUP) - rv |= POLLHUP; - if (event & APR_POLLNVAL) - rv |= POLLNVAL; - - return rv; -} +} -ap_int16_t get_revent(ap_int16_t event) +ap_status_t ap_add_poll_socket(struct pollfd_t *aprset, + struct socket_t *sock, ap_int16_t event) { - ap_int16_t rv = 0; - - if (event & POLLIN) - rv |= APR_POLLIN; - if (event & POLLPRI) - rv |= APR_POLLPRI; - if (event & POLLOUT) - rv |= APR_POLLOUT; - if (event & POLLERR) - rv |= APR_POLLERR; - if (event & POLLHUP) - rv |= APR_POLLHUP; - if (event & POLLNVAL) - rv |= APR_POLLNVAL; - - return rv; + 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_add_poll_socket(struct pollfd_t *aprset, - struct socket_t *sock, ap_int16_t event, - ap_int32_t pos) -{ - aprset[pos].sock = sock; - aprset[pos].events = get_event(event); - return APR_SUCCESS; -} ap_status_t ap_poll(struct pollfd_t *aprset, ap_int32_t *nsds, ap_int32_t timeout) { - int i; - int rv = 0, maxfd = 0; - uint32 starttime; - char test = 'T'; - struct timeval tv; - fd_set rd; - struct beos_pollfd_t *pollset; - - pollset = (struct beos_pollfd_t *)ap_palloc(aprset->cntxt, sizeof(struct beos_pollfd_t *) * *nsds);; - - FD_ZERO(&rd); - - /* try to build the fd_set mask for the read sockets... */ - for (i = 0; i < *nsds; i++) { - pollset[i].fd = aprset[i].sock->socketdes; - pollset[i].events = aprset[i].events; - if (pollset[i].fd > maxfd) - maxfd=pollset[i].fd; - if (aprset[i].events & POLLIN) { - FD_SET(pollset[i].fd, &rd); - } - } + int rv; + struct timeval *thetime; - /* now we have a timeout value - so set it into the timeval structure */ - tv.tv_sec = timeout; - tv.tv_usec=0; - - /*The timeout is given in seconds, so we use the real_time_clock() :-) */ - starttime = real_time_clock(); - -tryselectagain: - rv = select(maxfd + 1, &rd, NULL, NULL, &tv); - - /* if rv == -1 then it's an error */ - /* if the errno == EINTR then we need to go again... */ - if (rv == -1 && errno == EINTR){ - if (timeout == -1){ /* i.e. no timeout */ - goto tryselectagain; - } else { - /* OK - how long did we spend waiting ?? */ - if ((real_time_clock() - starttime) < timeout){ - tv.tv_sec = (real_time_clock() - starttime); - goto tryselectagain; - } else { - /* we passed our timeout, so we return 0 */ - rv=0; - } - } - } - - /* if we get this far then we have either */ - /* 1. a socket to look at... */ - /* 2. an error situation */ - /**/ - /* NB we haven't looked at writing sockets yet!!! */ - if (rv >= 0){ - /* i.e. we have a read socket to set the revents for */ - rv = 0; /* we reset for an independant check ! */ - for (i = 0; i < *nsds; i++){ - int ret = 0; - if ((pollset[i].events & POLLIN) && FD_ISSET(pollset[i].fd, &rd)){ - ret |= POLLIN; - } - if (pollset[i].events & POLLOUT) { - /* we asked if we could send... */ - if (send(pollset[i].fd, &test, 0, 0)!=0){ - if (errno == EWOULDBLOCK){ - /* the socket is blocking... */ - /* we still haven't reached the timeout so go back and try again... */ - if ((real_time_clock() - starttime)<timeout) - goto tryselectagain; - } else { - /* an error has occurred... */ - ret |= POLLERR; - } - } else { - /* it's OK to send to the socket */ - ret |= POLLOUT; - } - } - if (ret != 0){ - /* we have a change! */ - pollset[i].revents = ret; - aprset[i].revents = ret; - rv ++; - } - } + 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; } - if (rv == 0 && ((real_time_clock() - starttime) < timeout)) - goto tryselectagain; + rv = select(aprset->highsock + 1, aprset->read, aprset->write, + NULL, thetime); + (*nsds) = rv; + if ((*nsds) == 0) { + return APR_TIMEUP; + } if ((*nsds) < 0) { - return errno; + return APR_EEXIST; } return APR_SUCCESS; } -ap_status_t ap_get_revents(struct pollfd_t *aprset, ap_int32_t pos, ap_int16_t *event) +ap_status_t ap_get_revents(struct pollfd_t *aprset, struct socket_t *sock, ap_int16_t *event) { - (*event) = aprset[pos].revents; + ap_int16_t revents = 0; + char data[256]; + int dummy = 256; + + if (FD_ISSET(sock->socketdes, aprset->read)) { + revents |= APR_POLLIN; + if (recv(sock->socketdes, &data, 0, 0) == -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; + } + + /* Still no support for execpt bits in BeOS R4.5 so for the time being */ + /* we can't check this. Hopefully the error checking above will allow */ + /* sufficient errors to be recognised to cover this. */ + + /*if (FD_ISSET(sock->socketdes, aprset->except)) { + revents |= APR_POLLPRI; + }*/ + + (*event) = revents; return APR_SUCCESS; }