Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(639)

Side by Side Diff: content/browser/indexed_db/indexed_db_transaction.cc

Issue 18023022: Blob support for IDB [Chromium] (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Yet still more build fixes. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #include "content/browser/indexed_db/indexed_db_transaction.h" 5 #include "content/browser/indexed_db/indexed_db_transaction.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 // complete or aborted. 81 // complete or aborted.
82 DCHECK_EQ(state_, FINISHED); 82 DCHECK_EQ(state_, FINISHED);
83 DCHECK(preemptive_task_queue_.empty()); 83 DCHECK(preemptive_task_queue_.empty());
84 DCHECK_EQ(pending_preemptive_events_, 0); 84 DCHECK_EQ(pending_preemptive_events_, 0);
85 DCHECK(task_queue_.empty()); 85 DCHECK(task_queue_.empty());
86 DCHECK(abort_task_stack_.empty()); 86 DCHECK(abort_task_stack_.empty());
87 } 87 }
88 88
89 void IndexedDBTransaction::ScheduleTask(IndexedDBDatabase::TaskType type, 89 void IndexedDBTransaction::ScheduleTask(IndexedDBDatabase::TaskType type,
90 Operation task) { 90 Operation task) {
91 if (state_ == FINISHED) 91 if (IsStatePastStarted())
92 return; 92 return;
93 93
94 timeout_timer_.Stop(); 94 timeout_timer_.Stop();
95 used_ = true; 95 used_ = true;
96 if (type == IndexedDBDatabase::NORMAL_TASK) { 96 if (type == IndexedDBDatabase::NORMAL_TASK) {
97 task_queue_.push(task); 97 task_queue_.push(task);
98 ++diagnostics_.tasks_scheduled; 98 ++diagnostics_.tasks_scheduled;
99 } else { 99 } else {
100 preemptive_task_queue_.push(task); 100 preemptive_task_queue_.push(task);
101 } 101 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 DCHECK_EQ(CREATED, state_); 199 DCHECK_EQ(CREATED, state_);
200 state_ = STARTED; 200 state_ = STARTED;
201 diagnostics_.start_time = base::Time::Now(); 201 diagnostics_.start_time = base::Time::Now();
202 202
203 if (!used_) 203 if (!used_)
204 return; 204 return;
205 205
206 RunTasksIfStarted(); 206 RunTasksIfStarted();
207 } 207 }
208 208
209 class BlobWriteCallbackImpl : public IndexedDBBackingStore::BlobWriteCallback {
210 public:
211 BlobWriteCallbackImpl(scoped_refptr<IndexedDBTransaction> transaction)
212 : transaction_(transaction) {}
213 virtual void Run(bool succeeded) OVERRIDE {
214 transaction_->BlobWriteComplete(succeeded);
215 }
216
217 protected:
218 virtual ~BlobWriteCallbackImpl() {}
219
220 private:
221 scoped_refptr<IndexedDBTransaction> transaction_;
222 };
223
224 void IndexedDBTransaction::BlobWriteComplete(bool success) {
225 IDB_TRACE("IndexedDBTransaction::BlobWriteComplete");
226 if (state_ == FINISHED) // aborted
227 return;
228 DCHECK_EQ(state_, COMMITTING);
229 if (success)
230 CommitPhaseTwo();
231 else
232 Abort(IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionDataError,
233 "Failed to write blobs."));
234 }
235
209 void IndexedDBTransaction::Commit() { 236 void IndexedDBTransaction::Commit() {
210 IDB_TRACE("IndexedDBTransaction::Commit"); 237 IDB_TRACE("IndexedDBTransaction::Commit");
211 238
212 // In multiprocess ports, front-end may have requested a commit but 239 // In multiprocess ports, front-end may have requested a commit but
213 // an abort has already been initiated asynchronously by the 240 // an abort has already been initiated asynchronously by the
214 // back-end. 241 // back-end.
215 if (state_ == FINISHED) 242 if (IsStatePastStarted()) {
243 DCHECK(state_ == FINISHED);
216 return; 244 return;
245 }
217 246
218 DCHECK(!used_ || state_ == STARTED); 247 DCHECK(!used_ || state_ == STARTED);
219 commit_pending_ = true; 248 commit_pending_ = true;
220 249
221 // Front-end has requested a commit, but there may be tasks like 250 // Front-end has requested a commit, but there may be tasks like
222 // create_index which are considered synchronous by the front-end 251 // create_index which are considered synchronous by the front-end
223 // but are processed asynchronously. 252 // but are processed asynchronously.
224 if (HasPendingTasks()) 253 if (HasPendingTasks())
225 return; 254 return;
226 255
256 state_ = COMMITTING;
257
258 if (!used_)
259 CommitPhaseTwo();
260 else {
261 scoped_refptr<IndexedDBBackingStore::BlobWriteCallback> callback(
262 new BlobWriteCallbackImpl(this));
263 // CommitPhaseOne will call the callback synchronously if there are no blobs
264 // to write.
265 if (!transaction_->CommitPhaseOne(callback).ok())
cmumford 2014/05/28 22:35:02 Are we still preserving the ability to distinguish
ericu 2014/05/28 22:50:43 This change doesn't worsen corruption reporting.
266 Abort(IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionDataError,
267 "Error processing blob journal."));
268 }
269 }
270
271 void IndexedDBTransaction::CommitPhaseTwo() {
272 // Abort may have been called just as the blob write completed.
273 if (state_ == FINISHED)
274 return;
275
276 DCHECK_EQ(state_, COMMITTING);
277
227 // The last reference to this object may be released while performing the 278 // The last reference to this object may be released while performing the
228 // commit steps below. We therefore take a self reference to keep ourselves 279 // commit steps below. We therefore take a self reference to keep ourselves
229 // alive while executing this method. 280 // alive while executing this method.
230 scoped_refptr<IndexedDBTransaction> protect(this); 281 scoped_refptr<IndexedDBTransaction> protect(this);
231 282
232 timeout_timer_.Stop(); 283 timeout_timer_.Stop();
233 284
234 state_ = FINISHED; 285 state_ = FINISHED;
235 286
236 bool committed = !used_ || transaction_->Commit().ok(); 287 bool committed = !used_ || transaction_->CommitPhaseTwo().ok();
237 288
238 // Backing store resources (held via cursors) must be released 289 // Backing store resources (held via cursors) must be released
239 // before script callbacks are fired, as the script callbacks may 290 // before script callbacks are fired, as the script callbacks may
240 // release references and allow the backing store itself to be 291 // release references and allow the backing store itself to be
241 // released, and order is critical. 292 // released, and order is critical.
242 CloseOpenCursors(); 293 CloseOpenCursors();
243 transaction_->Reset(); 294 transaction_->Reset();
244 295
245 // Transactions must also be marked as completed before the 296 // Transactions must also be marked as completed before the
246 // front-end is notified, as the transaction completion unblocks 297 // front-end is notified, as the transaction completion unblocks
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 backing_store_transaction_begun_ = true; 332 backing_store_transaction_begun_ = true;
282 } 333 }
283 334
284 // The last reference to this object may be released while performing the 335 // The last reference to this object may be released while performing the
285 // tasks. Take take a self reference to keep this object alive so that 336 // tasks. Take take a self reference to keep this object alive so that
286 // the loop termination conditions can be checked. 337 // the loop termination conditions can be checked.
287 scoped_refptr<IndexedDBTransaction> protect(this); 338 scoped_refptr<IndexedDBTransaction> protect(this);
288 339
289 TaskQueue* task_queue = 340 TaskQueue* task_queue =
290 pending_preemptive_events_ ? &preemptive_task_queue_ : &task_queue_; 341 pending_preemptive_events_ ? &preemptive_task_queue_ : &task_queue_;
291 while (!task_queue->empty() && state_ != FINISHED) { 342 while (!task_queue->empty() && !IsStatePastStarted()) {
292 DCHECK_EQ(STARTED, state_); 343 DCHECK_EQ(state_, STARTED);
293 Operation task(task_queue->pop()); 344 Operation task(task_queue->pop());
294 task.Run(this); 345 task.Run(this);
295 if (!pending_preemptive_events_) { 346 if (!pending_preemptive_events_) {
296 DCHECK(diagnostics_.tasks_completed < diagnostics_.tasks_scheduled); 347 DCHECK(diagnostics_.tasks_completed < diagnostics_.tasks_scheduled);
297 ++diagnostics_.tasks_completed; 348 ++diagnostics_.tasks_completed;
298 } 349 }
299 350
300 // Event itself may change which queue should be processed next. 351 // Event itself may change which queue should be processed next.
301 task_queue = 352 task_queue =
302 pending_preemptive_events_ ? &preemptive_task_queue_ : &task_queue_; 353 pending_preemptive_events_ ? &preemptive_task_queue_ : &task_queue_;
303 } 354 }
304 355
305 // If there are no pending tasks, we haven't already committed/aborted, 356 // If there are no pending tasks, we haven't already committed/aborted,
306 // and the front-end requested a commit, it is now safe to do so. 357 // and the front-end requested a commit, it is now safe to do so.
307 if (!HasPendingTasks() && state_ != FINISHED && commit_pending_) { 358 if (!HasPendingTasks() && !IsStatePastStarted() && commit_pending_) {
308 Commit(); 359 Commit();
309 return; 360 return;
310 } 361 }
311 362
312 // The transaction may have been aborted while processing tasks. 363 // The transaction may have been aborted while processing tasks.
313 if (state_ == FINISHED) 364 if (state_ == FINISHED)
314 return; 365 return;
315 366
316 // Otherwise, start a timer in case the front-end gets wedged and 367 // Otherwise, start a timer in case the front-end gets wedged and
317 // never requests further activity. Read-only transactions don't 368 // never requests further activity. Read-only transactions don't
(...skipping 14 matching lines...) Expand all
332 383
333 void IndexedDBTransaction::CloseOpenCursors() { 384 void IndexedDBTransaction::CloseOpenCursors() {
334 for (std::set<IndexedDBCursor*>::iterator i = open_cursors_.begin(); 385 for (std::set<IndexedDBCursor*>::iterator i = open_cursors_.begin();
335 i != open_cursors_.end(); 386 i != open_cursors_.end();
336 ++i) 387 ++i)
337 (*i)->Close(); 388 (*i)->Close();
338 open_cursors_.clear(); 389 open_cursors_.clear();
339 } 390 }
340 391
341 } // namespace content 392 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/indexed_db/indexed_db_transaction.h ('k') | content/browser/indexed_db/indexed_db_transaction_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698