| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATABASE_H_ | 5 #ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATABASE_H_ |
| 6 #define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATABASE_H_ | 6 #define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATABASE_H_ |
| 7 | 7 |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 | 10 |
| 11 #include <list> | 11 #include <list> |
| 12 #include <map> | 12 #include <map> |
| 13 #include <memory> |
| 13 #include <queue> | 14 #include <queue> |
| 14 #include <string> | 15 #include <string> |
| 15 #include <utility> | 16 #include <utility> |
| 16 #include <vector> | 17 #include <vector> |
| 17 | 18 |
| 18 #include "base/macros.h" | 19 #include "base/macros.h" |
| 19 #include "base/memory/ref_counted.h" | 20 #include "base/memory/ref_counted.h" |
| 20 #include "content/browser/indexed_db/indexed_db.h" | 21 #include "content/browser/indexed_db/indexed_db.h" |
| 21 #include "content/browser/indexed_db/indexed_db_backing_store.h" | 22 #include "content/browser/indexed_db/indexed_db_backing_store.h" |
| 22 #include "content/browser/indexed_db/indexed_db_callbacks.h" | 23 #include "content/browser/indexed_db/indexed_db_callbacks.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 void OpenConnection(const IndexedDBPendingConnection& connection); | 79 void OpenConnection(const IndexedDBPendingConnection& connection); |
| 79 void DeleteDatabase(scoped_refptr<IndexedDBCallbacks> callbacks); | 80 void DeleteDatabase(scoped_refptr<IndexedDBCallbacks> callbacks); |
| 80 const IndexedDBDatabaseMetadata& metadata() const { return metadata_; } | 81 const IndexedDBDatabaseMetadata& metadata() const { return metadata_; } |
| 81 | 82 |
| 82 void CreateObjectStore(int64_t transaction_id, | 83 void CreateObjectStore(int64_t transaction_id, |
| 83 int64_t object_store_id, | 84 int64_t object_store_id, |
| 84 const base::string16& name, | 85 const base::string16& name, |
| 85 const IndexedDBKeyPath& key_path, | 86 const IndexedDBKeyPath& key_path, |
| 86 bool auto_increment); | 87 bool auto_increment); |
| 87 void DeleteObjectStore(int64_t transaction_id, int64_t object_store_id); | 88 void DeleteObjectStore(int64_t transaction_id, int64_t object_store_id); |
| 88 void CreateTransaction(int64_t transaction_id, | 89 IndexedDBTransaction* CreateTransaction( |
| 89 IndexedDBConnection* connection, | 90 int64_t transaction_id, |
| 90 const std::vector<int64_t>& object_store_ids, | 91 IndexedDBConnection* connection, |
| 91 blink::WebIDBTransactionMode mode); | 92 const std::vector<int64_t>& object_store_ids, |
| 93 blink::WebIDBTransactionMode mode); |
| 92 void Close(IndexedDBConnection* connection, bool forced); | 94 void Close(IndexedDBConnection* connection, bool forced); |
| 93 void ForceClose(); | 95 void ForceClose(); |
| 94 | 96 |
| 95 // Ack that one of the connections notified with a "versionchange" event did | 97 // Ack that one of the connections notified with a "versionchange" event did |
| 96 // not promptly close. Therefore a "blocked" event should be fired at the | 98 // not promptly close. Therefore a "blocked" event should be fired at the |
| 97 // pending connection. | 99 // pending connection. |
| 98 void VersionChangeIgnored(); | 100 void VersionChangeIgnored(); |
| 99 | 101 |
| 100 void Commit(int64_t transaction_id); | 102 void Commit(int64_t transaction_id); |
| 101 void Abort(int64_t transaction_id); | 103 void Abort(int64_t transaction_id); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 scoped_refptr<IndexedDBCallbacks> callbacks); | 174 scoped_refptr<IndexedDBCallbacks> callbacks); |
| 173 void DeleteRange(int64_t transaction_id, | 175 void DeleteRange(int64_t transaction_id, |
| 174 int64_t object_store_id, | 176 int64_t object_store_id, |
| 175 std::unique_ptr<IndexedDBKeyRange> key_range, | 177 std::unique_ptr<IndexedDBKeyRange> key_range, |
| 176 scoped_refptr<IndexedDBCallbacks> callbacks); | 178 scoped_refptr<IndexedDBCallbacks> callbacks); |
| 177 void Clear(int64_t transaction_id, | 179 void Clear(int64_t transaction_id, |
| 178 int64_t object_store_id, | 180 int64_t object_store_id, |
| 179 scoped_refptr<IndexedDBCallbacks> callbacks); | 181 scoped_refptr<IndexedDBCallbacks> callbacks); |
| 180 | 182 |
| 181 // Number of connections that have progressed passed initial open call. | 183 // Number of connections that have progressed passed initial open call. |
| 182 size_t ConnectionCount() const; | 184 size_t ConnectionCount() const { return connections_.size(); } |
| 183 // Number of open calls that are blocked on other connections. | 185 |
| 184 size_t PendingOpenCount() const; | 186 // Number of active open/delete calls (running or blocked on other |
| 185 // Number of pending upgrades (0 or 1). Also included in ConnectionCount(). | 187 // connections). |
| 186 size_t PendingUpgradeCount() const; | 188 size_t ActiveOpenDeleteCount() const { return active_request_ ? 1 : 0; } |
| 187 // Number of running upgrades (0 or 1). Also included in ConnectionCount(). | 189 |
| 188 size_t RunningUpgradeCount() const; | 190 // Number of open/delete calls that are waiting their turn. |
| 189 // Number of pending deletes, blocked on other connections. | 191 size_t PendingOpenDeleteCount() const { return pending_requests_.size(); } |
| 190 size_t PendingDeleteCount() const; | |
| 191 | 192 |
| 192 // Asynchronous tasks scheduled within transactions: | 193 // Asynchronous tasks scheduled within transactions: |
| 193 void CreateObjectStoreAbortOperation(int64_t object_store_id, | 194 void CreateObjectStoreAbortOperation(int64_t object_store_id, |
| 194 IndexedDBTransaction* transaction); | 195 IndexedDBTransaction* transaction); |
| 195 void DeleteObjectStoreOperation(int64_t object_store_id, | 196 void DeleteObjectStoreOperation(int64_t object_store_id, |
| 196 IndexedDBTransaction* transaction); | 197 IndexedDBTransaction* transaction); |
| 197 void DeleteObjectStoreAbortOperation( | 198 void DeleteObjectStoreAbortOperation( |
| 198 const IndexedDBObjectStoreMetadata& object_store_metadata, | 199 const IndexedDBObjectStoreMetadata& object_store_metadata, |
| 199 IndexedDBTransaction* transaction); | 200 IndexedDBTransaction* transaction); |
| 200 void VersionChangeOperation(int64_t version, | 201 void VersionChangeOperation(int64_t version, |
| 201 scoped_refptr<IndexedDBCallbacks> callbacks, | 202 scoped_refptr<IndexedDBCallbacks> callbacks, |
| 202 std::unique_ptr<IndexedDBConnection> connection, | |
| 203 IndexedDBTransaction* transaction); | 203 IndexedDBTransaction* transaction); |
| 204 void VersionChangeAbortOperation(int64_t previous_version, | 204 void VersionChangeAbortOperation(int64_t previous_version, |
| 205 IndexedDBTransaction* transaction); | 205 IndexedDBTransaction* transaction); |
| 206 void DeleteIndexOperation(int64_t object_store_id, | 206 void DeleteIndexOperation(int64_t object_store_id, |
| 207 int64_t index_id, | 207 int64_t index_id, |
| 208 IndexedDBTransaction* transaction); | 208 IndexedDBTransaction* transaction); |
| 209 void CreateIndexAbortOperation(int64_t object_store_id, | 209 void CreateIndexAbortOperation(int64_t object_store_id, |
| 210 int64_t index_id, | 210 int64_t index_id, |
| 211 IndexedDBTransaction* transaction); | 211 IndexedDBTransaction* transaction); |
| 212 void DeleteIndexAbortOperation(int64_t object_store_id, | 212 void DeleteIndexAbortOperation(int64_t object_store_id, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 const Identifier& unique_identifier); | 253 const Identifier& unique_identifier); |
| 254 virtual ~IndexedDBDatabase(); | 254 virtual ~IndexedDBDatabase(); |
| 255 | 255 |
| 256 // May be overridden in tests. | 256 // May be overridden in tests. |
| 257 virtual size_t GetMaxMessageSizeInBytes() const; | 257 virtual size_t GetMaxMessageSizeInBytes() const; |
| 258 | 258 |
| 259 private: | 259 private: |
| 260 friend class base::RefCounted<IndexedDBDatabase>; | 260 friend class base::RefCounted<IndexedDBDatabase>; |
| 261 friend class IndexedDBClassFactory; | 261 friend class IndexedDBClassFactory; |
| 262 | 262 |
| 263 class PendingDeleteCall; | 263 class OpenOrDeleteRequest; |
| 264 class PendingSuccessCall; | 264 class OpenRequest; |
| 265 class PendingUpgradeCall; | 265 class DeleteRequest; |
| 266 | 266 |
| 267 bool IsUpgradeRunning() const; | 267 leveldb::Status OpenInternal(); |
| 268 bool IsUpgradePendingOrRunning() const; | |
| 269 | 268 |
| 270 bool IsOpenConnectionBlocked() const; | 269 // Called internally when an open or delete request comes in. Processes |
| 271 leveldb::Status OpenInternal(); | 270 // the queue immediately if there are no other requests. |
| 272 void RunVersionChangeTransaction( | 271 void AppendRequest(std::unique_ptr<OpenOrDeleteRequest> request); |
| 273 scoped_refptr<IndexedDBCallbacks> callbacks, | |
| 274 std::unique_ptr<IndexedDBConnection> connection, | |
| 275 int64_t transaction_id, | |
| 276 int64_t requested_version); | |
| 277 void RunVersionChangeTransactionFinal( | |
| 278 scoped_refptr<IndexedDBCallbacks> callbacks, | |
| 279 std::unique_ptr<IndexedDBConnection> connection, | |
| 280 int64_t transaction_id, | |
| 281 int64_t requested_version); | |
| 282 void ProcessPendingCalls(); | |
| 283 | 272 |
| 284 bool IsDeleteDatabaseBlocked() const; | 273 // Called by requests when complete. The request will be freed, so the |
| 285 void DeleteDatabaseFinal(scoped_refptr<IndexedDBCallbacks> callbacks); | 274 // request must do no other work after calling this. If there are pending |
| 275 // requests, the queue will be synchronously processed. |
| 276 void RequestComplete(OpenOrDeleteRequest* request); |
| 277 |
| 278 // Pop the first request from the queue and start it. |
| 279 void ProcessRequestQueue(); |
| 286 | 280 |
| 287 std::unique_ptr<IndexedDBConnection> CreateConnection( | 281 std::unique_ptr<IndexedDBConnection> CreateConnection( |
| 288 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, | 282 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, |
| 289 int child_process_id); | 283 int child_process_id); |
| 290 | 284 |
| 291 IndexedDBTransaction* GetTransaction(int64_t transaction_id) const; | 285 IndexedDBTransaction* GetTransaction(int64_t transaction_id) const; |
| 292 | 286 |
| 293 bool ValidateObjectStoreId(int64_t object_store_id) const; | 287 bool ValidateObjectStoreId(int64_t object_store_id) const; |
| 294 bool ValidateObjectStoreIdAndIndexId(int64_t object_store_id, | 288 bool ValidateObjectStoreIdAndIndexId(int64_t object_store_id, |
| 295 int64_t index_id) const; | 289 int64_t index_id) const; |
| 296 bool ValidateObjectStoreIdAndOptionalIndexId(int64_t object_store_id, | 290 bool ValidateObjectStoreIdAndOptionalIndexId(int64_t object_store_id, |
| 297 int64_t index_id) const; | 291 int64_t index_id) const; |
| 298 bool ValidateObjectStoreIdAndNewIndexId(int64_t object_store_id, | 292 bool ValidateObjectStoreIdAndNewIndexId(int64_t object_store_id, |
| 299 int64_t index_id) const; | 293 int64_t index_id) const; |
| 300 | 294 |
| 301 scoped_refptr<IndexedDBBackingStore> backing_store_; | 295 scoped_refptr<IndexedDBBackingStore> backing_store_; |
| 302 IndexedDBDatabaseMetadata metadata_; | 296 IndexedDBDatabaseMetadata metadata_; |
| 303 | 297 |
| 304 const Identifier identifier_; | 298 const Identifier identifier_; |
| 305 scoped_refptr<IndexedDBFactory> factory_; | 299 scoped_refptr<IndexedDBFactory> factory_; |
| 306 | 300 |
| 307 IndexedDBTransactionCoordinator transaction_coordinator_; | 301 IndexedDBTransactionCoordinator transaction_coordinator_; |
| 308 | 302 |
| 309 std::map<int64_t, IndexedDBTransaction*> transactions_; | 303 std::map<int64_t, IndexedDBTransaction*> transactions_; |
| 310 | 304 |
| 311 // An open request ends up here if: | 305 list_set<IndexedDBConnection*> connections_; |
| 312 // * There is a running or pending upgrade. | |
| 313 // * There are pending deletes. | |
| 314 // Requests here have *not* broadcast OnVersionChange if necessary. | |
| 315 // When no longer blocked, the OpenConnection() calls are remade. | |
| 316 std::queue<IndexedDBPendingConnection> pending_open_calls_; | |
| 317 | 306 |
| 318 // This owns the connection for the first upgrade request (open with higher | 307 // This holds the first open or delete request that could not be immediately |
| 319 // version) that could not be immediately processed. The request has already | 308 // processed. The request has already broadcast OnVersionChange if |
| 320 // broadcast OnVersionChange if necessary. | 309 // necessary. |
| 321 std::unique_ptr<PendingUpgradeCall> | 310 std::unique_ptr<OpenOrDeleteRequest> active_request_; |
| 322 pending_run_version_change_transaction_call_; | |
| 323 | 311 |
| 324 // This references a connection for an upgrade request while the upgrade | 312 // This holds open or delete requests that are waiting for the active |
| 325 // transaction is running, so that the success/error result can be sent. It | 313 // request to be completed. The requests have not yet broadcast |
| 326 // is not set until the upgrade transaction actually starts executing | 314 // OnVersionChange (if necessary). |
| 327 // operations, so do not rely on it to determine if an upgrade is in | 315 std::queue<std::unique_ptr<OpenOrDeleteRequest>> pending_requests_; |
| 328 // progress. | |
| 329 std::unique_ptr<PendingSuccessCall> pending_second_half_open_; | |
| 330 | 316 |
| 331 // A delete request ends up here if: | 317 // The |processing_pending_requests_| flag is set while ProcessRequestQueue() |
| 332 // * There is a running upgrade. | 318 // is executing. It prevents rentrant calls if the active request completes |
| 333 // Requests here have *not* broadcast OnVersionChange if necessary. | 319 // synchronously. |
| 334 // When no longer blocked, DeleteDatabase() calls are remade. | 320 bool processing_pending_requests_ = false; |
| 335 std::list<std::unique_ptr<PendingDeleteCall>> pending_delete_calls_; | |
| 336 | 321 |
| 337 // A delete request ends up here if: | |
| 338 // * There are open connections. | |
| 339 // Requests here have already broadcast OnVersionChange if necessary. | |
| 340 // When no longer blocked, DeleteDatabaseFinal() calls are made. | |
| 341 std::list<std::unique_ptr<PendingDeleteCall>> blocked_delete_calls_; | |
| 342 | |
| 343 list_set<IndexedDBConnection*> connections_; | |
| 344 bool experimental_web_platform_features_enabled_; | 322 bool experimental_web_platform_features_enabled_; |
| 345 | 323 |
| 346 DISALLOW_COPY_AND_ASSIGN(IndexedDBDatabase); | 324 DISALLOW_COPY_AND_ASSIGN(IndexedDBDatabase); |
| 347 }; | 325 }; |
| 348 | 326 |
| 349 } // namespace content | 327 } // namespace content |
| 350 | 328 |
| 351 #endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATABASE_H_ | 329 #endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATABASE_H_ |
| OLD | NEW |