Commit a2f7d4c8 authored by beidson@apple.com's avatar beidson@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):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@160033 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 12d5e64d
2013-12-03 Brady Eidson <beidson@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_horton@apple.com>
Remove TiledCoreAnimationDrawingArea(Proxy)IOS
......
......@@ -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::shared()
}
DatabaseProcess::DatabaseProcess()
: m_queue(adoptRef(*WorkQueue::create("com.apple.WebKit.DatabaseProcess").leakRef()))
{
}
......
......@@ -31,6 +31,8 @@
#include "ChildProcess.h"
#include "UniqueIDBDatabaseIdentifier.h"
class WorkQueue;
namespace WebKit {
class DatabaseToWebProcessConnection;
......@@ -48,6 +50,8 @@ public:
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 @@ private:
Vector<RefPtr<DatabaseToWebProcessConnection>> m_databaseToWebProcessConnections;
Ref<WorkQueue> m_queue;
String m_indexedDatabaseDirectory;
HashMap<UniqueIDBDatabaseIdentifier, RefPtr<UniqueIDBDatabase>> m_idbDatabases;
......
......@@ -67,7 +67,7 @@ void DatabaseProcessIDBConnection::getOrEstablishIDBDatabaseMetadata(uint64_t re
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));
});
}
......
......@@ -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 @@ namespace WebKit {
UniqueIDBDatabase::UniqueIDBDatabase(const UniqueIDBDatabaseIdentifier& identifier)
: m_identifier(identifier)
, m_processingDatabaseQueueRequests(false)
{
}
......@@ -60,13 +63,66 @@ void UniqueIDBDatabase::unregisterConnection(DatabaseProcessIDBConnection& conne
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
......
......@@ -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 @@ struct IDBDatabaseMetadata;
namespace WebKit {
class AsyncRequest;
class DatabaseProcessIDBConnection;
struct SecurityOriginData;
......@@ -59,7 +61,7 @@ public:
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 @@ private:
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
......
......@@ -38,8 +38,9 @@ static uint64_t generateRequestID()
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 @@ AsyncRequest::~AsyncRequest()
ASSERT(!m_abortHandler);
}
void AsyncRequest::setAbortHandler(std::function<void()> handler)
void AsyncRequest::setAbortHandler(std::function<void ()> handler)
{
m_abortHandler = std::move(handler);
}
......
......@@ -39,16 +39,16 @@ public:
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,7 +59,12 @@ class AsyncRequestImpl FINAL : public AsyncRequest {
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()
......@@ -67,15 +72,16 @@ public:
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 @@ private:
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;
}
......
......@@ -101,7 +101,7 @@ void WebIDBServerConnection::didGetOrEstablishIDBDatabaseMetadata(uint64_t reque
RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
ASSERT(serverRequest);
serverRequest->requestCompleted(metadata, success);
serverRequest->completeRequest(metadata, success);
}
void WebIDBServerConnection::close()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment