summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsfraser%netscape.com <devnull@localhost>2002-03-09 02:11:42 +0000
committersfraser%netscape.com <devnull@localhost>2002-03-09 02:11:42 +0000
commit26726f337a0f2507eddfdc6a5f5f6676cf70a919 (patch)
treebb84ac293f7cfe2838fa75a5b6d4c4dae891a0fb
parent2d4e7995224311ad46afbb6e07c710ca3c59cb52 (diff)
downloadnspr-hg-MOZILLA_0_9_9_BRANCH.tar.gz
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=asaMOZILLA_0_9_9_BRANCH
-rw-r--r--pr/src/md/mac/macsockotpt.c53
1 files changed, 28 insertions, 25 deletions
diff --git a/pr/src/md/mac/macsockotpt.c b/pr/src/md/mac/macsockotpt.c
index e4ab43f0..1f2dbe62 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)
{
@@ -1952,39 +1950,44 @@ PRInt32 _MD_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
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);
+ 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)