Bug 1287691 (Part 1) - Expose yielding to decoding tasks. r=edwin

This commit is contained in:
Seth Fowler
2016-07-18 23:46:35 -07:00
parent 12cb1cb8ee
commit 60b6148b2d
4 changed files with 68 additions and 27 deletions

View File

@@ -85,20 +85,31 @@ DecodingTask::DecodingTask(NotNull<Decoder*> aDecoder)
void
DecodingTask::Run()
{
nsresult rv = mDecoder->Decode(WrapNotNull(this));
while (true) {
LexerResult result = mDecoder->Decode(WrapNotNull(this));
if (result.is<TerminalState>()) {
NotifyDecodeComplete(mDecoder);
return; // We're done.
}
MOZ_ASSERT(result.is<Yield>());
if (NS_SUCCEEDED(rv) && !mDecoder->GetDecodeDone()) {
// Notify for the progress we've made so far.
if (mDecoder->HasProgress()) {
NotifyProgress(mDecoder);
}
// We don't need to do anything else for this case. The decoder itself will
// ensure that we get reenqueued when more data is available.
return;
}
if (result == LexerResult(Yield::NEED_MORE_DATA)) {
// We can't make any more progress right now. The decoder itself will
// ensure that we get reenqueued when more data is available; just return
// for now.
return;
}
NotifyDecodeComplete(mDecoder);
// Right now we don't do anything special for other kinds of yields, so just
// keep working.
}
}
bool
@@ -122,17 +133,22 @@ MetadataDecodingTask::MetadataDecodingTask(NotNull<Decoder*> aDecoder)
void
MetadataDecodingTask::Run()
{
nsresult rv = mDecoder->Decode(WrapNotNull(this));
LexerResult result = mDecoder->Decode(WrapNotNull(this));
if (NS_SUCCEEDED(rv) && !mDecoder->GetDecodeDone()) {
// It's important that metadata decode results are delivered atomically, so
// we'll wait until NotifyDecodeComplete() to report any progress. We don't
// need to do anything else for this case. The decoder itself will ensure
// that we get reenqueued when more data is available.
if (result.is<TerminalState>()) {
NotifyDecodeComplete(mDecoder);
return; // We're done.
}
if (result == LexerResult(Yield::NEED_MORE_DATA)) {
// We can't make any more progress right now. We also don't want to report
// any progress, because it's important that metadata decode results are
// delivered atomically. The decoder itself will ensure that we get
// reenqueued when more data is available; just return for now.
return;
}
NotifyDecodeComplete(mDecoder);
MOZ_ASSERT_UNREACHABLE("Metadata decode yielded for an unexpected reason");
}
@@ -147,7 +163,23 @@ AnonymousDecodingTask::AnonymousDecodingTask(NotNull<Decoder*> aDecoder)
void
AnonymousDecodingTask::Run()
{
mDecoder->Decode(WrapNotNull(this));
while (true) {
LexerResult result = mDecoder->Decode(WrapNotNull(this));
if (result.is<TerminalState>()) {
return; // We're done.
}
if (result == LexerResult(Yield::NEED_MORE_DATA)) {
// We can't make any more progress right now. Let the caller decide how to
// handle it.
return;
}
// Right now we don't do anything special for other kinds of yields, so just
// keep working.
MOZ_ASSERT(result.is<Yield>());
}
}
} // namespace image