summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsfraser%netscape.com <devnull@localhost>2001-06-14 01:33:06 +0000
committersfraser%netscape.com <devnull@localhost>2001-06-14 01:33:06 +0000
commit723ab59a48c9050943c6b7825f81c0a1c383b197 (patch)
tree2fcb5ee8ae60df9a2c3f27869d74183602458ac6
parentde0c3886ad99646ac6a9b5eaac2fbc5a467b889c (diff)
downloadnspr-hg-723ab59a48c9050943c6b7825f81c0a1c383b197.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.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/pr/src/md/mac/macsockotpt.c b/pr/src/md/mac/macsockotpt.c
index 159a0db2..f8c454a9 100644
--- a/pr/src/md/mac/macsockotpt.c
+++ b/pr/src/md/mac/macsockotpt.c
@@ -1391,7 +1391,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);
@@ -1410,15 +1412,20 @@ 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
- PrepareForAsyncCompletion(me, fd->secret->md.osfd);
+ disabledNotifications = OTEnterNotifier(endpoint);
+ PrepareForAsyncCompletion(me, fd->secret->md.osfd);
}
}
while(1);
@@ -1439,19 +1446,23 @@ 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
- PrepareForAsyncCompletion(me, fd->secret->md.osfd);
+ disabledNotifications = OTEnterNotifier(endpoint);
+ PrepareForAsyncCompletion(me, fd->secret->md.osfd);
}
}
// Retry read if we had to wait for data to show up.
@@ -1459,11 +1470,16 @@ 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 );
bytesLeft -= result;