OSSP CVS Repository

ossp - Check-in [2783]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 2783
Date: 2002-Nov-08 21:26:02 (local)
2002-Nov-08 20:26:02 (UTC)
User:rse
Branch:
Comment: Make pth_poll(3) more compliant to POSIX.1-2001/SUSv3 poll(2).

Parts submitted by: Nick Hudson <skrll@netbsd.org>

Tickets:
Inspections:
Files:
ossp-pkg/pth/ChangeLog      1.596 -> 1.597     4 inserted, 1 deleted
ossp-pkg/pth/pth_high.c      1.103 -> 1.104     68 inserted, 57 deleted

ossp-pkg/pth/ChangeLog 1.596 -> 1.597

--- ChangeLog    2002/11/08 19:12:13     1.596
+++ ChangeLog    2002/11/08 20:26:02     1.597
@@ -21,7 +21,10 @@
                   
   Changes between 2.0b0 and 2.0b1 (07-Nov-2002 to xx-Nov-2002)
 
-   *) Make pth_select(2) more compliant to POSIX.1-2001/SUSv3 select(2).
+   *) Make pth_poll(3) more compliant to POSIX.1-2001/SUSv3 poll(2).
+      [Ralf S. Engelschall, Nick Hudson <skrll@netbsd.org>]
+
+   *) Make pth_select(3) more compliant to POSIX.1-2001/SUSv3 select(2).
       This especially fixes the polling-only situation (timeout = (0,0)).
       [Ralf S. Engelschall]
 


ossp-pkg/pth/pth_high.c 1.103 -> 1.104

--- pth_high.c   2002/11/08 19:12:13     1.103
+++ pth_high.c   2002/11/08 20:26:02     1.104
@@ -461,18 +461,20 @@
            INTERNALLY THE SCHEDULER IS ONLY select(2) BASED!! */
 int pth_poll_ev(struct pollfd *pfd, nfds_t nfd, int timeout, pth_event_t ev_extra)
 {
-    fd_set rfds, wfds, efds;
+    fd_set rfds, wfds, efds, xfds;
     struct timeval tv, *ptv;
-    int maxfd, rc, ok;
+    int maxfd, rc, n;
     unsigned int i;
     char data[64];
 
     pth_implicit_init();
     pth_debug2("pth_poll_ev: called from thread \"%s\"", pth_current->name);
 
-    /* poll(2) semantics */
+    /* argument sanity checks */
     if (pfd == NULL)
         return pth_error(-1, EFAULT);
+    if (nfd < 0 || nfd > FD_SETSIZE)
+        return pth_error(-1, EINVAL);
 
     /* convert timeout number into a timeval structure */
     ptv = &tv;
@@ -487,7 +489,7 @@
     }
     else if (timeout > 0) {
         /* return after timeout */
-        ptv->tv_sec  = timeout / 1000;
+        ptv->tv_sec  = (timeout / 1000);
         ptv->tv_usec = (timeout % 1000) * 1000;
     }
     else
@@ -498,14 +500,19 @@
     FD_ZERO(&rfds);
     FD_ZERO(&wfds);
     FD_ZERO(&efds);
-    for(i = 0; i < nfd; i++) {
-        if (!pth_util_fd_valid(pfd[i].fd))
-            return pth_error(-1, EBADF);
+    FD_ZERO(&xfds);
+    for (i = 0; i < nfd; i++) {
+        /* convert into fd_sets but remember that BSD select(2) says
+           "the only exceptional condition detectable is out-of-band
+           data received on a socket", hence we push POLLWRBAND events
+           onto wfds instead of efds. Additionally, remember invalid
+           filedescriptors in an extra fd_set xfds. */
+        if (!pth_util_fd_valid(pfd[i].fd)) {
+            FD_SET(pfd[i].fd, &xfds);
+            continue;
+        }
         if (pfd[i].events & (POLLIN|POLLRDNORM))
             FD_SET(pfd[i].fd, &rfds);
-        /* see select(2): "the only exceptional condition detectable
-           is out-of-band data received on a socket", hence we push
-           POLLWRBAND events onto wfds instead of efds. */
         if (pfd[i].events & (POLLOUT|POLLWRNORM|POLLWRBAND))
             FD_SET(pfd[i].fd, &wfds);
         if (pfd[i].events & (POLLPRI|POLLRDBAND))
@@ -516,60 +523,64 @@
                                  POLLWRNORM|POLLWRBAND)))
             maxfd = pfd[i].fd;
     }
-    if (maxfd == -1)
-        return pth_error(-1, EINVAL);
 
-    /* examine fd sets */
-    rc = pth_select_ev(maxfd+1, &rfds, &wfds, &efds, ptv, ev_extra);
+    /* examine fd sets with pth_select(3) */
+    rc = -1;
+    if (maxfd != -1) {
+        rc = pth_select_ev(maxfd+1, &rfds, &wfds, &efds, ptv, ev_extra);
+        if (rc < 0)
+            return pth_error(-1, errno);
+        else if (rc == 0)
+            return 0;
+    }
 
-    /* establish results */
-    if (rc > 0) {
-        rc = 0;
-        for (i = 0; i < nfd; i++) {
-            ok = 0;
-            pfd[i].revents = 0;
-            if (pfd[i].fd < 0) {
+    /* POSIX.1-2001/SUSv3 compliant result establishment */
+    n = 0;
+    for (i = 0; i < nfd; i++) {
+        pfd[i].revents = 0;
+        if (FD_ISSET(pfd[i].fd, &xfds)) {
+            if (pfd[i].fd >= 0) {
                 pfd[i].revents |= POLLNVAL;
-                continue;
-            }
-            if (FD_ISSET(pfd[i].fd, &rfds)) {
-                if (pfd[i].events & POLLIN)
-                    pfd[i].revents |= POLLIN;
-                if (pfd[i].events & POLLRDNORM)
-                    pfd[i].revents |= POLLRDNORM;
-                ok++;
-                /* support for POLLHUP */
-                if (recv(pfd[i].fd, data, sizeof(data), MSG_PEEK) == -1) {
-                    if (   errno == ESHUTDOWN    || errno == ECONNRESET
-                        || errno == ECONNABORTED || errno == ENETRESET) {
-                        pfd[i].revents &= ~(POLLIN);
-                        pfd[i].revents &= ~(POLLRDNORM);
-                        pfd[i].revents |= POLLHUP;
-                        ok--;
-                    }
-                }
+                n++;
             }
-            if (FD_ISSET(pfd[i].fd, &wfds)) {
-                if (pfd[i].events & POLLOUT)
-                    pfd[i].revents |= POLLOUT;
-                if (pfd[i].events & POLLWRNORM)
-                    pfd[i].revents |= POLLWRNORM;
-                if (pfd[i].events & POLLWRBAND)
-                    pfd[i].revents |= POLLWRBAND;
-                ok++;
-            }
-            if (FD_ISSET(pfd[i].fd, &efds)) {
-                if (pfd[i].events & POLLPRI)
-                    pfd[i].revents |= POLLPRI;
-                if (pfd[i].events & POLLRDBAND)
-                    pfd[i].revents |= POLLRDBAND;
-                ok++;
+            continue;
+        }
+        if (maxfd == -1)
+            continue;
+        if (FD_ISSET(pfd[i].fd, &rfds)) {
+            if (pfd[i].events & POLLIN)
+                pfd[i].revents |= POLLIN;
+            if (pfd[i].events & POLLRDNORM)
+                pfd[i].revents |= POLLRDNORM;
+            n++;
+            /* support for POLLHUP */
+            if (   recv(pfd[i].fd, data, sizeof(data), MSG_PEEK) == -1
+                && (   errno == ESHUTDOWN    || errno == ECONNRESET
+                    || errno == ECONNABORTED || errno == ENETRESET    )) {
+                pfd[i].revents &= ~(POLLIN);
+                pfd[i].revents &= ~(POLLRDNORM);
+                pfd[i].revents |= POLLHUP;
             }
-            if (ok)
-                rc++;
+        }
+        else if (FD_ISSET(pfd[i].fd, &wfds)) {
+            if (pfd[i].events & POLLOUT)
+                pfd[i].revents |= POLLOUT;
+            if (pfd[i].events & POLLWRNORM)
+                pfd[i].revents |= POLLWRNORM;
+            if (pfd[i].events & POLLWRBAND)
+                pfd[i].revents |= POLLWRBAND;
+            n++;
+        }
+        else if (FD_ISSET(pfd[i].fd, &efds)) {
+            if (pfd[i].events & POLLPRI)
+                pfd[i].revents |= POLLPRI;
+            if (pfd[i].events & POLLRDBAND)
+                pfd[i].revents |= POLLRDBAND;
+            n++;
         }
     }
-    return rc;
+
+    return n;
 }
 
 /* Pth variant of connect(2) */

CVSTrac 2.0.1