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

Unified Diff: third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp

Issue 2057283002: Fix canvas-related crash caused by bad object teardown sequence (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix test crash Created 4 years, 6 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
Index: third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
index 58f9ba9ab4bd99dab934e43072989c8c0394c05f..cab800506185b6da6faf705effa45508d8220f1a 100644
--- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
@@ -141,9 +141,7 @@ void CanvasRenderingContext2D::unwindStateStack()
}
}
-CanvasRenderingContext2D::~CanvasRenderingContext2D()
-{
-}
+CanvasRenderingContext2D::~CanvasRenderingContext2D() { }
void CanvasRenderingContext2D::dispose()
{
@@ -186,7 +184,7 @@ void CanvasRenderingContext2D::loseContext(LostContextMode lostMode)
if (m_contextLostMode != NotLostContext)
return;
m_contextLostMode = lostMode;
- if (m_contextLostMode == SyntheticLostContext) {
+ if (m_contextLostMode == SyntheticLostContext && canvas()) {
canvas()->discardImageBuffer();
}
m_dispatchContextLostEventTimer.startOneShot(0, BLINK_FROM_HERE);
@@ -221,7 +219,7 @@ DEFINE_TRACE(CanvasRenderingContext2D)
void CanvasRenderingContext2D::dispatchContextLostEvent(Timer<CanvasRenderingContext2D>*)
{
- if (contextLostRestoredEventsEnabled()) {
+ if (canvas() && contextLostRestoredEventsEnabled()) {
Event* event = Event::createCancelable(EventTypeNames::contextlost);
canvas()->dispatchEvent(event);
if (event->defaultPrevented()) {
@@ -245,7 +243,7 @@ void CanvasRenderingContext2D::tryRestoreContextEvent(Timer<CanvasRenderingConte
return;
}
- ASSERT(m_contextLostMode == RealLostContext);
+ DCHECK(m_contextLostMode == RealLostContext);
if (canvas()->hasImageBuffer() && canvas()->buffer()->restoreSurface()) {
m_tryRestoreContextEventTimer.stop();
dispatchContextRestoredEvent(nullptr);
@@ -512,13 +510,23 @@ void CanvasRenderingContext2D::schedulePruneLocalFontCacheIfNeeded()
void CanvasRenderingContext2D::didProcessTask()
{
+ Platform::current()->currentThread()->removeTaskObserver(this);
+
+ // This should be the only place where canvas() needs to be checked for nullness
+ // because the circular refence with HTMLCanvasElement mean the canvas and the
+ // context keep each other alive as long as the pair is referenced the task
+ // observer is the only persisten refernce to this object that is not traced,
+ // so didProcessTask() may be call at a time when the canvas has been garbage
+ // collected but not the context.
+ if (!canvas())
+ return;
+
// The rendering surface needs to be prepared now because it will be too late
// to create a layer once we are in the paint invalidation phase.
canvas()->prepareSurfaceForPaintingIfNeeded();
pruneLocalFontCache(canvas()->document().canvasFontCache()->maxFonts());
m_pruneLocalFontCacheScheduled = false;
- Platform::current()->currentThread()->removeTaskObserver(this);
}
void CanvasRenderingContext2D::pruneLocalFontCache(size_t targetSize)

Powered by Google App Engine
This is Rietveld 408576698