Modern IDB: Crash seen in IDBConnectionProxy::putOrAdd on GuardMalloc bot
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / client / IDBConnectionProxy.h
1 /*
2  * Copyright (C) 2016 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 #pragma once
27
28 #if ENABLE(INDEXED_DATABASE)
29
30 #include "IDBConnectionToServer.h"
31 #include "IDBResourceIdentifier.h"
32 #include "TransactionOperation.h"
33 #include <functional>
34 #include <wtf/CrossThreadQueue.h>
35 #include <wtf/CrossThreadTask.h>
36 #include <wtf/HashMap.h>
37 #include <wtf/MainThread.h>
38 #include <wtf/MessageQueue.h>
39 #include <wtf/RefPtr.h>
40 #include <wtf/Vector.h>
41 #include <wtf/text/WTFString.h>
42
43 namespace WebCore {
44
45 class IDBDatabase;
46 class IDBDatabaseIdentifier;
47 class IDBError;
48 class IDBOpenDBRequest;
49 class IDBResultData;
50 class IDBTransaction;
51 class ScriptExecutionContext;
52 class SecurityOrigin;
53
54 namespace IDBClient {
55
56 class IDBConnectionToServer;
57
58 class IDBConnectionProxy {
59 public:
60     IDBConnectionProxy(IDBConnectionToServer&);
61
62     RefPtr<IDBOpenDBRequest> openDatabase(ScriptExecutionContext&, const IDBDatabaseIdentifier&, uint64_t version);
63     void didOpenDatabase(const IDBResultData&);
64
65     RefPtr<IDBOpenDBRequest> deleteDatabase(ScriptExecutionContext&, const IDBDatabaseIdentifier&);
66     void didDeleteDatabase(const IDBResultData&);
67
68     void createObjectStore(TransactionOperation&, const IDBObjectStoreInfo&);
69     void deleteObjectStore(TransactionOperation&, const String& objectStoreName);
70     void clearObjectStore(TransactionOperation&, uint64_t objectStoreIdentifier);
71     void createIndex(TransactionOperation&, const IDBIndexInfo&);
72     void deleteIndex(TransactionOperation&, uint64_t objectStoreIdentifier, const String& indexName);
73     void putOrAdd(TransactionOperation&, IDBKeyData&&, const IDBValue&, const IndexedDB::ObjectStoreOverwriteMode);
74     void getRecord(TransactionOperation&, const IDBKeyRangeData&);
75     void getCount(TransactionOperation&, const IDBKeyRangeData&);
76     void deleteRecord(TransactionOperation&, const IDBKeyRangeData&);
77     void openCursor(TransactionOperation&, const IDBCursorInfo&);
78     void iterateCursor(TransactionOperation&, const IDBKeyData&, unsigned long count);
79     
80     void fireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier, uint64_t requestedVersion);
81     void didFireVersionChangeEvent(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& requestIdentifier);
82
83     void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion);
84     void openDBRequestCancelled(const IDBRequestData&);
85
86     void establishTransaction(IDBTransaction&);
87     void commitTransaction(IDBTransaction&);
88     void abortTransaction(IDBTransaction&);
89
90     void didStartTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
91     void didCommitTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
92     void didAbortTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
93
94     void didFinishHandlingVersionChangeTransaction(uint64_t databaseConnectionIdentifier, IDBTransaction&);
95     void databaseConnectionClosed(IDBDatabase&);
96
97     void didCloseFromServer(uint64_t databaseConnectionIdentifier, const IDBError&);
98     void confirmDidCloseFromServer(IDBDatabase&);
99
100     void abortOpenAndUpgradeNeeded(uint64_t databaseConnectionIdentifier, const IDBResourceIdentifier& transactionIdentifier);
101
102     void completeOperation(const IDBResultData&);
103
104     uint64_t serverConnectionIdentifier() const { return m_serverConnectionIdentifier; }
105
106     void ref();
107     void deref();
108
109     void getAllDatabaseNames(const SecurityOrigin& mainFrameOrigin, const SecurityOrigin& openingOrigin, std::function<void (const Vector<String>&)>);
110
111     void registerDatabaseConnection(IDBDatabase&);
112     void unregisterDatabaseConnection(IDBDatabase&);
113
114     void forgetActiveOperations(const Vector<RefPtr<TransactionOperation>>&);
115     void forgetActivityForCurrentThread();
116
117 private:
118     void completeOpenDBRequest(const IDBResultData&);
119     bool hasRecordOfTransaction(const IDBTransaction&) const;
120
121     void saveOperation(TransactionOperation&);
122
123     template<typename... Parameters, typename... Arguments>
124     void callConnectionOnMainThread(void (IDBConnectionToServer::*method)(Parameters...), Arguments&&... arguments)
125     {
126         if (isMainThread())
127             (m_connectionToServer.*method)(std::forward<Arguments>(arguments)...);
128         else
129             postMainThreadTask(m_connectionToServer, method, arguments...);
130     }
131
132     template<typename... Arguments>
133     void postMainThreadTask(Arguments&&... arguments)
134     {
135         auto task = createCrossThreadTask(arguments...);
136         m_mainThreadQueue.append(WTFMove(task));
137
138         scheduleMainThreadTasks();
139     }
140
141     void scheduleMainThreadTasks();
142     void handleMainThreadTasks();
143
144     IDBConnectionToServer& m_connectionToServer;
145     uint64_t m_serverConnectionIdentifier;
146
147     HashMap<uint64_t, IDBDatabase*> m_databaseConnectionMap;
148     Lock m_databaseConnectionMapLock;
149
150     HashMap<IDBResourceIdentifier, RefPtr<IDBOpenDBRequest>> m_openDBRequestMap;
151     Lock m_openDBRequestMapLock;
152
153     HashMap<IDBResourceIdentifier, RefPtr<IDBTransaction>> m_pendingTransactions;
154     HashMap<IDBResourceIdentifier, RefPtr<IDBTransaction>> m_committingTransactions;
155     HashMap<IDBResourceIdentifier, RefPtr<IDBTransaction>> m_abortingTransactions;
156     Lock m_transactionMapLock;
157
158     HashMap<IDBResourceIdentifier, RefPtr<TransactionOperation>> m_activeOperations;
159     Lock m_transactionOperationLock;
160
161     CrossThreadQueue<CrossThreadTask> m_mainThreadQueue;
162     Lock m_mainThreadTaskLock;
163     RefPtr<IDBConnectionToServer> m_mainThreadProtector;
164 };
165
166 } // namespace IDBClient
167 } // namespace WebCore
168
169 #endif // ENABLE(INDEXED_DATABASE)