Branch fix for bug 129364. Close a window of time in which notifiers could fire when we hadn't set up the polling thread on the poll descriptors, which could cause lost notifications and FTP stalls. Also revert to PR_FAST_INTSON() from PR_INTSON(), which seems to fix a permanent stall issue on Mac OS X. r=wtc, a=asa MOZILLA_0_9_9_BRANCH
authorsfraser%netscape.com
Sat, 09 Mar 2002 02:11:42 +0000
branchMOZILLA_0_9_9_BRANCH
changeset 2285 a6d81bf0639e8467b3649ddf32826db5b06bb92a
parent 2284 3a780a6b5c62fd062e14087b65e93538e0b0c5df
push idunknown
push userunknown
push dateunknown
reviewerswtc, asa
bugs129364
Branch fix for bug 129364. Close a window of time in which notifiers could fire when we hadn't set up the polling thread on the poll descriptors, which could cause lost notifications and FTP stalls. Also revert to PR_FAST_INTSON() from PR_INTSON(), which seems to fix a permanent stall issue on Mac OS X. r=wtc, a=asa
pr/src/md/mac/macsockotpt.c
--- a/pr/src/md/mac/macsockotpt.c
+++ b/pr/src/md/mac/macsockotpt.c
@@ -1929,67 +1929,70 @@ PRInt32 _MD_poll(PRPollDesc *pds, PRIntn
     
     PRInt16     *readFlags  = readFlagsArray;
     PRInt16     *writeFlags = writeFlagsArray;
 
     PRInt16     *ioFlags = NULL;
     
     PRThread    *thread = _PR_MD_CURRENT_THREAD();
     PRInt32     ready;
-    intn        is;
-    PRBool      needsToWait = PR_FALSE;
     
     if (npds > DESCRIPTOR_FLAGS_ARRAY_SIZE)
     {
         // we allocate a single double-size array. The first half is used
         // for read flags, and the second half for write flags.
         ioFlags = (PRInt16*)PR_Malloc(sizeof(PRInt16) * npds * 2);
         if (!ioFlags)
         {
             PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
             return -1;
         }
         
         readFlags = ioFlags;
         writeFlags = &ioFlags[npds];
     }
     
-    (void)CheckPollDescMethods(pds, npds, readFlags, writeFlags);
+    if (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);
-    
-    (void)CheckPollDescEndpoints(pds, npds, readFlags, writeFlags);
-    ready = CountReadyPollDescs(pds, npds);
-    
-    if ((ready == 0) && (timeout != PR_INTERVAL_NO_WAIT))
-    {
+        _PR_INTSOFF(is);
+        PR_Lock(thread->md.asyncIOLock);
         PrepareForAsyncCompletion(thread, 0);
+
         SetDescPollThread(pds, npds, thread);
-        needsToWait = PR_TRUE;
-    }    
-        
-    PR_Unlock(thread->md.asyncIOLock);
-    _PR_INTSON(is);
 
-    if (needsToWait)
-    {
-        WaitOnThisThread(thread, timeout);
+        (void)CheckPollDescEndpoints(pds, npds, readFlags, writeFlags);
+        
+        PR_Unlock(thread->md.asyncIOLock);
+        _PR_FAST_INTSON(is);
 
-        // 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);
 
+        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);
+        }
+
+        thread->io_pending = PR_FALSE;
         SetDescPollThread(pds, npds, NULL);
     }
     else {
-        thread->io_pending = PR_FALSE;
+        (void)CheckPollDescMethods(pds, npds, readFlags, writeFlags);
+        (void)CheckPollDescEndpoints(pds, npds, readFlags, writeFlags);
+        ready = CountReadyPollDescs(pds, npds);    
     }
 
     if (readFlags != readFlagsArray)
         PR_Free(ioFlags);
     
     return ready;
 }