зеркало из https://github.com/mozilla/pjs.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:
Родитель
8363ca6e21
Коммит
8f7cf3781e
|
@ -1408,7 +1408,9 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount,
|
||||||
goto ErrorExit;
|
goto ErrorExit;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (bytesLeft > 0) {
|
while (bytesLeft > 0)
|
||||||
|
{
|
||||||
|
Boolean disabledNotifications = OTEnterNotifier(endpoint);
|
||||||
|
|
||||||
PrepareForAsyncCompletion(me, fd->secret->md.osfd);
|
PrepareForAsyncCompletion(me, fd->secret->md.osfd);
|
||||||
|
|
||||||
|
@ -1427,14 +1429,19 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount,
|
||||||
if (result != kOTFlowErr)
|
if (result != kOTFlowErr)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Blocking write, but the pipe is full. Wait for an event,
|
// Blocking write, but the pipe is full. Turn notifications on and
|
||||||
// hoping that it's a T_GODATA event.
|
// wait for an event, hoping that it's a T_GODATA event.
|
||||||
|
if (disabledNotifications) {
|
||||||
|
OTLeaveNotifier(endpoint);
|
||||||
|
disabledNotifications = false;
|
||||||
|
}
|
||||||
WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
|
WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
|
||||||
result = me->md.osErrCode;
|
result = me->md.osErrCode;
|
||||||
if (result != kOTNoError) // got interrupted, or some other error
|
if (result != kOTNoError) // got interrupted, or some other error
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Prepare to loop back and try again
|
// Prepare to loop back and try again
|
||||||
|
disabledNotifications = OTEnterNotifier(endpoint);
|
||||||
PrepareForAsyncCompletion(me, fd->secret->md.osfd);
|
PrepareForAsyncCompletion(me, fd->secret->md.osfd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1456,18 +1463,22 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount,
|
||||||
OSErr tmpResult;
|
OSErr tmpResult;
|
||||||
tmpResult = OTCountDataBytes(endpoint, &count);
|
tmpResult = OTCountDataBytes(endpoint, &count);
|
||||||
fd->secret->md.readReady = ((tmpResult == kOTNoError) && (count > 0));
|
fd->secret->md.readReady = ((tmpResult == kOTNoError) && (count > 0));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blocking read, but no data available. Wait for an event
|
// Blocking read, but no data available. Turn notifications on and
|
||||||
// on this endpoint, and hope that we get a T_DATA event.
|
// 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);
|
WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
|
||||||
result = me->md.osErrCode;
|
result = me->md.osErrCode;
|
||||||
if (result != kOTNoError) // interrupted thread, etc.
|
if (result != kOTNoError) // interrupted thread, etc.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Prepare to loop back and try again
|
// Prepare to loop back and try again
|
||||||
|
disabledNotifications = OTEnterNotifier(endpoint);
|
||||||
PrepareForAsyncCompletion(me, fd->secret->md.osfd);
|
PrepareForAsyncCompletion(me, fd->secret->md.osfd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1476,10 +1487,15 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount,
|
||||||
}
|
}
|
||||||
|
|
||||||
me->io_pending = PR_FALSE;
|
me->io_pending = PR_FALSE;
|
||||||
|
|
||||||
if (opCode == kSTREAM_SEND)
|
if (opCode == kSTREAM_SEND)
|
||||||
fd->secret->md.write.thread = nil;
|
fd->secret->md.write.thread = NULL;
|
||||||
else
|
else
|
||||||
fd->secret->md.read.thread = nil;
|
fd->secret->md.read.thread = NULL;
|
||||||
|
|
||||||
|
// turn notifications back on
|
||||||
|
if (disabledNotifications)
|
||||||
|
OTLeaveNotifier(endpoint);
|
||||||
|
|
||||||
if (result > 0) {
|
if (result > 0) {
|
||||||
buf = (void *) ( (UInt32) buf + (UInt32)result );
|
buf = (void *) ( (UInt32) buf + (UInt32)result );
|
||||||
|
|
Загрузка…
Ссылка в новой задаче