[Soup] Long resources loaded by custom protocols sometimes never finish loading
authorcarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 Feb 2017 06:12:53 +0000 (06:12 +0000)
committercarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 Feb 2017 06:12:53 +0000 (06:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=167890

Reviewed by Michael Catanzaro.

It's another bug that has appeared in WebKitSoupRequestInputStream after moving the custom protocols handling to
the main thread. The problem is that webkitSoupRequestInputStreamPendingReadAsyncComplete invalidates
pendingAsyncRead after calling webkitSoupRequestInputStreamReadAsyncResultComplete, but in some cases
webkitSoupRequestInputStreamReadAsyncResultComplete completes the task in the same run loop iteration. In that
case webkitSoupRequestInputStreamReadAsync is called again creating a new AsyncReadData that is destroyed right
after webkitSoupRequestInputStreamReadAsyncResultComplete returns.

* WebProcess/soup/WebKitSoupRequestInputStream.cpp:
(AsyncReadData::AsyncReadData): Use an rvalue reference for the task.
(webkitSoupRequestInputStreamPendingReadAsyncComplete): Use WTFMove to ensure pendingAsyncRead is cleared before
webkitSoupRequestInputStreamReadAsyncResultComplete is called, and continue processing pending requests if there
are new ones after webkitSoupRequestInputStreamReadAsyncResultComplete.
(webkitSoupRequestInputStreamReadAsync): Use WTFMove to transfer the task to AsyncReadData.
(webkitSoupRequestInputStreamDidFailWithError): Use WTFMove to ensure pendingAsyncRead is cleared.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@211773 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/soup/WebKitSoupRequestInputStream.cpp

index 88c9b03..cf5323b 100644 (file)
@@ -1,3 +1,25 @@
+2017-02-06  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [Soup] Long resources loaded by custom protocols sometimes never finish loading
+        https://bugs.webkit.org/show_bug.cgi?id=167890
+
+        Reviewed by Michael Catanzaro.
+
+        It's another bug that has appeared in WebKitSoupRequestInputStream after moving the custom protocols handling to
+        the main thread. The problem is that webkitSoupRequestInputStreamPendingReadAsyncComplete invalidates
+        pendingAsyncRead after calling webkitSoupRequestInputStreamReadAsyncResultComplete, but in some cases
+        webkitSoupRequestInputStreamReadAsyncResultComplete completes the task in the same run loop iteration. In that
+        case webkitSoupRequestInputStreamReadAsync is called again creating a new AsyncReadData that is destroyed right
+        after webkitSoupRequestInputStreamReadAsyncResultComplete returns.
+
+        * WebProcess/soup/WebKitSoupRequestInputStream.cpp:
+        (AsyncReadData::AsyncReadData): Use an rvalue reference for the task.
+        (webkitSoupRequestInputStreamPendingReadAsyncComplete): Use WTFMove to ensure pendingAsyncRead is cleared before
+        webkitSoupRequestInputStreamReadAsyncResultComplete is called, and continue processing pending requests if there
+        are new ones after webkitSoupRequestInputStreamReadAsyncResultComplete.
+        (webkitSoupRequestInputStreamReadAsync): Use WTFMove to transfer the task to AsyncReadData.
+        (webkitSoupRequestInputStreamDidFailWithError): Use WTFMove to ensure pendingAsyncRead is cleared.
+
 2017-02-06  Dan Bernstein  <mitz@apple.com>
 
         [iOS] -[WKWebView becomeFirstResponder] and -[WKWebView resignFirstResponder] don’t get called when non-programmatic first responder changes happen
index 78d9761..25b6c07 100644 (file)
@@ -25,8 +25,8 @@
 #include <wtf/glib/GUniquePtr.h>
 
 struct AsyncReadData {
-    AsyncReadData(GTask* task, void* buffer, gsize count)
-        : task(task)
+    AsyncReadData(GRefPtr<GTask>&& task, void* buffer, gsize count)
+        : task(WTFMove(task))
         , buffer(buffer)
         , count(count)
     {
@@ -63,12 +63,10 @@ static void webkitSoupRequestInputStreamReadAsyncResultComplete(GTask* task, voi
 
 static void webkitSoupRequestInputStreamPendingReadAsyncComplete(WebKitSoupRequestInputStream* stream)
 {
-    if (!stream->priv->pendingAsyncRead)
-        return;
-
-    AsyncReadData* data = stream->priv->pendingAsyncRead.get();
-    webkitSoupRequestInputStreamReadAsyncResultComplete(data->task.get(), data->buffer, data->count);
-    stream->priv->pendingAsyncRead = nullptr;
+    while (stream->priv->pendingAsyncRead) {
+        auto data = WTFMove(stream->priv->pendingAsyncRead);
+        webkitSoupRequestInputStreamReadAsyncResultComplete(data->task.get(), data->buffer, data->count);
+    }
 }
 
 static bool webkitSoupRequestInputStreamHasDataToRead(WebKitSoupRequestInputStream* stream)
@@ -102,7 +100,7 @@ static void webkitSoupRequestInputStreamReadAsync(GInputStream* inputStream, voi
         return;
     }
 
-    stream->priv->pendingAsyncRead = std::make_unique<AsyncReadData>(task.get(), buffer, count);
+    stream->priv->pendingAsyncRead = std::make_unique<AsyncReadData>(WTFMove(task), buffer, count);
 }
 
 static gssize webkitSoupRequestInputStreamReadFinish(GInputStream* inputStream, GAsyncResult* result, GError** error)
@@ -171,10 +169,9 @@ void webkitSoupRequestInputStreamAddData(WebKitSoupRequestInputStream* stream, c
 void webkitSoupRequestInputStreamDidFailWithError(WebKitSoupRequestInputStream* stream, const WebCore::ResourceError& resourceError)
 {
     GUniquePtr<GError> error(g_error_new(g_quark_from_string(resourceError.domain().utf8().data()), resourceError.errorCode(), "%s", resourceError.localizedDescription().utf8().data()));
-    if (stream->priv->pendingAsyncRead) {
-        AsyncReadData* data = stream->priv->pendingAsyncRead.get();
+    if (auto data = WTFMove(stream->priv->pendingAsyncRead))
         g_task_return_error(data->task.get(), error.release());
-    else {
+    else {
         stream->priv->contentLength = stream->priv->bytesReceived;
         stream->priv->error = WTFMove(error);
     }