mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-05 16:22:53 +00:00
Bug 1371699 part 5. Fix IPCStreamSource's handling of async streams returning 0 from Available. r=bkelly
This aligns the code more closely with how the input stream pump works: 0 available bytes when the stream itself told us it's ready means the stream is at the end.
This commit is contained in:
parent
5193353a61
commit
817f0609ac
@ -190,7 +190,7 @@ void
|
||||
IPCStreamSource::Start()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(IPCStreamSource);
|
||||
DoRead();
|
||||
DoRead(ReadReason::Starting);
|
||||
}
|
||||
|
||||
void
|
||||
@ -201,7 +201,7 @@ IPCStreamSource::StartDestroy()
|
||||
}
|
||||
|
||||
void
|
||||
IPCStreamSource::DoRead()
|
||||
IPCStreamSource::DoRead(ReadReason aReadReason)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(IPCStreamSource);
|
||||
MOZ_ASSERT(mState == eActorConstructed);
|
||||
@ -215,6 +215,15 @@ IPCStreamSource::DoRead()
|
||||
static_assert(kMaxBytesPerMessage <= static_cast<uint64_t>(UINT32_MAX),
|
||||
"kMaxBytesPerMessage must cleanly cast to uint32_t");
|
||||
|
||||
// Per the nsIInputStream API, having 0 bytes available in a stream is
|
||||
// ambiguous. It could mean "no data yet, but some coming later" or it could
|
||||
// mean "EOF" (end of stream).
|
||||
//
|
||||
// If we're just starting up, we can't distinguish between those two options.
|
||||
// But if we're being notified that an async stream is ready, then the
|
||||
// first Available() call returning 0 should really mean end of stream.
|
||||
// Subsequent Available() calls, after we read some data, could mean anything.
|
||||
bool noDataMeansEOF = (aReadReason == ReadReason::Notified);
|
||||
while (true) {
|
||||
// It should not be possible to transition to closed state without
|
||||
// this loop terminating via a return.
|
||||
@ -234,7 +243,11 @@ IPCStreamSource::DoRead()
|
||||
}
|
||||
|
||||
if (available == 0) {
|
||||
Wait();
|
||||
if (noDataMeansEOF) {
|
||||
OnEnd(rv);
|
||||
} else {
|
||||
Wait();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -248,6 +261,9 @@ IPCStreamSource::DoRead()
|
||||
MOZ_ASSERT_IF(NS_FAILED(rv), bytesRead == 0);
|
||||
buffer.SetLength(bytesRead);
|
||||
|
||||
// After this point, having no data tells us nothing about EOF.
|
||||
noDataMeansEOF = false;
|
||||
|
||||
// If we read any data from the stream, send it across.
|
||||
if (!buffer.IsEmpty()) {
|
||||
SendData(buffer);
|
||||
@ -291,7 +307,7 @@ IPCStreamSource::OnStreamReady(Callback* aCallback)
|
||||
MOZ_ASSERT(aCallback == mCallback);
|
||||
mCallback->ClearSource();
|
||||
mCallback = nullptr;
|
||||
DoRead();
|
||||
DoRead(ReadReason::Notified);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -121,7 +121,11 @@ private:
|
||||
virtual bool
|
||||
Notify(dom::workers::Status aStatus) override;
|
||||
|
||||
void DoRead();
|
||||
enum class ReadReason {
|
||||
Starting, // We're trying to read because we just started off.
|
||||
Notified // We're trying to read because the streams said it's ready.
|
||||
};
|
||||
void DoRead(ReadReason aReadReason);
|
||||
|
||||
void Wait();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user