Fix for bug 168831: PR_Poll on mac ignoring data buffered in io layers. module r=wtc. a=be/adt. MOZILLA_1_0_BRANCH MOZILLA_1_0_20021107_TAG MOZILLA_1_0_20021114_TAG MOZILLA_1_0_20021120_TAG MOZILLA_1_0_2_RELEASE NETSCAPE_7_01_RTM_RELEASE NETSCAPE_7_02_RELEASE
authorsfraser%netscape.com
Thu, 31 Oct 2002 02:28:33 +0000
branchMOZILLA_1_0_BRANCH
changeset 2565 e555b2b056a5
parent 2466 f9bf8ec4b993
child 2566 1d1261151a73
push idunknown
push userunknown
push dateunknown
reviewerswtc, be, adt
bugs168831
Fix for bug 168831: PR_Poll on mac ignoring data buffered in io layers. module r=wtc. a=be/adt.
pr/src/md/mac/macsockotpt.c
--- a/pr/src/md/mac/macsockotpt.c
+++ b/pr/src/md/mac/macsockotpt.c
@@ -1771,16 +1771,18 @@ static PRInt32 CheckPollDescMethods(PRPo
     
     for (pd = pds, epd = pd + npds, readFlag = outReadFlags, writeFlag = outWriteFlags;
         pd < epd;
         pd++, readFlag++, writeFlag++)
     {
         PRInt16  in_flags_read = 0,  in_flags_write = 0;
         PRInt16 out_flags_read = 0, out_flags_write = 0;
 
+        pd->out_flags = 0;
+
         if (NULL == pd->fd || pd->in_flags == 0) continue;
 
         if (pd->in_flags & PR_POLL_READ)
         {
             in_flags_read = (pd->fd->methods->poll)(
                 pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
         }
 
@@ -1818,24 +1820,27 @@ static PRInt32 CheckPollDescEndpoints(PR
     {
         PRFileDesc *bottomFD;
         PRBool      readReady, writeReady, exceptReady;
         PRInt16     in_flags_read = *readFlag;
         PRInt16     in_flags_write = *writeFlag;
 
         if (NULL == pd->fd || pd->in_flags == 0) continue;
 
+        if ((pd->in_flags & ~pd->out_flags) == 0) {
+            ready++;
+            continue;
+        }
+
         bottomFD = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
         /* bottomFD can be NULL for pollable sockets */
         if (bottomFD)
         {
             if (_PR_FILEDESC_OPEN == bottomFD->secret->state)
             {
-                pd->out_flags = 0;  /* pre-condition */
-
                 if (GetState(bottomFD, &readReady, &writeReady, &exceptReady))
                 {
                     if (readReady)
                     {
                         if (in_flags_read & PR_POLL_READ)
                             pd->out_flags |= PR_POLL_READ;
                         if (in_flags_write & PR_POLL_READ)
                             pd->out_flags |= PR_POLL_WRITE;
@@ -1846,18 +1851,18 @@ static PRInt32 CheckPollDescEndpoints(PR
                             pd->out_flags |= PR_POLL_READ;
                         if (in_flags_write & PR_POLL_WRITE)
                             pd->out_flags |= PR_POLL_WRITE;
                     }
                     if (exceptReady && (pd->in_flags & PR_POLL_EXCEPT))
                     {
                         pd->out_flags |= PR_POLL_EXCEPT;
                     }
-                    if (0 != pd->out_flags) ready++;
                 }
+                if (0 != pd->out_flags) ready++;
             }
             else    /* bad state */
             {
                 ready += 1;  /* this will cause an abrupt return */
                 pd->out_flags = PR_POLL_NVAL;  /* bogii */
             }
         }
     }
@@ -1943,23 +1948,24 @@ PRInt32 _MD_poll(PRPollDesc *pds, PRIntn
             PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
             return -1;
         }
         
         readFlags = ioFlags;
         writeFlags = &ioFlags[npds];
     }
 
-    if (timeout != PR_INTERVAL_NO_WAIT) {
+    // we have to be outside the lock when calling this, since
+    // it can call arbitrary user code (including other socket
+    // entry points)
+    ready = CheckPollDescMethods(pds, npds, readFlags, writeFlags);
+
+    if (!ready && timeout != PR_INTERVAL_NO_WAIT) {
         intn        is;
         
-        // we have to be outside the lock when calling this, since
-        // it can call arbitrary user code (including other socket
-        // entry points)
-        (void)CheckPollDescMethods(pds, npds, readFlags, writeFlags);
 
         _PR_INTSOFF(is);
         PR_Lock(thread->md.asyncIOLock);
         PrepareForAsyncCompletion(thread, 0);
 
         SetDescPollThread(pds, npds, thread);
 
         (void)CheckPollDescEndpoints(pds, npds, readFlags, writeFlags);
@@ -1970,27 +1976,24 @@ PRInt32 _MD_poll(PRPollDesc *pds, PRIntn
         ready = CountReadyPollDescs(pds, npds);
 
         if (ready == 0) {
             WaitOnThisThread(thread, timeout);
 
             // since we may have been woken by a pollable event firing,
             // we have to check both poll methods and endpoints.
             (void)CheckPollDescMethods(pds, npds, readFlags, writeFlags);
-            (void)CheckPollDescEndpoints(pds, npds, readFlags, writeFlags);
-            ready = CountReadyPollDescs(pds, npds);
+            ready = CheckPollDescEndpoints(pds, npds, readFlags, writeFlags);
         }
         
         thread->io_pending = PR_FALSE;
         SetDescPollThread(pds, npds, NULL);
     }
     else {
-        (void)CheckPollDescMethods(pds, npds, readFlags, writeFlags);
-        (void)CheckPollDescEndpoints(pds, npds, readFlags, writeFlags);
-        ready = CountReadyPollDescs(pds, npds);    
+        ready = CheckPollDescEndpoints(pds, npds, readFlags, writeFlags);
     }
 
     if (readFlags != readFlagsArray)
         PR_Free(ioFlags);
     
     return ready;
 }