Return-Path: Delivered-To: apache-cvs-archive@hyperreal.org Received: (qmail 17009 invoked by uid 6000); 18 Oct 1999 11:36:06 -0000 Received: (qmail 17003 invoked by uid 2016); 18 Oct 1999 11:36:05 -0000 Delivered-To: apcore-apache-2.0-cvs@apache.org Received: (qmail 17001 invoked by uid 240); 18 Oct 1999 11:36:04 -0000 Date: 18 Oct 1999 11:36:04 -0000 Message-ID: <19991018113604.17000.qmail@hyperreal.org> From: bjh@hyperreal.org To: apache-2.0-cvs@apache.org Subject: cvs commit: apache-2.0/src/lib/apr/network_io/os2 networkio.h poll.c Sender: apache-cvs-owner@apache.org Precedence: bulk Reply-To: new-httpd@apache.org bjh 99/10/18 04:36:04 Modified: src/lib/apr/network_io/os2 networkio.h poll.c Log: OS/2: Rework ap_poll() to use native thread safe select instead of the EMX C library select which isn't thread safe. Revision Changes Path 1.3 +24 -5 apache-2.0/src/lib/apr/network_io/os2/networkio.h Index: networkio.h =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/os2/networkio.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- networkio.h 1999/10/08 21:27:52 1.2 +++ networkio.h 1999/10/18 11:36:03 1.3 @@ -64,17 +64,36 @@ int socketdes; struct sockaddr_in *addr; int addr_len; + int timeout; }; struct pollfd_t { ap_context_t *cntxt; - struct socket_t *sock; - ap_int16_t events; - ap_int16_t revents; - int curpos; + int *socket_list; + int *r_socket_list; + int num_read; + int num_write; + int num_except; + int num_total; }; -ap_int16_t get_event(ap_int16_t); +/* Pointers to dynamically linked API functions */ +extern int (*os2_select)(int *, int, int, int, long); +extern int (*os2_sock_errno)(); + +/* Error codes returned from sock_errno() */ +#define SOCBASEERR 10000 +#define SOCEPERM (SOCBASEERR+1) /* Not owner */ +#define SOCESRCH (SOCBASEERR+3) /* No such process */ +#define SOCEINTR (SOCBASEERR+4) /* Interrupted system call */ +#define SOCENXIO (SOCBASEERR+6) /* No such device or address */ +#define SOCEBADF (SOCBASEERR+9) /* Bad file number */ +#define SOCEACCES (SOCBASEERR+13) /* Permission denied */ +#define SOCEFAULT (SOCBASEERR+14) /* Bad address */ +#define SOCEINVAL (SOCBASEERR+22) /* Invalid argument */ +#define SOCEMFILE (SOCBASEERR+24) /* Too many open files */ +#define SOCEPIPE (SOCBASEERR+32) /* Broken pipe */ +#define SOCEOS2ERR (SOCBASEERR+100) /* OS/2 Error */ #endif /* ! NETWORK_IO_H */ 1.5 +170 -54 apache-2.0/src/lib/apr/network_io/os2/poll.c Index: poll.c =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/os2/poll.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- poll.c 1999/10/10 20:34:56 1.4 +++ poll.c 1999/10/18 11:36:04 1.5 @@ -57,40 +57,79 @@ #include "networkio.h" #include "apr_network_io.h" #include "apr_general.h" +#include "apr_portable.h" #include "apr_lib.h" #include +#include +#define INCL_DOS +#include -/* OS/2 doesn't have a poll function, implement using select */ +/* OS/2 doesn't have a poll function, implement using OS/2 style select */ +static int os2_select_init( int *s, int noreads, int nowrites, int noexcepts, long timeout ); +static int os2_sock_errno_init(); + +int (*os2_select)(int *, int, int, int, long) = os2_select_init; +int (*os2_sock_errno)() = os2_sock_errno_init; +static HMODULE hSO32DLL; + ap_status_t ap_setup_poll(struct pollfd_t **new, ap_int32_t num, ap_context_t *cont) { - (*new) = (struct pollfd_t *)ap_palloc(cont, sizeof(struct pollfd_t) * num); + *new = (struct pollfd_t *)ap_palloc(cont, sizeof(struct pollfd_t)); - if ((*new) == NULL) { + if (*new == NULL) { return APR_ENOMEM; } + (*new)->socket_list = ap_palloc(cont, sizeof(int) * num); + + if ((*new)->socket_list == NULL) { + return APR_ENOMEM; + } + + (*new)->r_socket_list = ap_palloc(cont, sizeof(int) * num); + + if ((*new)->r_socket_list == NULL) { + return APR_ENOMEM; + } + (*new)->cntxt = cont; - (*new)->curpos = 0; + (*new)->num_total = 0; + (*new)->num_read = 0; + (*new)->num_write = 0; + (*new)->num_except = 0; + return APR_SUCCESS; } ap_status_t ap_add_poll_socket(struct pollfd_t *aprset, - struct socket_t *sock, ap_int16_t event) + struct socket_t *sock, ap_int16_t events) { - int i = 0; + int i; - while (i < aprset->curpos && aprset[i].sock->socketdes != sock->socketdes) { - i++; + if (events & APR_POLLIN) { + for (i=aprset->num_total; i>aprset->num_read; i--) + aprset->socket_list[i] = aprset->socket_list[i-1]; + aprset->socket_list[i] = sock->socketdes; + aprset->num_read++; + aprset->num_total++; } - if (i >= aprset->curpos) { - aprset->curpos++; - } - aprset[i].sock = sock; - aprset[i].events = event; - + + if (events & APR_POLLOUT) { + for (i=aprset->num_total; i>aprset->num_read + aprset->num_write; i--) + aprset->socket_list[i] = aprset->socket_list[i-1]; + aprset->socket_list[i] = sock->socketdes; + aprset->num_write++; + aprset->num_total++; + } + + if (events &APR_POLLPRI) { + aprset->socket_list[aprset->num_total] = sock->socketdes; + aprset->num_except++; + aprset->num_total++; + } return APR_SUCCESS; } @@ -99,71 +138,148 @@ ap_status_t ap_poll(struct pollfd_t *pollfdset, ap_int32_t *nsds, ap_int32_t timeout) { int i; - int rv = 0, maxfd = 0; + int rv = 0; time_t starttime; struct timeval tv; - fd_set readfds, writefds, exceptfds; - - FD_ZERO(&readfds); - FD_ZERO(&writefds); - FD_ZERO(&exceptfds); - for (i = 0; i < *nsds; i++) { - if (pollfdset[i].sock->socketdes > maxfd) - maxfd = pollfdset[i].sock->socketdes; - - if (pollfdset[i].events & APR_POLLIN) - FD_SET(pollfdset[i].sock->socketdes, &readfds); - - if (pollfdset[i].events & APR_POLLOUT) - FD_SET(pollfdset[i].sock->socketdes, &writefds); - - if (pollfdset[i].events & APR_POLLPRI) - FD_SET(pollfdset[i].sock->socketdes, &exceptfds); - } - tv.tv_sec = timeout; tv.tv_usec = 0; time(&starttime); do { - rv = select(maxfd + 1, &readfds, &writefds, &exceptfds, timeout >= 0 ? &tv : NULL); + for (i=0; inum_total; i++) { + pollfdset->r_socket_list[i] = _getsockhandle(pollfdset->socket_list[i]); + } + + rv = os2_select(pollfdset->r_socket_list, + pollfdset->num_read, + pollfdset->num_write, + pollfdset->num_except, + timeout > 0 ? timeout * 1000 : -1); - if (rv < 0 && errno == EINTR && timeout >= 0 ) { + if (rv < 0 && os2_sock_errno() == SOCEINTR && timeout >= 0 ) { time_t elapsed = time(NULL) - starttime; if (timeout <= elapsed) break; - tv.tv_sec = timeout - elapsed; + timeout -= elapsed; } - } while ( rv < 0 && errno == EINTR ); + } while ( rv < 0 && os2_sock_errno() == SOCEINTR ); - if (rv >= 0) { - for (i = 0; i < *nsds; i++) { - pollfdset[i].revents = - (FD_ISSET(pollfdset[i].sock->socketdes, &readfds) ? APR_POLLIN : 0) + - (FD_ISSET(pollfdset[i].sock->socketdes, &writefds) ? APR_POLLOUT : 0) + - (FD_ISSET(pollfdset[i].sock->socketdes, &exceptfds) ? APR_POLLPRI : 0); - } - } - (*nsds) = rv; - return rv < 0 ? errno : APR_SUCCESS; + return rv < 0 ? os2errno(os2_sock_errno()) : APR_SUCCESS; } ap_status_t ap_get_revents(ap_int16_t *event, struct socket_t *sock, struct pollfd_t *aprset) { - int i = 0; + int i; - while (i < aprset->curpos && aprset[i].sock->socketdes != sock->socketdes) { - i++; - } - if (i >= aprset->curpos) { + for (i=0; i < aprset->num_total && aprset->socket_list[i] != sock->socketdes; i++); + + if (i == aprset->num_total) { return APR_INVALSOCK; } - (*event) = aprset[i].revents; + + if (i < aprset->num_read) + *event = APR_POLLIN; + else if (i < aprset->num_read + aprset->num_write) + *event = APR_POLLOUT; + else + *event = APR_POLLPRI; + return APR_SUCCESS; +} + + + +ap_status_t ap_remove_poll_socket(struct pollfd_t *aprset, + struct socket_t *sock, ap_int16_t events) +{ + int start, *count, pos; + + while (events) { + if (events & APR_POLLIN) { + start = 0; + count = &aprset->num_read; + events -= APR_POLLIN; + } else if (events & APR_POLLOUT) { + start = aprset->num_read; + count = &aprset->num_write; + events -= APR_POLLOUT; + } else if (events & APR_POLLPRI) { + start = aprset->num_read + aprset->num_write; + count = &aprset->num_except; + events -= APR_POLLPRI; + } else + break; + + for (pos=start; pos < start+(*count) && aprset->socket_list[pos] != sock->socketdes; pos++); + + if (pos < start+(*count)) { + aprset->num_total--; + (*count)--; + + for (;posnum_total; pos++) { + aprset->socket_list[pos] = aprset->socket_list[pos+1]; + } + } else { + return APR_NOTFOUND; + } + } + + return APR_SUCCESS; +} + + + +static int os2_fn_link() +{ + if (os2_select == os2_select_init || os2_select == NULL) { + DosEnterCritSec(); /* Stop two threads doing this at the same time */ + + if (os2_select == os2_select_init || os2_select == NULL) { + ULONG rc; + char errorstr[200]; + + rc = DosLoadModule(errorstr, sizeof(errorstr), "SO32DLL", &hSO32DLL); + + if (rc) + return os2errno(rc); + + rc = DosQueryProcAddr(hSO32DLL, 0, "SELECT", &os2_select); + + if (rc) + return os2errno(rc); + + rc = DosQueryProcAddr(hSO32DLL, 0, "SOCK_ERRNO", &os2_sock_errno); + + if (rc) + return os2errno(rc); + } + DosExitCritSec(); + } + return APR_SUCCESS; +} + + + +static int os2_select_init(int *s, int noreads, int nowrites, int noexcepts, long timeout) +{ + int rc = os2_fn_link(); + if (rc == APR_SUCCESS) + return os2_select(s, noreads, nowrites, noexcepts, timeout); + return rc; +} + + + +static int os2_sock_errno_init() +{ + int rc = os2_fn_link(); + if (rc == APR_SUCCESS) + return os2_sock_errno(); + return rc; }