2
* Copyright (C) 2019 Apple Inc. All rights reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
13
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
#include "WebIDBServer.h"
29
#include "WebIDBConnectionToClient.h"
30
#include "WebIDBServerMessages.h"
31
#include <WebCore/SQLiteDatabaseTracker.h>
32
#include <WebCore/StorageQuotaManager.h>
33
#include <wtf/threads/BinarySemaphore.h>
35
#if ENABLE(INDEXED_DATABASE)
39
Ref<WebIDBServer> WebIDBServer::create(PAL::SessionID sessionID, const String& directory, WebCore::IDBServer::IDBServer::StorageQuotaManagerSpaceRequester&& spaceRequester)
41
return adoptRef(*new WebIDBServer(sessionID, directory, WTFMove(spaceRequester)));
44
WebIDBServer::WebIDBServer(PAL::SessionID sessionID, const String& directory, WebCore::IDBServer::IDBServer::StorageQuotaManagerSpaceRequester&& spaceRequester)
45
: CrossThreadTaskHandler("com.apple.WebKit.IndexedDBServer", WTF::CrossThreadTaskHandler::AutodrainedPoolForRunLoop::Use)
47
ASSERT(RunLoop::isMain());
49
BinarySemaphore semaphore;
50
postTask([this, protectedThis = makeRef(*this), &semaphore, sessionID, directory = directory.isolatedCopy(), spaceRequester = WTFMove(spaceRequester)] () mutable {
51
m_server = makeUnique<WebCore::IDBServer::IDBServer>(sessionID, directory, WTFMove(spaceRequester));
57
void WebIDBServer::closeAndDeleteDatabasesModifiedSince(WallTime modificationTime, CompletionHandler<void()>&& callback)
59
ASSERT(RunLoop::isMain());
61
postTask([this, protectedThis = makeRef(*this), modificationTime, callback = WTFMove(callback)]() mutable {
62
ASSERT(!RunLoop::isMain());
64
LockHolder locker(m_server->lock());
65
m_server->closeAndDeleteDatabasesModifiedSince(modificationTime);
66
postTaskReply(CrossThreadTask([callback = WTFMove(callback)]() mutable {
72
void WebIDBServer::closeAndDeleteDatabasesForOrigins(const Vector<WebCore::SecurityOriginData>& originDatas, CompletionHandler<void()>&& callback)
74
ASSERT(RunLoop::isMain());
76
postTask([this, protectedThis = makeRef(*this), originDatas = originDatas.isolatedCopy(), callback = WTFMove(callback)] () mutable {
77
ASSERT(!RunLoop::isMain());
79
LockHolder locker(m_server->lock());
80
m_server->closeAndDeleteDatabasesForOrigins(originDatas);
81
postTaskReply(CrossThreadTask([callback = WTFMove(callback)]() mutable {
87
void WebIDBServer::suspend(ShouldForceStop shouldForceStop)
89
ASSERT(RunLoop::isMain());
91
if (shouldForceStop == ShouldForceStop::No && WebCore::SQLiteDatabaseTracker::hasTransactionInProgress())
98
m_server->lock().lock();
99
m_server->stopDatabaseActivitiesOnMainThread();
102
void WebIDBServer::resume()
104
ASSERT(RunLoop::isMain());
109
m_isSuspended = false;
110
m_server->lock().unlock();
113
void WebIDBServer::openDatabase(const WebCore::IDBRequestData& requestData)
115
ASSERT(!RunLoop::isMain());
117
LockHolder locker(m_server->lock());
118
m_server->openDatabase(requestData);
121
void WebIDBServer::deleteDatabase(const WebCore::IDBRequestData& requestData)
123
ASSERT(!RunLoop::isMain());
125
LockHolder locker(m_server->lock());
126
m_server->deleteDatabase(requestData);
129
void WebIDBServer::abortTransaction(const WebCore::IDBResourceIdentifier& transactionIdentifier)
131
ASSERT(!RunLoop::isMain());
133
LockHolder locker(m_server->lock());
134
m_server->abortTransaction(transactionIdentifier);
137
void WebIDBServer::commitTransaction(const WebCore::IDBResourceIdentifier& transactionIdentifier)
139
ASSERT(!RunLoop::isMain());
141
LockHolder locker(m_server->lock());
142
m_server->commitTransaction(transactionIdentifier);
145
void WebIDBServer::didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& transactionIdentifier)
147
ASSERT(!RunLoop::isMain());
149
LockHolder locker(m_server->lock());
150
m_server->didFinishHandlingVersionChangeTransaction(databaseConnectionIdentifier, transactionIdentifier);
153
void WebIDBServer::createObjectStore(const WebCore::IDBRequestData& requestData, const WebCore::IDBObjectStoreInfo& objectStoreInfo)
155
ASSERT(!RunLoop::isMain());
157
LockHolder locker(m_server->lock());
158
m_server->createObjectStore(requestData, objectStoreInfo);
161
void WebIDBServer::deleteObjectStore(const WebCore::IDBRequestData& requestData, const String& objectStoreName)
163
ASSERT(!RunLoop::isMain());
165
LockHolder locker(m_server->lock());
166
m_server->deleteObjectStore(requestData, objectStoreName);
169
void WebIDBServer::renameObjectStore(const WebCore::IDBRequestData& requestData, uint64_t objectStoreIdentifier, const String& newName)
171
ASSERT(!RunLoop::isMain());
173
LockHolder locker(m_server->lock());
174
m_server->renameObjectStore(requestData, objectStoreIdentifier, newName);
177
void WebIDBServer::clearObjectStore(const WebCore::IDBRequestData& requestData, uint64_t objectStoreIdentifier)
179
ASSERT(!RunLoop::isMain());
181
LockHolder locker(m_server->lock());
182
m_server->clearObjectStore(requestData, objectStoreIdentifier);
185
void WebIDBServer::createIndex(const WebCore::IDBRequestData& requestData, const WebCore::IDBIndexInfo& indexInfo)
187
ASSERT(!RunLoop::isMain());
189
LockHolder locker(m_server->lock());
190
m_server->createIndex(requestData, indexInfo);
193
void WebIDBServer::deleteIndex(const WebCore::IDBRequestData& requestData, uint64_t objectStoreIdentifier, const String& indexName)
195
ASSERT(!RunLoop::isMain());
197
LockHolder locker(m_server->lock());
198
m_server->deleteIndex(requestData, objectStoreIdentifier, indexName);
201
void WebIDBServer::renameIndex(const WebCore::IDBRequestData& requestData, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName)
203
ASSERT(!RunLoop::isMain());
205
LockHolder locker(m_server->lock());
206
m_server->renameIndex(requestData, objectStoreIdentifier, indexIdentifier, newName);
209
void WebIDBServer::putOrAdd(const WebCore::IDBRequestData& requestData, const WebCore::IDBKeyData& keyData, const WebCore::IDBValue& value, WebCore::IndexedDB::ObjectStoreOverwriteMode overWriteMode)
211
ASSERT(!RunLoop::isMain());
213
LockHolder locker(m_server->lock());
214
m_server->putOrAdd(requestData, keyData, value, overWriteMode);
217
void WebIDBServer::getRecord(const WebCore::IDBRequestData& requestData, const WebCore::IDBGetRecordData& getRecordData)
219
ASSERT(!RunLoop::isMain());
221
LockHolder locker(m_server->lock());
222
m_server->getRecord(requestData, getRecordData);
225
void WebIDBServer::getAllRecords(const WebCore::IDBRequestData& requestData, const WebCore::IDBGetAllRecordsData& getAllRecordsData)
227
ASSERT(!RunLoop::isMain());
229
LockHolder locker(m_server->lock());
230
m_server->getAllRecords(requestData, getAllRecordsData);
233
void WebIDBServer::getCount(const WebCore::IDBRequestData& requestData, const WebCore::IDBKeyRangeData& keyRangeData)
235
ASSERT(!RunLoop::isMain());
237
LockHolder locker(m_server->lock());
238
m_server->getCount(requestData, keyRangeData);
241
void WebIDBServer::deleteRecord(const WebCore::IDBRequestData& requestData, const WebCore::IDBKeyRangeData& keyRangeData)
243
ASSERT(!RunLoop::isMain());
245
LockHolder locker(m_server->lock());
246
m_server->deleteRecord(requestData, keyRangeData);
249
void WebIDBServer::openCursor(const WebCore::IDBRequestData& requestData, const WebCore::IDBCursorInfo& cursorInfo)
251
ASSERT(!RunLoop::isMain());
253
LockHolder locker(m_server->lock());
254
m_server->openCursor(requestData, cursorInfo);
257
void WebIDBServer::iterateCursor(const WebCore::IDBRequestData& requestData, const WebCore::IDBIterateCursorData& iterateCursorData)
259
ASSERT(!RunLoop::isMain());
261
LockHolder locker(m_server->lock());
262
m_server->iterateCursor(requestData, iterateCursorData);
265
void WebIDBServer::establishTransaction(uint64_t databaseConnectionIdentifier, const WebCore::IDBTransactionInfo& transactionInfo)
267
ASSERT(!RunLoop::isMain());
269
LockHolder locker(m_server->lock());
270
m_server->establishTransaction(databaseConnectionIdentifier, transactionInfo);
273
void WebIDBServer::databaseConnectionPendingClose(uint64_t databaseConnectionIdentifier)
275
ASSERT(!RunLoop::isMain());
277
LockHolder locker(m_server->lock());
278
m_server->databaseConnectionPendingClose(databaseConnectionIdentifier);
281
void WebIDBServer::databaseConnectionClosed(uint64_t databaseConnectionIdentifier)
283
ASSERT(!RunLoop::isMain());
285
LockHolder locker(m_server->lock());
286
m_server->databaseConnectionClosed(databaseConnectionIdentifier);
289
void WebIDBServer::abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& transactionIdentifier)
291
ASSERT(!RunLoop::isMain());
293
LockHolder locker(m_server->lock());
294
m_server->abortOpenAndUpgradeNeeded(databaseConnectionIdentifier, transactionIdentifier);
297
void WebIDBServer::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const WebCore::IDBResourceIdentifier& requestIdentifier, WebCore::IndexedDB::ConnectionClosedOnBehalfOfServer connectionClosed)
299
ASSERT(!RunLoop::isMain());
301
LockHolder locker(m_server->lock());
302
m_server->didFireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier, connectionClosed);
305
void WebIDBServer::openDBRequestCancelled(const WebCore::IDBRequestData& requestData)
307
ASSERT(!RunLoop::isMain());
309
LockHolder locker(m_server->lock());
310
m_server->openDBRequestCancelled(requestData);
313
void WebIDBServer::getAllDatabaseNames(IPC::Connection& connection, const WebCore::SecurityOriginData& mainFrameOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID)
315
ASSERT(!RunLoop::isMain());
317
auto* webIDBConnection = m_connectionMap.get(connection.uniqueID());
318
ASSERT(webIDBConnection);
320
LockHolder locker(m_server->lock());
321
m_server->getAllDatabaseNames(webIDBConnection->identifier(), mainFrameOrigin, openingOrigin, callbackID);
324
void WebIDBServer::addConnection(IPC::Connection& connection, WebCore::ProcessIdentifier processIdentifier)
326
ASSERT(RunLoop::isMain());
328
postTask([this, protectedThis = makeRef(*this), protectedConnection = makeRefPtr(connection), processIdentifier] {
329
auto[iter, isNewEntry] = m_connectionMap.ensure(protectedConnection->uniqueID(), [&] {
330
return makeUnique<WebIDBConnectionToClient>(*protectedConnection, processIdentifier);
333
ASSERT_UNUSED(isNewEntry, isNewEntry);
335
LockHolder locker(m_server->lock());
336
m_server->registerConnection(iter->value->connectionToClient());
338
connection.addThreadMessageReceiver(Messages::WebIDBServer::messageReceiverName(), this);
341
void WebIDBServer::removeConnection(IPC::Connection& connection)
343
ASSERT(RunLoop::isMain());
345
connection.removeThreadMessageReceiver(Messages::WebIDBServer::messageReceiverName());
346
postTask([this, protectedThis = makeRef(*this), connectionID = connection.uniqueID()] {
347
auto connection = m_connectionMap.take(connectionID);
351
LockHolder locker(m_server->lock());
352
m_server->unregisterConnection(connection->connectionToClient());
356
void WebIDBServer::postTask(Function<void()>&& task)
358
ASSERT(RunLoop::isMain());
360
CrossThreadTaskHandler::postTask(CrossThreadTask(WTFMove(task)));
363
void WebIDBServer::dispatchToThread(Function<void()>&& task)
365
CrossThreadTaskHandler::postTask(CrossThreadTask(WTFMove(task)));
368
} // namespace WebKit