OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_TRANSACTION_H_ | |
6 #define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_TRANSACTION_H_ | |
7 | |
8 #include <queue> | |
9 #include <set> | |
10 #include <stack> | |
11 #include <vector> | |
12 | |
13 #include "base/basictypes.h" | |
14 #include "base/memory/ref_counted.h" | |
15 #include "base/memory/scoped_ptr.h" | |
16 #include "base/timer.h" | |
17 #include "content/browser/indexed_db/indexed_db_backing_store.h" | |
18 #include "content/browser/indexed_db/indexed_db_database.h" | |
19 #include "content/browser/indexed_db/indexed_db_database_error.h" | |
20 | |
21 namespace content { | |
22 | |
23 class IndexedDBDatabaseImpl; | |
24 class IndexedDBCursorImpl; | |
25 class IndexedDBDatabaseCallbacksWrapper; | |
26 | |
27 class IndexedDBTransaction : public base::RefCounted<IndexedDBTransaction> { | |
28 public: | |
29 static scoped_refptr<IndexedDBTransaction> Create( | |
30 int64 transaction_id, | |
31 scoped_refptr<IndexedDBDatabaseCallbacksWrapper> callbacks, | |
32 const std::vector<int64>& scope, | |
33 indexed_db::TransactionMode, | |
34 IndexedDBDatabaseImpl* db); | |
35 | |
36 virtual void Abort(); | |
37 void Commit(); | |
38 | |
39 class Operation { | |
40 public: | |
41 Operation() {} | |
42 virtual ~Operation() {} | |
43 virtual void Perform(IndexedDBTransaction* transaction) = 0; | |
44 }; | |
45 | |
46 void Abort(scoped_refptr<IndexedDBDatabaseError> error); | |
47 void Run(); | |
48 indexed_db::TransactionMode mode() const { return mode_; } | |
49 const std::set<int64>& scope() const { return object_store_ids_; } | |
50 void ScheduleTask(Operation* task, Operation* abort_task = NULL) { | |
51 ScheduleTask(IndexedDBDatabase::NORMAL_TASK, task, abort_task); | |
52 } | |
53 void ScheduleTask(IndexedDBDatabase::TaskType, | |
54 Operation* task, | |
55 Operation* abort_task = NULL); | |
56 void RegisterOpenCursor(IndexedDBCursorImpl* cursor); | |
57 void UnregisterOpenCursor(IndexedDBCursorImpl* cursor); | |
58 void AddPreemptiveEvent() { pending_preemptive_events_++; } | |
59 void DidCompletePreemptiveEvent() { | |
60 pending_preemptive_events_--; | |
61 DCHECK_GE(pending_preemptive_events_, 0); | |
62 } | |
63 IndexedDBBackingStore::Transaction* BackingStoreTransaction() { | |
64 return &transaction_; | |
65 } | |
66 int64 id() const { return id_; } | |
67 | |
68 IndexedDBDatabaseImpl* database() const { return database_.get(); } | |
69 IndexedDBDatabaseCallbacksWrapper* connection() const { | |
70 return callbacks_.get(); | |
71 } | |
72 | |
73 protected: | |
74 virtual ~IndexedDBTransaction(); | |
75 friend class base::RefCounted<IndexedDBTransaction>; | |
76 | |
77 private: | |
78 IndexedDBTransaction( | |
79 int64 id, | |
80 scoped_refptr<IndexedDBDatabaseCallbacksWrapper> callbacks, | |
81 const std::set<int64>& object_store_ids, | |
82 indexed_db::TransactionMode, | |
83 IndexedDBDatabaseImpl* db); | |
84 | |
85 enum State { | |
86 UNUSED, // Created, but no tasks yet. | |
87 START_PENDING, // Enqueued tasks, but backing store transaction not yet | |
88 // started. | |
89 RUNNING, // Backing store transaction started but not yet finished. | |
90 FINISHED, // Either aborted or committed. | |
91 }; | |
92 | |
93 void Start(); | |
94 | |
95 bool IsTaskQueueEmpty() const; | |
96 bool HasPendingTasks() const; | |
97 | |
98 void TaskTimerFired(); | |
99 void CloseOpenCursors(); | |
100 | |
101 const int64 id_; | |
102 const std::set<int64> object_store_ids_; | |
103 const indexed_db::TransactionMode mode_; | |
104 | |
105 State state_; | |
106 bool commit_pending_; | |
107 scoped_refptr<IndexedDBDatabaseCallbacksWrapper> callbacks_; | |
108 scoped_refptr<IndexedDBDatabaseImpl> database_; | |
109 | |
110 class TaskQueue { | |
111 public: | |
112 TaskQueue(); | |
113 ~TaskQueue(); | |
114 bool empty() const { return queue_.empty(); } | |
115 void push(Operation* task) { queue_.push(task); } | |
116 scoped_ptr<Operation> pop(); | |
117 void clear(); | |
118 | |
119 private: | |
120 std::queue<Operation*> queue_; | |
121 }; | |
122 | |
123 class TaskStack { | |
124 public: | |
125 TaskStack(); | |
126 ~TaskStack(); | |
127 bool empty() const { return stack_.empty(); } | |
128 void push(Operation* task) { stack_.push(task); } | |
129 scoped_ptr<Operation> pop(); | |
130 void clear(); | |
131 | |
132 private: | |
133 std::stack<Operation*> stack_; | |
134 }; | |
135 | |
136 TaskQueue task_queue_; | |
137 TaskQueue preemptive_task_queue_; | |
138 TaskStack abort_task_stack_; | |
139 | |
140 IndexedDBBackingStore::Transaction transaction_; | |
141 | |
142 base::OneShotTimer<IndexedDBTransaction> task_timer_; | |
143 int pending_preemptive_events_; | |
144 | |
145 std::set<IndexedDBCursorImpl*> open_cursors_; | |
146 }; | |
147 | |
148 } // namespace content | |
149 | |
150 #endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_TRANSACTION_H_ | |
OLD | NEW |