зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
fdd2288a50
Коммит
4bd2a71a05
|
@ -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 );
|
||||
|
|
Загрузка…
Ссылка в новой задаче