Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(901)

Unified Diff: Source/core/svg/graphics/SVGImage.cpp

Issue 185613003: Oilpan: Delay frameDetached() so it won't dispatch event inside ~SVGImage (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: add comments Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | Source/core/svg/graphics/SVGImageChromeClient.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/svg/graphics/SVGImage.cpp
diff --git a/Source/core/svg/graphics/SVGImage.cpp b/Source/core/svg/graphics/SVGImage.cpp
index baa838bad5aa32912a161c10e01f73acbbe90b56..9fb0700d56825cc1d7b068b3bbb8abb3ceb76f94 100644
--- a/Source/core/svg/graphics/SVGImage.cpp
+++ b/Source/core/svg/graphics/SVGImage.cpp
@@ -57,16 +57,61 @@ SVGImage::SVGImage(ImageObserver* observer)
{
}
-SVGImage::~SVGImage()
-{
- if (m_page) {
- // Store m_page in a local variable, clearing m_page, so that SVGImageChromeClient knows we're destructed.
- OwnPtr<Page> currentPage = m_page.release();
- currentPage->mainFrame()->loader().frameDetached(); // Break both the loader and view references to the frame
+// Delay destruction of Page attached to SVGImage.
+// We need to call |loader().frameDetached()| before disposing a Page, however
+// the call is non-trivial and involves touching/creating on-heap objects
+// which is not possible from a GarbageCollected object finalizer.
+// To circumvent this, DelayedSVGImageDestructor will delay the call to
+// the end of current event loop.
+class DelayedSVGImageDestructor {
+public:
+ void add(PassOwnPtr<SVGImageChromeClient> chromeClient, PassOwnPtr<Page> page)
+ {
+ Entry entry;
+ entry.chromeClient = chromeClient.leakPtr();
eseidel 2014/03/10 21:49:09 Why not just use an OwnPtr and then call .clear()
+ entry.page = page.leakPtr();
+
+ m_entries.append(entry);
+ m_detachTimer.startOneShot(0.0);
+ }
+
+ static DelayedSVGImageDestructor* get()
+ {
+ DEFINE_STATIC_LOCAL(DelayedSVGImageDestructor, delayed, ());
+ return &delayed;
}
- // Verify that page teardown destroyed the Chrome
- ASSERT(!m_chromeClient || !m_chromeClient->image());
+private:
+ DelayedSVGImageDestructor()
+ : m_detachTimer(this, &DelayedSVGImageDestructor::detachTimerFired)
+ {
+ }
+
+ void detachTimerFired(Timer<DelayedSVGImageDestructor>*)
+ {
+ Vector<Entry>::const_iterator it = m_entries.begin();
+ Vector<Entry>::const_iterator itEnd = m_entries.end();
+ for (; it != itEnd; ++it) {
+ it->page->mainFrame()->loader().frameDetached();
+ delete it->page;
+ delete it->chromeClient;
+ }
+
+ m_entries.clear();
+ }
+
+ struct Entry {
+ SVGImageChromeClient* chromeClient;
+ Page* page;
+ };
+ Vector<Entry> m_entries;
+ Timer<DelayedSVGImageDestructor> m_detachTimer;
+};
+
+SVGImage::~SVGImage()
+{
+ m_chromeClient->clearImage();
+ DelayedSVGImageDestructor::get()->add(m_chromeClient.release(), m_page.release());
}
bool SVGImage::isInSVGImage(const Element* element)
« no previous file with comments | « no previous file | Source/core/svg/graphics/SVGImageChromeClient.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698