Ignore:
Timestamp:
Feb 6, 2017, 10:12:53 PM (9 years ago)
Author:
Carlos Garcia Campos
Message:

[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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/WebProcess/soup/WebKitSoupRequestInputStream.cpp

    r211734 r211773  
    2626
    2727struct AsyncReadData {
    28     AsyncReadData(GTask* task, void* buffer, gsize count)
    29         : task(task)
     28    AsyncReadData(GRefPtr<GTask>&& task, void* buffer, gsize count)
     29        : task(WTFMove(task))
    3030        , buffer(buffer)
    3131        , count(count)
     
    6464static void webkitSoupRequestInputStreamPendingReadAsyncComplete(WebKitSoupRequestInputStream* stream)
    6565{
    66     if (!stream->priv->pendingAsyncRead)
    67         return;
    68 
    69     AsyncReadData* data = stream->priv->pendingAsyncRead.get();
    70     webkitSoupRequestInputStreamReadAsyncResultComplete(data->task.get(), data->buffer, data->count);
    71     stream->priv->pendingAsyncRead = nullptr;
     66    while (stream->priv->pendingAsyncRead) {
     67        auto data = WTFMove(stream->priv->pendingAsyncRead);
     68        webkitSoupRequestInputStreamReadAsyncResultComplete(data->task.get(), data->buffer, data->count);
     69    }
    7270}
    7371
     
    103101    }
    104102
    105     stream->priv->pendingAsyncRead = std::make_unique<AsyncReadData>(task.get(), buffer, count);
     103    stream->priv->pendingAsyncRead = std::make_unique<AsyncReadData>(WTFMove(task), buffer, count);
    106104}
    107105
     
    172170{
    173171    GUniquePtr<GError> error(g_error_new(g_quark_from_string(resourceError.domain().utf8().data()), resourceError.errorCode(), "%s", resourceError.localizedDescription().utf8().data()));
    174     if (stream->priv->pendingAsyncRead) {
    175         AsyncReadData* data = stream->priv->pendingAsyncRead.get();
     172    if (auto data = WTFMove(stream->priv->pendingAsyncRead))
    176173        g_task_return_error(data->task.get(), error.release());
    177     } else {
     174    else {
    178175        stream->priv->contentLength = stream->priv->bytesReceived;
    179176        stream->priv->error = WTFMove(error);
Note: See TracChangeset for help on using the changeset viewer.