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