From 26726f337a0f2507eddfdc6a5f5f6676cf70a919 Mon Sep 17 00:00:00 2001 From: "sfraser%netscape.com" Date: Sat, 9 Mar 2002 02:11:42 +0000 Subject: 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 | 53 ++++++++++++++++++++++++--------------------- 1 file 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) -- cgit v1.2.1