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

This commit is contained in:
sfraser%netscape.com 2001-06-14 01:35:05 +00:00
Родитель fdd2288a50
Коммит 4bd2a71a05
1 изменённых файлов: 24 добавлений и 8 удалений

Просмотреть файл

@ -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 );