Title: [183801] trunk/Source/WebKit2
Revision
183801
Author
[email protected]
Date
2015-05-05 01:20:47 -0700 (Tue, 05 May 2015)

Log Message

[SOUP] Network Cache: IOChannel operations are not sent to the right thread
https://bugs.webkit.org/show_bug.cgi?id=144542

Reviewed by Darin Adler.

We are ignoring the given WorkQueue and running the async
operations in the current thread. Check the given WorkQueue
instead and schedule the operation to the given queue. If the
given queue is nullptr, which means the operation should be run in
the main context, the operation is run directly if the current
context is the main one or sent to the main context using a
GMainLoopSource.

Fixes crashes due to asserts when running disk-cache layout tests
in a Debug build.

* NetworkProcess/cache/NetworkCacheIOChannel.h:
* NetworkProcess/cache/NetworkCacheIOChannelSoup.cpp:
(WebKit::NetworkCache::runTaskInQueue):
(WebKit::NetworkCache::IOChannel::read):
(WebKit::NetworkCache::IOChannel::readSync):
(WebKit::NetworkCache::IOChannel::write):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (183800 => 183801)


--- trunk/Source/WebKit2/ChangeLog	2015-05-05 08:16:16 UTC (rev 183800)
+++ trunk/Source/WebKit2/ChangeLog	2015-05-05 08:20:47 UTC (rev 183801)
@@ -1,3 +1,28 @@
+2015-05-05  Carlos Garcia Campos  <[email protected]>
+
+        [SOUP] Network Cache: IOChannel operations are not sent to the right thread
+        https://bugs.webkit.org/show_bug.cgi?id=144542
+
+        Reviewed by Darin Adler.
+
+        We are ignoring the given WorkQueue and running the async
+        operations in the current thread. Check the given WorkQueue
+        instead and schedule the operation to the given queue. If the
+        given queue is nullptr, which means the operation should be run in
+        the main context, the operation is run directly if the current
+        context is the main one or sent to the main context using a
+        GMainLoopSource.
+
+        Fixes crashes due to asserts when running disk-cache layout tests
+        in a Debug build.
+
+        * NetworkProcess/cache/NetworkCacheIOChannel.h:
+        * NetworkProcess/cache/NetworkCacheIOChannelSoup.cpp:
+        (WebKit::NetworkCache::runTaskInQueue):
+        (WebKit::NetworkCache::IOChannel::read):
+        (WebKit::NetworkCache::IOChannel::readSync):
+        (WebKit::NetworkCache::IOChannel::write):
+
 2015-05-04  Dan Bernstein  <[email protected]>
 
         WebKit always goes through LaunchServices for main frame navigation actions

Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheIOChannel.h (183800 => 183801)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheIOChannel.h	2015-05-05 08:16:16 UTC (rev 183800)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheIOChannel.h	2015-05-05 08:20:47 UTC (rev 183801)
@@ -60,6 +60,12 @@
 private:
     IOChannel(const String& filePath, IOChannel::Type);
 
+#if USE(SOUP)
+    void read(size_t offset, size_t, std::function<void (Data&, int error)>);
+    void readSync(size_t offset, size_t, std::function<void (Data&, int error)>);
+    void write(size_t offset, const Data&, std::function<void (int error)>);
+#endif
+
     String m_path;
     Type m_type;
 

Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheIOChannelSoup.cpp (183800 => 183801)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheIOChannelSoup.cpp	2015-05-05 08:16:16 UTC (rev 183800)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheIOChannelSoup.cpp	2015-05-05 08:20:47 UTC (rev 183801)
@@ -29,6 +29,8 @@
 #if ENABLE(NETWORK_CACHE)
 
 #include "NetworkCacheFileSystemPosix.h"
+#include <wtf/gobject/GMainLoopSource.h>
+#include <wtf/gobject/GMutexLocker.h>
 #include <wtf/gobject/GUniquePtr.h>
 
 namespace WebKit {
@@ -68,6 +70,17 @@
     return adoptRef(*new IOChannel(filePath, type));
 }
 
+static inline void runTaskInQueue(std::function<void ()> task, WorkQueue* queue)
+{
+    if (queue) {
+        queue->dispatch(task);
+        return;
+    }
+
+    // Using nullptr as queue submits the result to the main context.
+    GMainLoopSource::scheduleAndDeleteOnDestroy("[WebKit] IOChannel task", task);
+}
+
 static void fillDataFromReadBuffer(SoupBuffer* readBuffer, size_t size, Data& data)
 {
     GRefPtr<SoupBuffer> buffer;
@@ -125,7 +138,7 @@
         reinterpret_cast<GAsyncReadyCallback>(inputStreamReadReadyCallback), asyncData.release());
 }
 
-void IOChannel::read(size_t offset, size_t size, WorkQueue*, std::function<void (Data&, int error)> completionHandler)
+void IOChannel::read(size_t offset, size_t size, std::function<void (Data&, int error)> completionHandler)
 {
     ASSERT(m_inputStream);
 
@@ -139,8 +152,16 @@
         reinterpret_cast<GAsyncReadyCallback>(inputStreamReadReadyCallback), asyncData);
 }
 
+void IOChannel::read(size_t offset, size_t size, WorkQueue* queue, std::function<void (Data&, int error)> completionHandler)
+{
+    RefPtr<IOChannel> channel(this);
+    runTaskInQueue([channel, offset, size, completionHandler] {
+        channel->read(offset, size, completionHandler);
+    }, queue);
+}
+
 // FIXME: It would be better to do without this.
-void IOChannel::readSync(size_t offset, size_t size, WorkQueue*, std::function<void (Data&, int error)> completionHandler)
+void IOChannel::readSync(size_t offset, size_t size, std::function<void (Data&, int error)> completionHandler)
 {
     ASSERT(m_inputStream);
     size_t bufferSize = std::min(size, gDefaultReadBufferSize);
@@ -170,6 +191,20 @@
     completionHandler(data, 0);
 }
 
+void IOChannel::readSync(size_t offset, size_t size, WorkQueue* queue, std::function<void (Data&, int error)> completionHandler)
+{
+    static GMutex mutex;
+    static GCond condition;
+
+    WTF::GMutexLocker<GMutex> lock(mutex);
+    RefPtr<IOChannel> channel(this);
+    runTaskInQueue([channel, offset, size, completionHandler] {
+        channel->readSync(offset, size, completionHandler);
+        g_cond_signal(&condition);
+    }, queue);
+    g_cond_wait(&condition, &mutex);
+}
+
 struct WriteAsyncData {
     RefPtr<IOChannel> channel;
     GRefPtr<SoupBuffer> buffer;
@@ -198,7 +233,7 @@
         reinterpret_cast<GAsyncReadyCallback>(outputStreamWriteReadyCallback), asyncData.release());
 }
 
-void IOChannel::write(size_t offset, const Data& data, WorkQueue*, std::function<void (int error)> completionHandler)
+void IOChannel::write(size_t offset, const Data& data, std::function<void (int error)> completionHandler)
 {
     ASSERT(m_outputStream || m_ioStream);
 
@@ -209,6 +244,14 @@
         reinterpret_cast<GAsyncReadyCallback>(outputStreamWriteReadyCallback), asyncData);
 }
 
+void IOChannel::write(size_t offset, const Data& data, WorkQueue* queue, std::function<void (int error)> completionHandler)
+{
+    RefPtr<IOChannel> channel(this);
+    runTaskInQueue([channel, offset, data, completionHandler] {
+        channel->write(offset, data, completionHandler);
+    }, queue);
+}
+
 } // namespace NetworkCache
 } // namespace WebKit
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to