Bug 802390 - Gracefully handle shutting down a decoder that hasn't had a chance to do any work. r=jrmuizel

This commit is contained in:
Joe Drew 2012-11-16 11:43:24 -08:00
parent 46d5358fe4
commit da2ef18bab
4 changed files with 26 additions and 19 deletions

View File

@ -80,7 +80,7 @@ Decoder::Write(const char* aBuffer, uint32_t aCount)
}
void
Decoder::Finish()
Decoder::Finish(RasterImage::eShutdownIntent aShutdownIntent)
{
// Implementation-specific finalization
if (!HasError())
@ -114,16 +114,22 @@ Decoder::Finish()
}
}
// If we only have a data error, see if things are worth salvaging
bool salvage = !HasDecoderError() && mImage.GetNumFrames();
bool usable = true;
if (aShutdownIntent != RasterImage::eShutdownIntent_Interrupted && !HasDecoderError()) {
// If we only have a data error, we're usable if we have at least one frame.
if (mImage.GetNumFrames() == 0) {
usable = false;
}
}
// If we're salvaging, say we finished decoding
if (salvage)
mImage.DecodingComplete();
// Fire teardown notifications
if (mObserver) {
mObserver->OnStopDecode(salvage ? NS_OK : NS_ERROR_FAILURE);
// If we're usable, do exactly what we should have when the decoder
// completed.
if (usable) {
PostDecodeDone();
} else {
if (mObserver) {
mObserver->OnStopDecode(NS_ERROR_FAILURE);
}
}
}
}

View File

@ -59,7 +59,7 @@ public:
*
* Notifications Sent: TODO
*/
void Finish();
void Finish(RasterImage::eShutdownIntent aShutdownIntent);
/**
* Informs the shared decoder that all the data has been written.

View File

@ -2591,7 +2591,7 @@ RasterImage::ShutdownDecoder(eShutdownIntent aIntent)
mFinishing = true;
mInDecoder = true;
decoder->Finish();
decoder->Finish(aIntent);
mInDecoder = false;
mFinishing = false;

View File

@ -311,6 +311,14 @@ public:
// SCALE_INVALID otherwise.
void ScalingDone(ScaleRequest* request, ScaleStatus status);
// Decoder shutdown
enum eShutdownIntent {
eShutdownIntent_Done = 0,
eShutdownIntent_Interrupted = 1,
eShutdownIntent_Error = 2,
eShutdownIntent_AllCount = 3
};
private:
struct Anim
{
@ -710,13 +718,6 @@ private: // data
// will inform us when to let go of this pointer.
ScaleRequest* mScaleRequest;
// Decoder shutdown
enum eShutdownIntent {
eShutdownIntent_Done = 0,
eShutdownIntent_Interrupted = 1,
eShutdownIntent_Error = 2,
eShutdownIntent_AllCount = 3
};
nsresult ShutdownDecoder(eShutdownIntent aIntent);
// Helpers