| 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_TRANSACTION_H_ | 5 #ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_TRANSACTION_H_ |
| 6 #define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_TRANSACTION_H_ | 6 #define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_TRANSACTION_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 | 26 |
| 27 namespace content { | 27 namespace content { |
| 28 | 28 |
| 29 class BlobWriteCallbackImpl; | 29 class BlobWriteCallbackImpl; |
| 30 class IndexedDBCursor; | 30 class IndexedDBCursor; |
| 31 class IndexedDBDatabaseCallbacks; | 31 class IndexedDBDatabaseCallbacks; |
| 32 | 32 |
| 33 class CONTENT_EXPORT IndexedDBTransaction | 33 class CONTENT_EXPORT IndexedDBTransaction |
| 34 : public NON_EXPORTED_BASE(base::RefCounted<IndexedDBTransaction>) { | 34 : public NON_EXPORTED_BASE(base::RefCounted<IndexedDBTransaction>) { |
| 35 public: | 35 public: |
| 36 typedef base::Callback<void(IndexedDBTransaction*)> Operation; | 36 using Operation = base::Callback<leveldb::Status(IndexedDBTransaction*)>; |
| 37 using AbortOperation = base::Closure; |
| 37 | 38 |
| 38 enum State { | 39 enum State { |
| 39 CREATED, // Created, but not yet started by coordinator. | 40 CREATED, // Created, but not yet started by coordinator. |
| 40 STARTED, // Started by the coordinator. | 41 STARTED, // Started by the coordinator. |
| 41 COMMITTING, // In the process of committing, possibly waiting for blobs | 42 COMMITTING, // In the process of committing, possibly waiting for blobs |
| 42 // to be written. | 43 // to be written. |
| 43 FINISHED, // Either aborted or committed. | 44 FINISHED, // Either aborted or committed. |
| 44 }; | 45 }; |
| 45 | 46 |
| 46 virtual void Abort(); | 47 virtual void Abort(); |
| 47 leveldb::Status Commit(); | 48 leveldb::Status Commit(); |
| 48 void Abort(const IndexedDBDatabaseError& error); | 49 void Abort(const IndexedDBDatabaseError& error); |
| 49 | 50 |
| 50 // Called by the transaction coordinator when this transaction is unblocked. | 51 // Called by the transaction coordinator when this transaction is unblocked. |
| 51 void Start(); | 52 void Start(); |
| 52 | 53 |
| 53 blink::WebIDBTransactionMode mode() const { return mode_; } | 54 blink::WebIDBTransactionMode mode() const { return mode_; } |
| 54 const std::set<int64_t>& scope() const { return object_store_ids_; } | 55 const std::set<int64_t>& scope() const { return object_store_ids_; } |
| 55 | 56 |
| 56 void ScheduleTask(Operation task) { | 57 void ScheduleTask(Operation task) { |
| 57 ScheduleTask(blink::WebIDBTaskTypeNormal, task); | 58 ScheduleTask(blink::WebIDBTaskTypeNormal, task); |
| 58 } | 59 } |
| 59 void ScheduleTask(blink::WebIDBTaskType, Operation task); | 60 void ScheduleTask(blink::WebIDBTaskType, Operation task); |
| 60 void ScheduleAbortTask(Operation abort_task); | 61 void ScheduleAbortTask(AbortOperation abort_task); |
| 61 void RegisterOpenCursor(IndexedDBCursor* cursor); | 62 void RegisterOpenCursor(IndexedDBCursor* cursor); |
| 62 void UnregisterOpenCursor(IndexedDBCursor* cursor); | 63 void UnregisterOpenCursor(IndexedDBCursor* cursor); |
| 63 void AddPreemptiveEvent() { pending_preemptive_events_++; } | 64 void AddPreemptiveEvent() { pending_preemptive_events_++; } |
| 64 void DidCompletePreemptiveEvent() { | 65 void DidCompletePreemptiveEvent() { |
| 65 pending_preemptive_events_--; | 66 pending_preemptive_events_--; |
| 66 DCHECK_GE(pending_preemptive_events_, 0); | 67 DCHECK_GE(pending_preemptive_events_, 0); |
| 67 } | 68 } |
| 68 void AddPendingObserver(int32_t observer_id, | 69 void AddPendingObserver(int32_t observer_id, |
| 69 const IndexedDBObserver::Options& options); | 70 const IndexedDBObserver::Options& options); |
| 70 // Delete pending observers with ID's listed in |pending_observer_ids|. | 71 // Delete pending observers with ID's listed in |pending_observer_ids|. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 friend class IndexedDBClassFactory; | 119 friend class IndexedDBClassFactory; |
| 119 friend class base::RefCounted<IndexedDBTransaction>; | 120 friend class base::RefCounted<IndexedDBTransaction>; |
| 120 | 121 |
| 121 FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTestMode, AbortPreemptive); | 122 FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTestMode, AbortPreemptive); |
| 122 FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTestMode, AbortTasks); | 123 FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTestMode, AbortTasks); |
| 123 FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTest, NoTimeoutReadOnly); | 124 FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTest, NoTimeoutReadOnly); |
| 124 FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTest, | 125 FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTest, |
| 125 SchedulePreemptiveTask); | 126 SchedulePreemptiveTask); |
| 126 FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTestMode, | 127 FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTestMode, |
| 127 ScheduleNormalTask); | 128 ScheduleNormalTask); |
| 129 FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTestMode, TaskFails); |
| 128 FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTest, Timeout); | 130 FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTest, Timeout); |
| 129 FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTest, IndexedDBObserver); | 131 FRIEND_TEST_ALL_PREFIXES(IndexedDBTransactionTest, IndexedDBObserver); |
| 130 | 132 |
| 131 void RunTasksIfStarted(); | 133 void RunTasksIfStarted(); |
| 132 | 134 |
| 133 bool IsTaskQueueEmpty() const; | 135 bool IsTaskQueueEmpty() const; |
| 134 bool HasPendingTasks() const; | 136 bool HasPendingTasks() const; |
| 135 | 137 |
| 136 void BlobWriteComplete(bool success); | 138 void BlobWriteComplete(bool success); |
| 137 void ProcessTaskQueue(); | 139 void ProcessTaskQueue(); |
| 138 void CloseOpenCursors(); | 140 void CloseOpenCursors(); |
| 139 leveldb::Status CommitPhaseTwo(); | 141 leveldb::Status CommitPhaseTwo(); |
| 140 void Timeout(); | 142 void Timeout(); |
| 141 | 143 |
| 142 const int64_t id_; | 144 const int64_t id_; |
| 143 const std::set<int64_t> object_store_ids_; | 145 const std::set<int64_t> object_store_ids_; |
| 144 const blink::WebIDBTransactionMode mode_; | 146 const blink::WebIDBTransactionMode mode_; |
| 145 | 147 |
| 146 bool used_; | 148 bool used_ = false; |
| 147 State state_; | 149 State state_ = CREATED; |
| 148 bool commit_pending_; | 150 bool commit_pending_ = false; |
| 149 base::WeakPtr<IndexedDBConnection> connection_; | 151 base::WeakPtr<IndexedDBConnection> connection_; |
| 150 scoped_refptr<IndexedDBDatabaseCallbacks> callbacks_; | 152 scoped_refptr<IndexedDBDatabaseCallbacks> callbacks_; |
| 151 scoped_refptr<IndexedDBDatabase> database_; | 153 scoped_refptr<IndexedDBDatabase> database_; |
| 152 | 154 |
| 153 // Observers in pending queue do not listen to changes until activated. | 155 // Observers in pending queue do not listen to changes until activated. |
| 154 std::vector<std::unique_ptr<IndexedDBObserver>> pending_observers_; | 156 std::vector<std::unique_ptr<IndexedDBObserver>> pending_observers_; |
| 155 std::map<int32_t, ::indexed_db::mojom::ObserverChangesPtr> | 157 std::map<int32_t, ::indexed_db::mojom::ObserverChangesPtr> |
| 156 connection_changes_map_; | 158 connection_changes_map_; |
| 157 | 159 |
| 158 class TaskQueue { | 160 class TaskQueue { |
| 159 public: | 161 public: |
| 160 TaskQueue(); | 162 TaskQueue(); |
| 161 ~TaskQueue(); | 163 ~TaskQueue(); |
| 162 bool empty() const { return queue_.empty(); } | 164 bool empty() const { return queue_.empty(); } |
| 163 void push(Operation task) { queue_.push(task); } | 165 void push(Operation task) { queue_.push(std::move(task)); } |
| 164 Operation pop(); | 166 Operation pop(); |
| 165 void clear(); | 167 void clear(); |
| 166 | 168 |
| 167 private: | 169 private: |
| 168 std::queue<Operation> queue_; | 170 std::queue<Operation> queue_; |
| 169 | 171 |
| 170 DISALLOW_COPY_AND_ASSIGN(TaskQueue); | 172 DISALLOW_COPY_AND_ASSIGN(TaskQueue); |
| 171 }; | 173 }; |
| 172 | 174 |
| 173 class TaskStack { | 175 class TaskStack { |
| 174 public: | 176 public: |
| 175 TaskStack(); | 177 TaskStack(); |
| 176 ~TaskStack(); | 178 ~TaskStack(); |
| 177 bool empty() const { return stack_.empty(); } | 179 bool empty() const { return stack_.empty(); } |
| 178 void push(Operation task) { stack_.push(task); } | 180 void push(AbortOperation task) { stack_.push(std::move(task)); } |
| 179 Operation pop(); | 181 AbortOperation pop(); |
| 180 void clear(); | 182 void clear(); |
| 181 | 183 |
| 182 private: | 184 private: |
| 183 std::stack<Operation> stack_; | 185 std::stack<AbortOperation> stack_; |
| 184 | 186 |
| 185 DISALLOW_COPY_AND_ASSIGN(TaskStack); | 187 DISALLOW_COPY_AND_ASSIGN(TaskStack); |
| 186 }; | 188 }; |
| 187 | 189 |
| 188 TaskQueue task_queue_; | 190 TaskQueue task_queue_; |
| 189 TaskQueue preemptive_task_queue_; | 191 TaskQueue preemptive_task_queue_; |
| 190 TaskStack abort_task_stack_; | 192 TaskStack abort_task_stack_; |
| 191 | 193 |
| 192 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction_; | 194 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction_; |
| 193 bool backing_store_transaction_begun_; | 195 bool backing_store_transaction_begun_ = false; |
| 194 | 196 |
| 195 bool should_process_queue_; | 197 bool should_process_queue_ = false; |
| 196 int pending_preemptive_events_; | 198 int pending_preemptive_events_ = 0; |
| 199 bool processing_event_queue_ = false; |
| 197 | 200 |
| 198 std::set<IndexedDBCursor*> open_cursors_; | 201 std::set<IndexedDBCursor*> open_cursors_; |
| 199 | 202 |
| 200 // This timer is started after requests have been processed. If no subsequent | 203 // This timer is started after requests have been processed. If no subsequent |
| 201 // requests are processed before the timer fires, assume the script is | 204 // requests are processed before the timer fires, assume the script is |
| 202 // unresponsive and abort to unblock the transaction queue. | 205 // unresponsive and abort to unblock the transaction queue. |
| 203 base::OneShotTimer timeout_timer_; | 206 base::OneShotTimer timeout_timer_; |
| 204 | 207 |
| 205 Diagnostics diagnostics_; | 208 Diagnostics diagnostics_; |
| 206 }; | 209 }; |
| 207 | 210 |
| 208 } // namespace content | 211 } // namespace content |
| 209 | 212 |
| 210 #endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_TRANSACTION_H_ | 213 #endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_TRANSACTION_H_ |
| OLD | NEW |