summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsfraser%netscape.com <devnull@localhost>2001-06-14 01:35:05 +0000
committersfraser%netscape.com <devnull@localhost>2001-06-14 01:35:05 +0000
commit5429f36e7da3facc36cee7e250103e85bda4ce30 (patch)
treeb7914258ef7bba25339feaeb565054a483a53879
parent87adadd8f7ce537e9bab9ef63aa8af0708674cef (diff)
downloadnspr-hg-5429f36e7da3facc36cee7e250103e85bda4ce30.tar.gz
Fix for bug 85514 -- use OTEnter/LeaveNotifer calls to fix synchronization problem caused by the OT notifier firing while we are inside OTSnd or OTRcv. r=gordon, wtc. a=blizzard
-rw-r--r--pr/src/md/mac/macsockotpt.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/pr/src/md/mac/macsockotpt.c b/pr/src/md/mac/macsockotpt.c
index 68c07367..00cc9022 100644
--- a/pr/src/md/mac/macsockotpt.c
+++ b/pr/src/md/mac/macsockotpt.c
@@ -1408,7 +1408,9 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount,
goto ErrorExit;
}
- while (bytesLeft > 0) {
+ while (bytesLeft > 0)
+ {
+ Boolean disabledNotifications = OTEnterNotifier(endpoint);
PrepareForAsyncCompletion(me, fd->secret->md.osfd);
@@ -1427,14 +1429,19 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount,
if (result != kOTFlowErr)
break;
- // Blocking write, but the pipe is full. Wait for an event,
- // hoping that it's a T_GODATA event.
+ // Blocking write, but the pipe is full. Turn notifications on and
+ // wait for an event, hoping that it's a T_GODATA event.
+ if (disabledNotifications) {
+ OTLeaveNotifier(endpoint);
+ disabledNotifications = false;
+ }
WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
result = me->md.osErrCode;
if (result != kOTNoError) // got interrupted, or some other error
break;
// Prepare to loop back and try again
+ disabledNotifications = OTEnterNotifier(endpoint);
PrepareForAsyncCompletion(me, fd->secret->md.osfd);
}
}
@@ -1456,18 +1463,22 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount,
OSErr tmpResult;
tmpResult = OTCountDataBytes(endpoint, &count);
fd->secret->md.readReady = ((tmpResult == kOTNoError) && (count > 0));
-
break;
}
- // Blocking read, but no data available. Wait for an event
- // on this endpoint, and hope that we get a T_DATA event.
+ // Blocking read, but no data available. Turn notifications on and
+ // wait for an event on this endpoint, and hope that we get a T_DATA event.
+ if (disabledNotifications) {
+ OTLeaveNotifier(endpoint);
+ disabledNotifications = false;
+ }
WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
result = me->md.osErrCode;
if (result != kOTNoError) // interrupted thread, etc.
break;
// Prepare to loop back and try again
+ disabledNotifications = OTEnterNotifier(endpoint);
PrepareForAsyncCompletion(me, fd->secret->md.osfd);
}
}
@@ -1476,10 +1487,15 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount,
}
me->io_pending = PR_FALSE;
+
if (opCode == kSTREAM_SEND)
- fd->secret->md.write.thread = nil;
+ fd->secret->md.write.thread = NULL;
else
- fd->secret->md.read.thread = nil;
+ fd->secret->md.read.thread = NULL;
+
+ // turn notifications back on
+ if (disabledNotifications)
+ OTLeaveNotifier(endpoint);
if (result > 0) {
buf = (void *) ( (UInt32) buf + (UInt32)result );