Modern IDB (Workers): Get everything to the right threads.
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / shared / InProcessIDBServer.cpp
1 /*
2  * Copyright (C) 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "InProcessIDBServer.h"
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "FileSystem.h"
32 #include "IDBConnectionToClient.h"
33 #include "IDBConnectionToServer.h"
34 #include "IDBCursorInfo.h"
35 #include "IDBKeyRangeData.h"
36 #include "IDBOpenDBRequest.h"
37 #include "IDBRequestData.h"
38 #include "IDBResultData.h"
39 #include "IDBValue.h"
40 #include "Logging.h"
41 #include <wtf/RunLoop.h>
42
43 namespace WebCore {
44
45 Ref<InProcessIDBServer> InProcessIDBServer::create()
46 {
47     Ref<InProcessIDBServer> server = adoptRef(*new InProcessIDBServer);
48     server->m_server->registerConnection(server->connectionToClient());
49     return server;
50 }
51
52 Ref<InProcessIDBServer> InProcessIDBServer::create(const String& databaseDirectoryPath)
53 {
54     Ref<InProcessIDBServer> server = adoptRef(*new InProcessIDBServer(databaseDirectoryPath));
55     server->m_server->registerConnection(server->connectionToClient());
56     return server;
57 }
58
59 InProcessIDBServer::InProcessIDBServer()
60     : m_server(IDBServer::IDBServer::create(*this))
61 {
62     relaxAdoptionRequirement();
63     m_connectionToServer = IDBClient::IDBConnectionToServer::create(*this);
64     m_connectionToClient = IDBServer::IDBConnectionToClient::create(*this);
65 }
66
67 InProcessIDBServer::InProcessIDBServer(const String& databaseDirectoryPath)
68     : m_server(IDBServer::IDBServer::create(databaseDirectoryPath, *this))
69 {
70     relaxAdoptionRequirement();
71     m_connectionToServer = IDBClient::IDBConnectionToServer::create(*this);
72     m_connectionToClient = IDBServer::IDBConnectionToClient::create(*this);
73 }
74
75 uint64_t InProcessIDBServer::identifier() const
76 {
77     // An instance of InProcessIDBServer always has a 1:1 relationship with its instance of IDBServer.
78     // Therefore the connection identifier between the two can always be "1".
79     return 1;
80 }
81
82 IDBClient::IDBConnectionToServer& InProcessIDBServer::connectionToServer() const
83 {
84     return *m_connectionToServer;
85 }
86
87 IDBServer::IDBConnectionToClient& InProcessIDBServer::connectionToClient() const
88 {
89     return *m_connectionToClient;
90 }
91
92 void InProcessIDBServer::deleteDatabase(const IDBRequestData& requestData)
93 {
94     RefPtr<InProcessIDBServer> self(this);
95     RunLoop::current().dispatch([this, self, requestData] {
96         m_server->deleteDatabase(requestData);
97     });
98 }
99
100 void InProcessIDBServer::didDeleteDatabase(const IDBResultData& resultData)
101 {
102     RefPtr<InProcessIDBServer> self(this);
103     RunLoop::current().dispatch([this, self, resultData] {
104         m_connectionToServer->didDeleteDatabase(resultData);
105     });
106 }
107
108 void InProcessIDBServer::openDatabase(const IDBRequestData& requestData)
109 {
110     RefPtr<InProcessIDBServer> self(this);
111     RunLoop::current().dispatch([this, self, requestData] {
112         m_server->openDatabase(requestData);
113     });
114 }
115
116 void InProcessIDBServer::didOpenDatabase(const IDBResultData& resultData)
117 {
118     RefPtr<InProcessIDBServer> self(this);
119     RunLoop::current().dispatch([this, self, resultData] {
120         m_connectionToServer->didOpenDatabase(resultData);
121     });
122 }
123
124 void InProcessIDBServer::didAbortTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
125 {
126     RefPtr<InProcessIDBServer> self(this);
127     RunLoop::current().dispatch([this, self, transactionIdentifier, error] {
128         m_connectionToServer->didAbortTransaction(transactionIdentifier, error);
129     });
130 }
131
132 void InProcessIDBServer::didCommitTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
133 {
134     RefPtr<InProcessIDBServer> self(this);
135     RunLoop::current().dispatch([this, self, transactionIdentifier, error] {
136         m_connectionToServer->didCommitTransaction(transactionIdentifier, error);
137     });
138 }
139
140 void InProcessIDBServer::didCreateObjectStore(const IDBResultData& resultData)
141 {
142     RefPtr<InProcessIDBServer> self(this);
143     RunLoop::current().dispatch([this, self, resultData] {
144         m_connectionToServer->didCreateObjectStore(resultData);
145     });
146 }
147
148 void InProcessIDBServer::didDeleteObjectStore(const IDBResultData& resultData)
149 {
150     RefPtr<InProcessIDBServer> self(this);
151     RunLoop::current().dispatch([this, self, resultData] {
152         m_connectionToServer->didDeleteObjectStore(resultData);
153     });
154 }
155
156 void InProcessIDBServer::didClearObjectStore(const IDBResultData& resultData)
157 {
158     RefPtr<InProcessIDBServer> self(this);
159     RunLoop::current().dispatch([this, self, resultData] {
160         m_connectionToServer->didClearObjectStore(resultData);
161     });
162 }
163
164 void InProcessIDBServer::didCreateIndex(const IDBResultData& resultData)
165 {
166     RefPtr<InProcessIDBServer> self(this);
167     RunLoop::current().dispatch([this, self, resultData] {
168         m_connectionToServer->didCreateIndex(resultData);
169     });
170 }
171
172 void InProcessIDBServer::didDeleteIndex(const IDBResultData& resultData)
173 {
174     RefPtr<InProcessIDBServer> self(this);
175     RunLoop::current().dispatch([this, self, resultData] {
176         m_connectionToServer->didDeleteIndex(resultData);
177     });
178 }
179
180 void InProcessIDBServer::didPutOrAdd(const IDBResultData& resultData)
181 {
182     RefPtr<InProcessIDBServer> self(this);
183     RunLoop::current().dispatch([this, self, resultData] {
184         m_connectionToServer->didPutOrAdd(resultData);
185     });
186 }
187
188 void InProcessIDBServer::didGetRecord(const IDBResultData& resultData)
189 {
190     RefPtr<InProcessIDBServer> self(this);
191     RunLoop::current().dispatch([this, self, resultData] {
192         m_connectionToServer->didGetRecord(resultData);
193     });
194 }
195
196 void InProcessIDBServer::didGetCount(const IDBResultData& resultData)
197 {
198     RefPtr<InProcessIDBServer> self(this);
199     RunLoop::current().dispatch([this, self, resultData] {
200         m_connectionToServer->didGetCount(resultData);
201     });
202 }
203
204 void InProcessIDBServer::didDeleteRecord(const IDBResultData& resultData)
205 {
206     RefPtr<InProcessIDBServer> self(this);
207     RunLoop::current().dispatch([this, self, resultData] {
208         m_connectionToServer->didDeleteRecord(resultData);
209     });
210 }
211
212 void InProcessIDBServer::didOpenCursor(const IDBResultData& resultData)
213 {
214     RefPtr<InProcessIDBServer> self(this);
215     RunLoop::current().dispatch([this, self, resultData] {
216         m_connectionToServer->didOpenCursor(resultData);
217     });
218 }
219
220 void InProcessIDBServer::didIterateCursor(const IDBResultData& resultData)
221 {
222     RefPtr<InProcessIDBServer> self(this);
223     RunLoop::current().dispatch([this, self, resultData] {
224         m_connectionToServer->didIterateCursor(resultData);
225     });
226 }
227
228 void InProcessIDBServer::abortTransaction(const IDBResourceIdentifier& resourceIdentifier)
229 {
230     RefPtr<InProcessIDBServer> self(this);
231     RunLoop::current().dispatch([this, self, resourceIdentifier] {
232         m_server->abortTransaction(resourceIdentifier);
233     });
234 }
235
236 void InProcessIDBServer::commitTransaction(const IDBResourceIdentifier& resourceIdentifier)
237 {
238     RefPtr<InProcessIDBServer> self(this);
239     RunLoop::current().dispatch([this, self, resourceIdentifier] {
240         m_server->commitTransaction(resourceIdentifier);
241     });
242 }
243
244 void InProcessIDBServer::didFinishHandlingVersionChangeTransaction(const IDBResourceIdentifier& transactionIdentifier)
245 {
246     RefPtr<InProcessIDBServer> self(this);
247     RunLoop::current().dispatch([this, self, transactionIdentifier] {
248         m_server->didFinishHandlingVersionChangeTransaction(transactionIdentifier);
249     });
250 }
251
252 void InProcessIDBServer::createObjectStore(const IDBRequestData& resultData, const IDBObjectStoreInfo& info)
253 {
254     RefPtr<InProcessIDBServer> self(this);
255     RunLoop::current().dispatch([this, self, resultData, info] {
256         m_server->createObjectStore(resultData, info);
257     });
258 }
259
260 void InProcessIDBServer::deleteObjectStore(const IDBRequestData& requestData, const String& objectStoreName)
261 {
262     RefPtr<InProcessIDBServer> self(this);
263     RunLoop::current().dispatch([this, self, requestData, objectStoreName] {
264         m_server->deleteObjectStore(requestData, objectStoreName);
265     });
266 }
267
268 void InProcessIDBServer::clearObjectStore(const IDBRequestData& requestData, uint64_t objectStoreIdentifier)
269 {
270     RefPtr<InProcessIDBServer> self(this);
271     RunLoop::current().dispatch([this, self, requestData, objectStoreIdentifier] {
272         m_server->clearObjectStore(requestData, objectStoreIdentifier);
273     });
274 }
275
276 void InProcessIDBServer::createIndex(const IDBRequestData& requestData, const IDBIndexInfo& info)
277 {
278     RefPtr<InProcessIDBServer> self(this);
279     RunLoop::current().dispatch([this, self, requestData, info] {
280         m_server->createIndex(requestData, info);
281     });
282 }
283
284 void InProcessIDBServer::deleteIndex(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, const String& indexName)
285 {
286     RefPtr<InProcessIDBServer> self(this);
287     RunLoop::current().dispatch([this, self, requestData, objectStoreIdentifier, indexName] {
288         m_server->deleteIndex(requestData, objectStoreIdentifier, indexName);
289     });
290 }
291
292 void InProcessIDBServer::putOrAdd(const IDBRequestData& requestData, const IDBKeyData& keyData, const IDBValue& value, const IndexedDB::ObjectStoreOverwriteMode overwriteMode)
293 {
294     RefPtr<InProcessIDBServer> self(this);
295     RunLoop::current().dispatch([this, self, requestData, keyData, value, overwriteMode] {
296         m_server->putOrAdd(requestData, keyData, value, overwriteMode);
297     });
298 }
299
300 void InProcessIDBServer::getRecord(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData)
301 {
302     RefPtr<InProcessIDBServer> self(this);
303
304     RunLoop::current().dispatch([this, self, requestData, keyRangeData] {
305         m_server->getRecord(requestData, keyRangeData);
306     });
307 }
308
309 void InProcessIDBServer::getCount(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData)
310 {
311     RefPtr<InProcessIDBServer> self(this);
312     RunLoop::current().dispatch([this, self, requestData, keyRangeData] {
313         m_server->getCount(requestData, keyRangeData);
314     });
315 }
316
317 void InProcessIDBServer::deleteRecord(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData)
318 {
319     RefPtr<InProcessIDBServer> self(this);
320
321     RunLoop::current().dispatch([this, self, requestData, keyRangeData] {
322         m_server->deleteRecord(requestData, keyRangeData);
323     });
324 }
325
326 void InProcessIDBServer::openCursor(const IDBRequestData& requestData, const IDBCursorInfo& info)
327 {
328     RefPtr<InProcessIDBServer> self(this);
329
330     RunLoop::current().dispatch([this, self, requestData, info] {
331         m_server->openCursor(requestData, info);
332     });
333 }
334
335 void InProcessIDBServer::iterateCursor(const IDBRequestData& requestData, const IDBKeyData& key, unsigned long count)
336 {
337     RefPtr<InProcessIDBServer> self(this);
338
339     RunLoop::current().dispatch([this, self, requestData, key, count] {
340         m_server->iterateCursor(requestData, key, count);
341     });
342 }
343
344 void InProcessIDBServer::establishTransaction(uint64_t databaseConnectionIdentifier, const IDBTransactionInfo& info)
345 {
346     RefPtr<InProcessIDBServer> self(this);
347
348     RunLoop::current().dispatch([this, self, databaseConnectionIdentifier, info] {
349         m_server->establishTransaction(databaseConnectionIdentifier, info);
350     });
351 }
352
353 void InProcessIDBServer::fireVersionChangeEvent(IDBServer::UniqueIDBDatabaseConnection& connection, const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion)
354 {
355     RefPtr<InProcessIDBServer> self(this);
356     uint64_t databaseConnectionIdentifier = connection.identifier();
357     RunLoop::current().dispatch([this, self, databaseConnectionIdentifier, requestIdentifier, requestedVersion] {
358         m_connectionToServer->fireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier, requestedVersion);
359     });
360 }
361
362 void InProcessIDBServer::didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError& error)
363 {
364     RefPtr<InProcessIDBServer> self(this);
365     RunLoop::current().dispatch([this, self, transactionIdentifier, error] {
366         m_connectionToServer->didStartTransaction(transactionIdentifier, error);
367     });
368 }
369
370 void InProcessIDBServer::notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion)
371 {
372     RefPtr<InProcessIDBServer> self(this);
373     RunLoop::current().dispatch([this, self, requestIdentifier, oldVersion, newVersion] {
374         m_connectionToServer->notifyOpenDBRequestBlocked(requestIdentifier, oldVersion, newVersion);
375     });
376 }
377
378 void InProcessIDBServer::databaseConnectionClosed(uint64_t databaseConnectionIdentifier)
379 {
380     RefPtr<InProcessIDBServer> self(this);
381     RunLoop::current().dispatch([this, self, databaseConnectionIdentifier] {
382         m_server->databaseConnectionClosed(databaseConnectionIdentifier);
383     });
384 }
385
386 void InProcessIDBServer::abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier)
387 {
388     RefPtr<InProcessIDBServer> self(this);
389     RunLoop::current().dispatch([this, self, databaseConnectionIdentifier, transactionIdentifier] {
390         m_server->abortOpenAndUpgradeNeeded(databaseConnectionIdentifier, transactionIdentifier);
391     });
392 }
393
394 void InProcessIDBServer::didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier)
395 {
396     RefPtr<InProcessIDBServer> self(this);
397     RunLoop::current().dispatch([this, self, databaseConnectionIdentifier, requestIdentifier] {
398         m_server->didFireVersionChangeEvent(databaseConnectionIdentifier, requestIdentifier);
399     });
400 }
401
402 void InProcessIDBServer::getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID)
403 {
404     RefPtr<InProcessIDBServer> protector(this);
405     RunLoop::current().dispatch([this, protector, mainFrameOrigin, openingOrigin, callbackID] {
406         m_server->getAllDatabaseNames(m_connectionToServer->identifier(), mainFrameOrigin, openingOrigin, callbackID);
407     });
408 }
409
410 void InProcessIDBServer::didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames)
411 {
412     RefPtr<InProcessIDBServer> protector(this);
413     RunLoop::current().dispatch([this, protector, callbackID, databaseNames] {
414         m_connectionToServer->didGetAllDatabaseNames(callbackID, databaseNames);
415     });
416 }
417
418 void InProcessIDBServer::accessToTemporaryFileComplete(const String& path)
419 {
420     deleteFile(path);
421 }
422
423 } // namespace WebCore
424
425 #endif // ENABLE(INDEXED_DATABASE)