diff options
-rw-r--r-- | pr/src/md/mac/macsockotpt.c | 53 |
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) |