summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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)