forked from mirrors/gecko-dev
Bug 1474900: Assert there are no pending locks when destroying the image proxy. r=tnikkel
This commit is contained in:
parent
9eb572df9c
commit
59ff5de1a2
6 changed files with 40 additions and 17 deletions
|
|
@ -150,11 +150,7 @@ imgRequestProxy::~imgRequestProxy()
|
|||
mHadDispatch);
|
||||
}
|
||||
|
||||
// Unlock the image the proper number of times if we're holding locks on
|
||||
// it. Note that UnlockImage() decrements mLockCount each time it's called.
|
||||
while (mLockCount) {
|
||||
UnlockImage();
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(!mLockCount, "Someone forgot to unlock on time?");
|
||||
|
||||
ClearAnimationConsumers();
|
||||
|
||||
|
|
|
|||
|
|
@ -407,6 +407,10 @@ TEST_F(ImageDecoders, AnimatedGIFWithFRAME_FIRST)
|
|||
// Lock the image so its surfaces don't disappear during the test.
|
||||
image->LockImage();
|
||||
|
||||
auto unlock = mozilla::MakeScopeExit([&] {
|
||||
image->UnlockImage();
|
||||
});
|
||||
|
||||
// Use GetFrame() to force a sync decode of the image, specifying FRAME_FIRST
|
||||
// to ensure that we don't get an animated decode.
|
||||
RefPtr<SourceSurface> surface =
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ function checkClone(other_listener, aRequest)
|
|||
var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||
.createScriptedObserver(listener);
|
||||
var clone = aRequest.clone(outer);
|
||||
requests.push(clone);
|
||||
requests.push({ request: clone, locked: false });
|
||||
}
|
||||
|
||||
// Ensure that all the callbacks were called on aRequest.
|
||||
|
|
@ -71,7 +71,7 @@ function secondLoadDone(oldlistener, aRequest)
|
|||
var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||
.createScriptedObserver(listener);
|
||||
var staticrequestclone = staticrequest.clone(outer);
|
||||
requests.push(staticrequestclone);
|
||||
requests.push({ request: staticrequestclone, locked: false });
|
||||
} catch(e) {
|
||||
// We can't create a static request. Most likely the request we started
|
||||
// with didn't load successfully.
|
||||
|
|
@ -92,7 +92,10 @@ function checkSecondLoad()
|
|||
var listener = new ImageListener(checkClone, secondLoadDone);
|
||||
var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||
.createScriptedObserver(listener);
|
||||
requests.push(gCurrentLoader.loadImageXPCOM(uri, null, null, "default", null, null, outer, null, 0, null));
|
||||
requests.push({
|
||||
request: gCurrentLoader.loadImageXPCOM(uri, null, null, "default", null, null, outer, null, 0, null),
|
||||
locked: false,
|
||||
});
|
||||
listener.synchronous = false;
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +133,10 @@ function checkSecondChannelLoad()
|
|||
var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||
.createScriptedObserver(listener);
|
||||
var outlistener = {};
|
||||
requests.push(gCurrentLoader.loadImageWithChannelXPCOM(channel, outer, null, outlistener));
|
||||
requests.push({
|
||||
request: gCurrentLoader.loadImageWithChannelXPCOM(channel, outer, null, outlistener),
|
||||
locked: false,
|
||||
});
|
||||
channellistener.outputListener = outlistener.value;
|
||||
|
||||
listener.synchronous = false;
|
||||
|
|
@ -152,7 +158,10 @@ function run_loadImageWithChannel_tests()
|
|||
var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||
.createScriptedObserver(listener);
|
||||
var outlistener = {};
|
||||
requests.push(gCurrentLoader.loadImageWithChannelXPCOM(channel, outer, null, outlistener));
|
||||
requests.push({
|
||||
request: gCurrentLoader.loadImageWithChannelXPCOM(channel, outer, null, outlistener),
|
||||
locked: false,
|
||||
});
|
||||
channellistener.outputListener = outlistener.value;
|
||||
|
||||
listener.synchronous = false;
|
||||
|
|
@ -172,7 +181,10 @@ function startImageCallback(otherCb)
|
|||
var listener2 = new ImageListener(null, function(foo, bar) { do_test_finished(); });
|
||||
var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||
.createScriptedObserver(listener2);
|
||||
requests.push(gCurrentLoader.loadImageXPCOM(uri, null, null, "default", null, null, outer, null, 0, null));
|
||||
requests.push({
|
||||
request: gCurrentLoader.loadImageXPCOM(uri, null, null, "default", null, null, outer, null, 0, null),
|
||||
locked: false,
|
||||
});
|
||||
listener2.synchronous = false;
|
||||
|
||||
// Now that we've started another load, chain to the callback.
|
||||
|
|
@ -184,8 +196,11 @@ var gCurrentLoader;
|
|||
|
||||
function cleanup()
|
||||
{
|
||||
for (var i = 0; i < requests.length; ++i) {
|
||||
requests[i].cancelAndForgetObserver(0);
|
||||
for (let {request, locked} of requests) {
|
||||
if (locked) {
|
||||
try { request.unlockImage() } catch (e) {}
|
||||
}
|
||||
request.cancelAndForgetObserver(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -200,10 +215,11 @@ function run_test()
|
|||
var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
|
||||
.createScriptedObserver(listener);
|
||||
var req = gCurrentLoader.loadImageXPCOM(uri, null, null, "default", null, null, outer, null, 0, null);
|
||||
requests.push(req);
|
||||
|
||||
// Ensure that we don't cause any mayhem when we lock an image.
|
||||
req.lockImage();
|
||||
|
||||
requests.push({ request: req, locked: true });
|
||||
|
||||
listener.synchronous = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,6 +182,8 @@ nsImageBoxFrame::DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDest
|
|||
nsLayoutUtils::DeregisterImageRequest(PresContext(), mImageRequest,
|
||||
&mRequestRegistered);
|
||||
|
||||
mImageRequest->UnlockImage();
|
||||
|
||||
// Release image loader first so that it's refcnt can go to zero
|
||||
mImageRequest->CancelAndForgetObserver(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ nsTreeBodyFrame::CancelImageRequests()
|
|||
nsTreeImageCacheEntry entry = iter.UserData();
|
||||
nsLayoutUtils::DeregisterImageRequest(PresContext(), entry.request,
|
||||
nullptr);
|
||||
entry.request->UnlockImage();
|
||||
entry.request->CancelAndForgetObserver(NS_BINDING_ABORTED);
|
||||
}
|
||||
}
|
||||
|
|
@ -4243,6 +4244,7 @@ nsTreeBodyFrame::RemoveImageCacheEntry(int32_t aRowIndex, nsTreeColumn* aCol)
|
|||
if (mImageCache.Get(imageSrc, &entry)) {
|
||||
nsLayoutUtils::DeregisterImageRequest(PresContext(), entry.request,
|
||||
nullptr);
|
||||
entry.request->UnlockImage();
|
||||
entry.request->CancelAndForgetObserver(NS_BINDING_ABORTED);
|
||||
mImageCache.Remove(imageSrc);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,9 +38,12 @@ class ScrollbarActivity;
|
|||
// An entry in the tree's image cache
|
||||
struct nsTreeImageCacheEntry
|
||||
{
|
||||
nsTreeImageCacheEntry() {}
|
||||
nsTreeImageCacheEntry(imgIRequest *aRequest, imgINotificationObserver *aListener)
|
||||
: request(aRequest), listener(aListener) {}
|
||||
nsTreeImageCacheEntry() = default;
|
||||
nsTreeImageCacheEntry(imgIRequest* aRequest,
|
||||
imgINotificationObserver* aListener)
|
||||
: request(aRequest)
|
||||
, listener(aListener)
|
||||
{ }
|
||||
|
||||
nsCOMPtr<imgIRequest> request;
|
||||
nsCOMPtr<imgINotificationObserver> listener;
|
||||
|
|
|
|||
Loading…
Reference in a new issue