REGRESSION (r254291): [ Catalina wk2 Debug ] Flaky ASSERT on fast/images/animated-image-loop-count.html
https://bugs.webkit.org/show_bug.cgi?id=206068
<rdar://problem/58480028>

Patch by Chris Lord <clord@igalia.com> on 2020-01-16
Reviewed by Chris Dumez.

No new tests, covered by existing tests.

* platform/graphics/ImageSource.cpp:
(WebCore::ImageSource::startAsyncDecodingQueue):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@254692 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 145d497..a74d590 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,16 @@
+2020-01-16  Chris Lord  <clord@igalia.com>
+
+        REGRESSION (r254291): [ Catalina wk2 Debug ] Flaky ASSERT on fast/images/animated-image-loop-count.html
+        https://bugs.webkit.org/show_bug.cgi?id=206068
+        <rdar://problem/58480028>
+
+        Reviewed by Chris Dumez.
+
+        No new tests, covered by existing tests.
+
+        * platform/graphics/ImageSource.cpp:
+        (WebCore::ImageSource::startAsyncDecodingQueue):
+
 2020-01-16  youenn fablet  <youenn@apple.com>
 
         Add support for MediaStream video track rendering in GPUProcess
diff --git a/Source/WebCore/platform/graphics/ImageSource.cpp b/Source/WebCore/platform/graphics/ImageSource.cpp
index 5eaa732..2724d73 100644
--- a/Source/WebCore/platform/graphics/ImageSource.cpp
+++ b/Source/WebCore/platform/graphics/ImageSource.cpp
@@ -345,8 +345,11 @@
     if (hasAsyncDecodingQueue() || !isDecoderAvailable())
         return;
 
+    // Async decoding is only enabled for HTMLImageElement and CSS background images.
+    ASSERT(isMainThread());
+
     // We need to protect this, m_decodingQueue and m_decoder from being deleted while we are in the decoding loop.
-    decodingQueue().dispatch([protectedThis = makeRef(*this), protectedDecodingQueue = makeRef(decodingQueue()), protectedFrameRequestQueue = makeRef(frameRequestQueue()), protectedDecoder = makeRef(*m_decoder), sourceURL = sourceURL().string().isolatedCopy()] {
+    decodingQueue().dispatch([protectedThis = makeRef(*this), protectedDecodingQueue = makeRef(decodingQueue()), protectedFrameRequestQueue = makeRef(frameRequestQueue()), protectedDecoder = makeRef(*m_decoder), sourceURL = sourceURL().string().isolatedCopy()] () mutable {
         ImageFrameRequest frameRequest;
         Seconds minDecodingDuration = protectedThis->frameDecodingDurationForTesting();
 
@@ -371,7 +374,7 @@
                 sleep(minDecodingDuration - (MonotonicTime::now() - startingTime));
 
             // Update the cached frames on the creation thread to avoid updating the MemoryCache from a different thread.
-            protectedThis->m_runLoop.dispatch([protectedThis = protectedThis.copyRef(), protectedQueue = protectedDecodingQueue.copyRef(), protectedDecoder = protectedDecoder.copyRef(), sourceURL = sourceURL.isolatedCopy(), nativeImage = WTFMove(nativeImage), frameRequest] () mutable {
+            callOnMainThread([protectedThis = protectedThis.copyRef(), protectedQueue = protectedDecodingQueue.copyRef(), protectedDecoder = protectedDecoder.copyRef(), sourceURL = sourceURL.isolatedCopy(), nativeImage = WTFMove(nativeImage), frameRequest] () mutable {
                 // The queue may have been closed if after we got the frame NativeImage, stopAsyncDecodingQueue() was called.
                 if (protectedQueue.ptr() == protectedThis->m_decodingQueue && protectedDecoder.ptr() == protectedThis->m_decoder) {
                     ASSERT(protectedThis->m_frameCommitQueue.first() == frameRequest);
@@ -381,6 +384,9 @@
                     LOG(Images, "ImageSource::%s - %p - url: %s [frame %ld will not cached]", __FUNCTION__, protectedThis.ptr(), sourceURL.utf8().data(), frameRequest.index);
             });
         }
+
+        // Ensure destruction happens on creation thread.
+        callOnMainThread([protectedThis = WTFMove(protectedThis), protectedQueue = WTFMove(protectedDecodingQueue), protectedDecoder = WTFMove(protectedDecoder)] () mutable { });
     });
 }