1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file. 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_TRANSACTION_H_ 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_TRANSACTION_H_ 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <queue> 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <set> 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <stack> 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/basictypes.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/ref_counted.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/time/time.h" 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/timer/timer.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_backing_store.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_database.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_database_error.h" 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace content { 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class BlobWriteCallbackImpl; 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class IndexedDBCursor; 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass IndexedDBDatabaseCallbacks; 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class CONTENT_EXPORT IndexedDBTransaction 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : public NON_EXPORTED_BASE(base::RefCounted<IndexedDBTransaction>) { 29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) typedef base::Callback<void(IndexedDBTransaction*)> Operation; 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) IndexedDBTransaction( 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int64 id, 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_refptr<IndexedDBDatabaseCallbacks> callbacks, 35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::set<int64>& object_store_ids, 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) indexed_db::TransactionMode, 37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) IndexedDBDatabase* db, 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) IndexedDBBackingStore::Transaction* backing_store_transaction); 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void Abort(); 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void Commit(); 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void Abort(const IndexedDBDatabaseError& error); 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Called by the transaction coordinator when this transaction is unblocked. 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void Start(); 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexed_db::TransactionMode mode() const { return mode_; } 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::set<int64>& scope() const { return object_store_ids_; } 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void ScheduleTask(Operation task) { 513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScheduleTask(IndexedDBDatabase::NORMAL_TASK, task); 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void ScheduleTask(IndexedDBDatabase::TaskType, Operation task); 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void ScheduleAbortTask(Operation abort_task); 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void RegisterOpenCursor(IndexedDBCursor* cursor); 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void UnregisterOpenCursor(IndexedDBCursor* cursor); 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void AddPreemptiveEvent() { pending_preemptive_events_++; } 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void DidCompletePreemptiveEvent() { 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pending_preemptive_events_--; 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK_GE(pending_preemptive_events_, 0); 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IndexedDBBackingStore::Transaction* BackingStoreTransaction() { 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return transaction_.get(); 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 id() const { return id_; } 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexedDBDatabase* database() const { return database_; } 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexedDBDatabaseCallbacks* connection() const { return callbacks_; } 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) enum State { 7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CREATED, // Created, but not yet started by coordinator. 7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) STARTED, // Started by the coordinator. 7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) COMMITTING, // In the process of committing, possibly waiting for blobs 7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // to be written. 7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FINISHED, // Either aborted or committed. 76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) }; 77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) State state() const { return state_; } 79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool IsTimeoutTimerRunning() const { return timeout_timer_.IsRunning(); } 80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) struct Diagnostics { 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Time creation_time; 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Time start_time; 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int tasks_scheduled; 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int tasks_completed; 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) }; 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Diagnostics& diagnostics() const { return diagnostics_; } 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) friend class BlobWriteCallbackImpl; 9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 93c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTestMode, AbortPreemptive); 94c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTest, Timeout); 95a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTest, 96a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SchedulePreemptiveTask); 970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTestMode, 980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ScheduleNormalTask); 99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) friend class base::RefCounted<IndexedDBTransaction>; 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~IndexedDBTransaction(); 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void RunTasksIfStarted(); 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool IsTaskQueueEmpty() const; 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool HasPendingTasks() const; 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void BlobWriteComplete(bool success); 1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void ProcessTaskQueue(); 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void CloseOpenCursors(); 11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void CommitPhaseTwo(); 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void Timeout(); 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int64 id_; 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::set<int64> object_store_ids_; 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const indexed_db::TransactionMode mode_; 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool used_; 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) State state_; 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool commit_pending_; 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<IndexedDBDatabaseCallbacks> callbacks_; 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<IndexedDBDatabase> database_; 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) class TaskQueue { 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TaskQueue(); 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ~TaskQueue(); 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool empty() const { return queue_.empty(); } 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void push(Operation task) { queue_.push(task); } 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Operation pop(); 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void clear(); 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::queue<Operation> queue_; 135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TaskQueue); 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) }; 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) class TaskStack { 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TaskStack(); 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ~TaskStack(); 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool empty() const { return stack_.empty(); } 1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void push(Operation task) { stack_.push(task); } 1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Operation pop(); 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void clear(); 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::stack<Operation> stack_; 150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TaskStack); 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) }; 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TaskQueue task_queue_; 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TaskQueue preemptive_task_queue_; 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TaskStack abort_task_stack_; 157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<IndexedDBBackingStore::Transaction> transaction_; 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool backing_store_transaction_begun_; 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool should_process_queue_; 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int pending_preemptive_events_; 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::set<IndexedDBCursor*> open_cursors_; 165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // This timer is started after requests have been processed. If no subsequent 167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // requests are processed before the timer fires, assume the script is 168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // unresponsive and abort to unblock the transaction queue. 169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::OneShotTimer<IndexedDBTransaction> timeout_timer_; 170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Diagnostics diagnostics_; 172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace content 175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_TRANSACTION_H_ 177