Title: [160033] trunk/Source/WebKit2
Revision
160033
Author
beid...@apple.com
Date
2013-12-03 13:21:52 -0800 (Tue, 03 Dec 2013)

Log Message

Indexed Database work should be done on a non-main queue
https://bugs.webkit.org/show_bug.cgi?id=125127

Reviewed by Darin Adler.

Add a non-main WorkQueue to the DatabaseProcess:
* DatabaseProcess/DatabaseProcess.cpp:
(WebKit::DatabaseProcess::DatabaseProcess):
(WebKit::DatabaseProcess::queue):
* DatabaseProcess/DatabaseProcess.h:

* DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
(WebKit::UniqueIDBDatabase::UniqueIDBDatabase):
(WebKit::UniqueIDBDatabase::enqueueDatabaseQueueRequest): Add an AsyncRequest to the deque then schedule performing
  the requests on the background WorkQueue.
(WebKit::UniqueIDBDatabase::processDatabaseRequestQueue): Processes all enqueued database requests.
(WebKit::UniqueIDBDatabase::getOrEstablishIDBDatabaseMetadata): Renamed from getIDBDatabaseMetadata().
(WebKit::UniqueIDBDatabase::getOrEstablishIDBDatabaseMetadataInternal): For doing i/o on a background queue/thread.
* DatabaseProcess/IndexedDB/UniqueIDBDatabase.h:

Add a creator that takes the abort handler as an argument, and rename requestedCompleted()
to completeRequest(). This makes more sense in more situations:
* Shared/AsyncRequest.cpp:
(WebKit::AsyncRequest::AsyncRequest):
(WebKit::AsyncRequest::setAbortHandler):
* Shared/AsyncRequest.h:
(WebKit::AsyncRequest::completeRequest):

Update for the AsyncRequest rename:
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp:
(WebKit::WebIDBServerConnection::didGetOrEstablishIDBDatabaseMetadata):

* DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp:
(WebKit::DatabaseProcessIDBConnection::getOrEstablishIDBDatabaseMetadata):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (160032 => 160033)


--- trunk/Source/WebKit2/ChangeLog	2013-12-03 20:58:18 UTC (rev 160032)
+++ trunk/Source/WebKit2/ChangeLog	2013-12-03 21:21:52 UTC (rev 160033)
@@ -1,3 +1,40 @@
+2013-12-03  Brady Eidson  <beid...@apple.com>
+
+        Indexed Database work should be done on a non-main queue
+        https://bugs.webkit.org/show_bug.cgi?id=125127
+
+        Reviewed by Darin Adler.
+
+        Add a non-main WorkQueue to the DatabaseProcess:
+        * DatabaseProcess/DatabaseProcess.cpp:
+        (WebKit::DatabaseProcess::DatabaseProcess):
+        (WebKit::DatabaseProcess::queue):
+        * DatabaseProcess/DatabaseProcess.h:
+
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
+        (WebKit::UniqueIDBDatabase::UniqueIDBDatabase):
+        (WebKit::UniqueIDBDatabase::enqueueDatabaseQueueRequest): Add an AsyncRequest to the deque then schedule performing
+          the requests on the background WorkQueue.
+        (WebKit::UniqueIDBDatabase::processDatabaseRequestQueue): Processes all enqueued database requests.
+        (WebKit::UniqueIDBDatabase::getOrEstablishIDBDatabaseMetadata): Renamed from getIDBDatabaseMetadata().
+        (WebKit::UniqueIDBDatabase::getOrEstablishIDBDatabaseMetadataInternal): For doing i/o on a background queue/thread.
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabase.h:
+
+        Add a creator that takes the abort handler as an argument, and rename requestedCompleted()
+        to completeRequest(). This makes more sense in more situations:
+        * Shared/AsyncRequest.cpp:
+        (WebKit::AsyncRequest::AsyncRequest):
+        (WebKit::AsyncRequest::setAbortHandler):
+        * Shared/AsyncRequest.h:
+        (WebKit::AsyncRequest::completeRequest):
+
+        Update for the AsyncRequest rename:
+        * WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp:
+        (WebKit::WebIDBServerConnection::didGetOrEstablishIDBDatabaseMetadata):
+
+        * DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp:
+        (WebKit::DatabaseProcessIDBConnection::getOrEstablishIDBDatabaseMetadata):
+
 2013-12-03  Tim Horton  <timothy_hor...@apple.com>
 
         Remove TiledCoreAnimationDrawingArea(Proxy)IOS

Modified: trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.cpp (160032 => 160033)


--- trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.cpp	2013-12-03 20:58:18 UTC (rev 160032)
+++ trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.cpp	2013-12-03 21:21:52 UTC (rev 160033)
@@ -26,13 +26,13 @@
 #include "config.h"
 #include "DatabaseProcess.h"
 
+#if ENABLE(DATABASE_PROCESS)
+
 #include "DatabaseProcessCreationParameters.h"
 #include "DatabaseProcessProxyMessages.h"
 #include "DatabaseToWebProcessConnection.h"
 #include "UniqueIDBDatabase.h"
 
-#if ENABLE(DATABASE_PROCESS)
-
 namespace WebKit {
 
 DatabaseProcess& DatabaseProcess::shared()
@@ -42,6 +42,7 @@
 }
 
 DatabaseProcess::DatabaseProcess()
+    : m_queue(adoptRef(*WorkQueue::create("com.apple.WebKit.DatabaseProcess").leakRef()))
 {
 }
 

Modified: trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.h (160032 => 160033)


--- trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.h	2013-12-03 20:58:18 UTC (rev 160032)
+++ trunk/Source/WebKit2/DatabaseProcess/DatabaseProcess.h	2013-12-03 21:21:52 UTC (rev 160033)
@@ -31,6 +31,8 @@
 #include "ChildProcess.h"
 #include "UniqueIDBDatabaseIdentifier.h"
 
+class WorkQueue;
+
 namespace WebKit {
 
 class DatabaseToWebProcessConnection;
@@ -48,6 +50,8 @@
     PassRefPtr<UniqueIDBDatabase> getOrCreateUniqueIDBDatabase(const UniqueIDBDatabaseIdentifier&);
     void removeUniqueIDBDatabase(const UniqueIDBDatabase&);
 
+    WorkQueue& queue() const { return const_cast<WorkQueue&>(m_queue.get()); }
+
 private:
     DatabaseProcess();
     ~DatabaseProcess();
@@ -70,6 +74,8 @@
 
     Vector<RefPtr<DatabaseToWebProcessConnection>> m_databaseToWebProcessConnections;
 
+    Ref<WorkQueue> m_queue;
+
     String m_indexedDatabaseDirectory;
 
     HashMap<UniqueIDBDatabaseIdentifier, RefPtr<UniqueIDBDatabase>> m_idbDatabases;

Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp (160032 => 160033)


--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp	2013-12-03 20:58:18 UTC (rev 160032)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp	2013-12-03 21:21:52 UTC (rev 160033)
@@ -67,7 +67,7 @@
     ASSERT(m_uniqueIDBDatabase);
 
     RefPtr<DatabaseProcessIDBConnection> connection(this);
-    m_uniqueIDBDatabase->getIDBDatabaseMetadata([connection, requestID](bool success, const IDBDatabaseMetadata& metadata) {
+    m_uniqueIDBDatabase->getOrEstablishIDBDatabaseMetadata([connection, requestID](bool success, const IDBDatabaseMetadata& metadata) {
         connection->send(Messages::WebIDBServerConnection::DidGetOrEstablishIDBDatabaseMetadata(requestID, success, metadata));
     });
 }

Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp (160032 => 160033)


--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp	2013-12-03 20:58:18 UTC (rev 160032)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp	2013-12-03 21:21:52 UTC (rev 160033)
@@ -28,9 +28,11 @@
 
 #if ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)
 
+#include "AsyncRequest.h"
 #include "DatabaseProcess.h"
 #include "DatabaseProcessIDBConnection.h"
 #include <WebCore/IDBDatabaseMetadata.h>
+#include <wtf/MainThread.h>
 
 using namespace WebCore;
 
@@ -38,6 +40,7 @@
 
 UniqueIDBDatabase::UniqueIDBDatabase(const UniqueIDBDatabaseIdentifier& identifier)
     : m_identifier(identifier)
+    , m_processingDatabaseQueueRequests(false)
 {
 }
 
@@ -60,13 +63,66 @@
         DatabaseProcess::shared().removeUniqueIDBDatabase(*this);
 }
 
-void UniqueIDBDatabase::getIDBDatabaseMetadata(std::function<void(bool, const WebCore::IDBDatabaseMetadata&)> completionCallback)
+void UniqueIDBDatabase::enqueueDatabaseQueueRequest(PassRefPtr<AsyncRequest> request)
 {
+    ASSERT(request);
+
+    MutexLocker locker(m_databaseQueueRequestsMutex);
+    m_databaseQueueRequests.append(request);
+
+    if (m_processingDatabaseQueueRequests)
+        return;
+
+    m_processingDatabaseQueueRequests = true;
+    DatabaseProcess::shared().queue().dispatch(bind(&UniqueIDBDatabase::processDatabaseRequestQueue, this));
+}
+
+void UniqueIDBDatabase::processDatabaseRequestQueue()
+{
+    ASSERT(m_processingDatabaseQueueRequests);
+
+    while (true) {
+        RefPtr<AsyncRequest> request;
+        {
+            MutexLocker locker(m_databaseQueueRequestsMutex);
+            if (m_databaseQueueRequests.isEmpty()) {
+                m_processingDatabaseQueueRequests = false;
+                return;
+            }
+            request = m_databaseQueueRequests.takeFirst();
+        }
+
+        request->completeRequest();
+    }
+}
+
+void UniqueIDBDatabase::getOrEstablishIDBDatabaseMetadata(std::function<void(bool, const IDBDatabaseMetadata&)> completionCallback)
+{
+    RefPtr<AsyncRequest> request = AsyncRequestImpl<>::create([completionCallback, this]() {
+        IDBDatabaseMetadata metadata;
+        bool success = getOrEstablishIDBDatabaseMetadataInternal(metadata);
+
+        RunLoop::main()->dispatch([metadata, success, completionCallback]() {
+            completionCallback(success, metadata);
+        });
+    }, [completionCallback]() {
+        RunLoop::main()->dispatch([completionCallback]() {
+            // The boolean flag to the completion callback represents whether the attempt to get/establish metadata
+            // succeeded or failed.
+            // Since we're aborting the attempt, it failed, so we always pass in false.
+            completionCallback(false, IDBDatabaseMetadata());
+        });
+    });
+
+    enqueueDatabaseQueueRequest(request.release());
+}
+
+bool UniqueIDBDatabase::getOrEstablishIDBDatabaseMetadataInternal(const WebCore::IDBDatabaseMetadata&)
+{
     // FIXME: This method is successfully called by messaging from the WebProcess, and calls back with dummy data.
     // Needs real implementation.
-
-    IDBDatabaseMetadata metadata;
-    completionCallback(false, metadata);
+    ASSERT(!isMainThread());
+    return false;
 }
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.h (160032 => 160033)


--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.h	2013-12-03 20:58:18 UTC (rev 160032)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.h	2013-12-03 21:21:52 UTC (rev 160033)
@@ -30,6 +30,7 @@
 
 #include "UniqueIDBDatabaseIdentifier.h"
 #include <functional>
+#include <wtf/Deque.h>
 #include <wtf/HashSet.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
@@ -41,6 +42,7 @@
 
 namespace WebKit {
 
+class AsyncRequest;
 class DatabaseProcessIDBConnection;
 
 struct SecurityOriginData;
@@ -59,7 +61,7 @@
     void registerConnection(DatabaseProcessIDBConnection&);
     void unregisterConnection(DatabaseProcessIDBConnection&);
 
-    void getIDBDatabaseMetadata(std::function<void(bool, const WebCore::IDBDatabaseMetadata&)> completionCallback);
+    void getOrEstablishIDBDatabaseMetadata(std::function<void(bool, const WebCore::IDBDatabaseMetadata&)> completionCallback);
 
 private:
     UniqueIDBDatabase(const UniqueIDBDatabaseIdentifier&);
@@ -67,6 +69,17 @@
     UniqueIDBDatabaseIdentifier m_identifier;
 
     HashSet<RefPtr<DatabaseProcessIDBConnection>> m_connections;
+    HashMap<uint64_t, RefPtr<AsyncRequest>> m_databaseRequests;
+
+    void enqueueDatabaseQueueRequest(PassRefPtr<AsyncRequest>);
+
+    // To be called from the database workqueue thread only
+    void processDatabaseRequestQueue();
+    bool getOrEstablishIDBDatabaseMetadataInternal(const WebCore::IDBDatabaseMetadata&);
+
+    Mutex m_databaseQueueRequestsMutex;
+    Deque<RefPtr<AsyncRequest>> m_databaseQueueRequests;
+    bool m_processingDatabaseQueueRequests;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/Shared/AsyncRequest.cpp (160032 => 160033)


--- trunk/Source/WebKit2/Shared/AsyncRequest.cpp	2013-12-03 20:58:18 UTC (rev 160032)
+++ trunk/Source/WebKit2/Shared/AsyncRequest.cpp	2013-12-03 21:21:52 UTC (rev 160033)
@@ -38,8 +38,9 @@
     return ++requestID;
 }
 
-AsyncRequest::AsyncRequest()
-    : m_requestID(generateRequestID())
+AsyncRequest::AsyncRequest(std::function<void ()> abortHandler)
+    : m_abortHandler(std::move(abortHandler))
+    , m_requestID(generateRequestID())
 {
 }
 
@@ -48,7 +49,7 @@
     ASSERT(!m_abortHandler);
 }
 
-void AsyncRequest::setAbortHandler(std::function<void()> handler)
+void AsyncRequest::setAbortHandler(std::function<void ()> handler)
 {
     m_abortHandler = std::move(handler);
 }

Modified: trunk/Source/WebKit2/Shared/AsyncRequest.h (160032 => 160033)


--- trunk/Source/WebKit2/Shared/AsyncRequest.h	2013-12-03 20:58:18 UTC (rev 160032)
+++ trunk/Source/WebKit2/Shared/AsyncRequest.h	2013-12-03 21:21:52 UTC (rev 160033)
@@ -39,16 +39,16 @@
 
     uint64_t requestID() { return m_requestID; }
 
-    void setAbortHandler(std::function<void()>);
+    void setAbortHandler(std::function<void ()>);
     void requestAborted();
-    template<typename... Arguments> void requestCompleted(Arguments&&... arguments);
+    template<typename... Arguments> void completeRequest(Arguments&&... arguments);
 
 protected:
-    AsyncRequest();
+    explicit AsyncRequest(std::function<void ()> abortHandler);
 
     virtual void clearCompletionHandler() = 0;
 
-    std::function<void()> m_abortHandler;
+    std::function<void ()> m_abortHandler;
 
 private:
     uint64_t m_requestID;
@@ -59,23 +59,29 @@
 public:
     static PassRefPtr<AsyncRequest> create(std::function<void (Arguments...)> completionHandler)
     {
-        return adoptRef(new AsyncRequestImpl<Arguments...>(std::move(completionHandler)));
+        return adoptRef(new AsyncRequestImpl<Arguments...>(std::move(completionHandler), nullptr));
     }
 
+    static PassRefPtr<AsyncRequest> create(std::function<void (Arguments...)> completionHandler, std::function<void ()> abortHandler)
+    {
+        return adoptRef(new AsyncRequestImpl<Arguments...>(std::move(completionHandler), std::move(abortHandler)));
+    }
+
     virtual ~AsyncRequestImpl()
     {
         ASSERT(!m_completionHandler);
     }
 
-    void requestCompleted(Arguments&&... arguments)
+    void completeRequest(Arguments&&... arguments)
     {
         m_completionHandler(std::forward<Arguments>(arguments)...);
         m_completionHandler = nullptr;
     }
 
 private:
-    AsyncRequestImpl(std::function<void (Arguments...)> completionHandler)
-        : m_completionHandler(std::move(completionHandler))
+    AsyncRequestImpl(std::function<void (Arguments...)> completionHandler, std::function<void ()> abortHandler)
+        : AsyncRequest(std::move(abortHandler))
+        , m_completionHandler(std::move(completionHandler))
     {
         ASSERT(m_completionHandler);
     }
@@ -88,10 +94,10 @@
     std::function<void (Arguments...)> m_completionHandler;
 };
 
-template<typename... Arguments> void AsyncRequest::requestCompleted(Arguments&&... arguments)
+template<typename... Arguments> void AsyncRequest::completeRequest(Arguments&&... arguments)
 {
     AsyncRequestImpl<Arguments...>* request = static_cast<AsyncRequestImpl<Arguments...>*>(this);
-    request->requestCompleted(std::forward<Arguments>(arguments)...);
+    request->completeRequest(std::forward<Arguments>(arguments)...);
     m_abortHandler = nullptr;
 }
 

Modified: trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp (160032 => 160033)


--- trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp	2013-12-03 20:58:18 UTC (rev 160032)
+++ trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp	2013-12-03 21:21:52 UTC (rev 160033)
@@ -101,7 +101,7 @@
     RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
     ASSERT(serverRequest);
 
-    serverRequest->requestCompleted(metadata, success);
+    serverRequest->completeRequest(metadata, success);
 }
 
 void WebIDBServerConnection::close()
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to