зеркало из https://github.com/mozilla/gecko-dev.git
Bug 910881 - Do not call RasterImage::DoError off the main thread. r=jdm
--HG-- extra : rebase_source : 9d76763242a351dfbdcf8a35db98a5dceed0d838
This commit is contained in:
Родитель
5a86d36e71
Коммит
2ef014c792
|
@ -401,6 +401,7 @@ RasterImage::RasterImage(imgStatusTracker* aStatusTracker,
|
|||
mFinishing(false),
|
||||
mInUpdateImageContainer(false),
|
||||
mWantFullDecode(false),
|
||||
mPendingError(false),
|
||||
mScaleRequest(nullptr)
|
||||
{
|
||||
// Set up the discard tracker node.
|
||||
|
@ -2822,13 +2823,19 @@ RasterImage::DoError()
|
|||
if (mError)
|
||||
return;
|
||||
|
||||
// We can't safely handle errors off-main-thread, so dispatch a worker to do it.
|
||||
if (!NS_IsMainThread()) {
|
||||
HandleErrorWorker::DispatchIfNeeded(this);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're mid-decode, shut down the decoder.
|
||||
if (mDecoder) {
|
||||
MutexAutoLock lock(mDecodingMutex);
|
||||
FinishedSomeDecoding(eShutdownIntent_Error);
|
||||
}
|
||||
|
||||
// Put the container in an error state
|
||||
// Put the container in an error state.
|
||||
mError = true;
|
||||
|
||||
if (mDecodeRequest) {
|
||||
|
@ -2841,6 +2848,30 @@ RasterImage::DoError()
|
|||
LOG_CONTAINER_ERROR;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
RasterImage::HandleErrorWorker::DispatchIfNeeded(RasterImage* aImage)
|
||||
{
|
||||
if (!aImage->mPendingError) {
|
||||
aImage->mPendingError = true;
|
||||
nsRefPtr<HandleErrorWorker> worker = new HandleErrorWorker(aImage);
|
||||
NS_DispatchToMainThread(worker);
|
||||
}
|
||||
}
|
||||
|
||||
RasterImage::HandleErrorWorker::HandleErrorWorker(RasterImage* aImage)
|
||||
: mImage(aImage)
|
||||
{
|
||||
MOZ_ASSERT(mImage, "Should have image");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RasterImage::HandleErrorWorker::Run()
|
||||
{
|
||||
mImage->DoError();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIInputStream callback to copy the incoming image data directly to the
|
||||
// RasterImage without processing. The RasterImage is passed as the closure.
|
||||
// Always reads everything it gets, even if the data is erroneous.
|
||||
|
@ -3188,6 +3219,7 @@ RasterImage::DecodePool::DecodeJob::Run()
|
|||
// this request to the back of the list.
|
||||
else if (mImage->mDecoder &&
|
||||
!mImage->mError &&
|
||||
!mImage->mPendingError &&
|
||||
!mImage->IsDecodeFinished() &&
|
||||
bytesDecoded < mRequest->mBytesToDecode &&
|
||||
bytesDecoded > 0) {
|
||||
|
|
|
@ -667,6 +667,11 @@ private: // data
|
|||
// off a full decode.
|
||||
bool mWantFullDecode:1;
|
||||
|
||||
// Set when a decode worker detects an error off-main-thread. Once the error
|
||||
// is handled on the main thread, mError is set, but mPendingError is used to
|
||||
// stop decode work immediately.
|
||||
bool mPendingError:1;
|
||||
|
||||
// Decoding
|
||||
nsresult WantDecodedFrames();
|
||||
nsresult SyncDecode();
|
||||
|
@ -699,8 +704,28 @@ private: // data
|
|||
|
||||
nsresult ShutdownDecoder(eShutdownIntent aIntent);
|
||||
|
||||
// Helpers
|
||||
// Error handling.
|
||||
void DoError();
|
||||
|
||||
class HandleErrorWorker : public nsRunnable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Called from decoder threads when DoError() is called, since errors can't
|
||||
* be handled safely off-main-thread. Dispatches an event which reinvokes
|
||||
* DoError on the main thread if there isn't one already pending.
|
||||
*/
|
||||
static void DispatchIfNeeded(RasterImage* aImage);
|
||||
|
||||
NS_IMETHOD Run();
|
||||
|
||||
private:
|
||||
HandleErrorWorker(RasterImage* aImage);
|
||||
|
||||
nsRefPtr<RasterImage> mImage;
|
||||
};
|
||||
|
||||
// Helpers
|
||||
bool CanDiscard();
|
||||
bool CanForciblyDiscard();
|
||||
bool DiscardingActive();
|
||||
|
|
Загрузка…
Ссылка в новой задаче