summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsfraser%netscape.com <devnull@localhost>2002-03-09 03:00:07 +0000
committersfraser%netscape.com <devnull@localhost>2002-03-09 03:00:07 +0000
commitf48e504dcee334bdb98d290566f3b4987ebd64b9 (patch)
tree1b9853d54a763f9c7ff7c8df1dbcce752b909756
parent26d27f7bbefbcf4e9fe5a8dbfd10b44ae184e127 (diff)
downloadnspr-hg-f48e504dcee334bdb98d290566f3b4987ebd64b9.tar.gz
Fix for bug 129364. Eliminate 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
-rw-r--r--pr/src/md/mac/macsockotpt.c55
1 files changed, 29 insertions, 26 deletions
diff --git a/pr/src/md/mac/macsockotpt.c b/pr/src/md/mac/macsockotpt.c
index e4ab43f0..79bd372b 100644
--- a/pr/src/md/mac/macsockotpt.c
+++ b/pr/src/md/mac/macsockotpt.c
@@ -1934,8 +1934,6 @@ PRInt32 _MD_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
PRThread *thread = _PR_MD_CURRENT_THREAD();
PRInt32 ready;
- intn is;
- PRBool needsToWait = PR_FALSE;
if (npds > DESCRIPTOR_FLAGS_ARRAY_SIZE)
{
@@ -1951,40 +1949,45 @@ PRInt32 _MD_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
readFlags = ioFlags;
writeFlags = &ioFlags[npds];
}
-
- (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))
- {
- PrepareForAsyncCompletion(thread, 0);
- SetDescPollThread(pds, npds, thread);
- needsToWait = PR_TRUE;
- }
+ if (timeout != PR_INTERVAL_NO_WAIT) {
+ intn is;
- PR_Unlock(thread->md.asyncIOLock);
- _PR_INTSON(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);
- if (needsToWait)
- {
- WaitOnThisThread(thread, timeout);
+ _PR_INTSOFF(is);
+ PR_Lock(thread->md.asyncIOLock);
+ PrepareForAsyncCompletion(thread, 0);
+
+ SetDescPollThread(pds, npds, thread);
- // 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);
+
+ PR_Unlock(thread->md.asyncIOLock);
+ _PR_FAST_INTSON(is);
+
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)