| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 #include "core/events/EventQueue.h" | 41 #include "core/events/EventQueue.h" |
| 42 #include "modules/IndexedDBNames.h" | 42 #include "modules/IndexedDBNames.h" |
| 43 #include "modules/indexeddb/IDBCursorWithValue.h" | 43 #include "modules/indexeddb/IDBCursorWithValue.h" |
| 44 #include "modules/indexeddb/IDBDatabase.h" | 44 #include "modules/indexeddb/IDBDatabase.h" |
| 45 #include "modules/indexeddb/IDBEventDispatcher.h" | 45 #include "modules/indexeddb/IDBEventDispatcher.h" |
| 46 #include "modules/indexeddb/IDBRequestQueueItem.h" | 46 #include "modules/indexeddb/IDBRequestQueueItem.h" |
| 47 #include "modules/indexeddb/IDBTracing.h" | 47 #include "modules/indexeddb/IDBTracing.h" |
| 48 #include "modules/indexeddb/IDBValue.h" | 48 #include "modules/indexeddb/IDBValue.h" |
| 49 #include "modules/indexeddb/IDBValueWrapping.h" | 49 #include "modules/indexeddb/IDBValueWrapping.h" |
| 50 #include "modules/indexeddb/WebIDBCallbacksImpl.h" | 50 #include "modules/indexeddb/WebIDBCallbacksImpl.h" |
| 51 #include "platform/Histogram.h" |
| 51 #include "platform/SharedBuffer.h" | 52 #include "platform/SharedBuffer.h" |
| 52 #include "platform/heap/Handle.h" | 53 #include "platform/heap/Handle.h" |
| 53 #include "platform/wtf/PtrUtil.h" | 54 #include "platform/wtf/PtrUtil.h" |
| 54 #include "public/platform/WebBlobInfo.h" | 55 #include "public/platform/WebBlobInfo.h" |
| 55 | 56 |
| 56 using blink::WebIDBCursor; | 57 using blink::WebIDBCursor; |
| 57 | 58 |
| 58 namespace blink { | 59 namespace blink { |
| 59 | 60 |
| 61 IDBRequest::AsyncTraceState::AsyncTraceState(const char* tracing_name, void* id) |
| 62 : tracing_name_(tracing_name), id_(id) { |
| 63 if (tracing_name_) |
| 64 TRACE_EVENT_ASYNC_BEGIN0("IndexedDB", tracing_name_, id); |
| 65 } |
| 66 |
| 67 void IDBRequest::AsyncTraceState::RecordAndReset() { |
| 68 if (tracing_name_) |
| 69 TRACE_EVENT_ASYNC_END0("IndexedDB", tracing_name_, id_); |
| 70 tracing_name_ = nullptr; |
| 71 } |
| 72 |
| 73 IDBRequest::AsyncTraceState::~AsyncTraceState() { |
| 74 if (tracing_name_) |
| 75 TRACE_EVENT_ASYNC_END0("IndexedDB", tracing_name_, id_); |
| 76 } |
| 77 |
| 60 IDBRequest* IDBRequest::Create(ScriptState* script_state, | 78 IDBRequest* IDBRequest::Create(ScriptState* script_state, |
| 61 IDBAny* source, | 79 IDBAny* source, |
| 62 IDBTransaction* transaction) { | 80 IDBTransaction* transaction, |
| 63 IDBRequest* request = new IDBRequest(script_state, source, transaction); | 81 IDBRequest::AsyncTraceState metrics) { |
| 82 IDBRequest* request = |
| 83 new IDBRequest(script_state, source, transaction, std::move(metrics)); |
| 64 request->SuspendIfNeeded(); | 84 request->SuspendIfNeeded(); |
| 65 // Requests associated with IDBFactory (open/deleteDatabase/getDatabaseNames) | 85 // Requests associated with IDBFactory (open/deleteDatabase/getDatabaseNames) |
| 66 // do not have an associated transaction. | 86 // do not have an associated transaction. |
| 67 if (transaction) | 87 if (transaction) |
| 68 transaction->RegisterRequest(request); | 88 transaction->RegisterRequest(request); |
| 69 return request; | 89 return request; |
| 70 } | 90 } |
| 71 | 91 |
| 72 IDBRequest::IDBRequest(ScriptState* script_state, | 92 IDBRequest::IDBRequest(ScriptState* script_state, |
| 73 IDBAny* source, | 93 IDBAny* source, |
| 74 IDBTransaction* transaction) | 94 IDBTransaction* transaction, |
| 95 AsyncTraceState metrics) |
| 75 : SuspendableObject(ExecutionContext::From(script_state)), | 96 : SuspendableObject(ExecutionContext::From(script_state)), |
| 76 transaction_(transaction), | 97 transaction_(transaction), |
| 77 isolate_(script_state->GetIsolate()), | 98 isolate_(script_state->GetIsolate()), |
| 78 source_(source) {} | 99 source_(source), |
| 100 metrics_(std::move(metrics)) {} |
| 79 | 101 |
| 80 IDBRequest::~IDBRequest() { | 102 IDBRequest::~IDBRequest() { |
| 81 DCHECK(ready_state_ == DONE || ready_state_ == kEarlyDeath || | 103 DCHECK((ready_state_ == DONE && !metrics_.is_valid()) || |
| 82 !GetExecutionContext()); | 104 ready_state_ == kEarlyDeath || !GetExecutionContext()); |
| 83 } | 105 } |
| 84 | 106 |
| 85 DEFINE_TRACE(IDBRequest) { | 107 DEFINE_TRACE(IDBRequest) { |
| 86 visitor->Trace(transaction_); | 108 visitor->Trace(transaction_); |
| 87 visitor->Trace(source_); | 109 visitor->Trace(source_); |
| 88 visitor->Trace(result_); | 110 visitor->Trace(result_); |
| 89 visitor->Trace(error_); | 111 visitor->Trace(error_); |
| 90 visitor->Trace(enqueued_events_); | 112 visitor->Trace(enqueued_events_); |
| 91 visitor->Trace(pending_cursor_); | 113 visitor->Trace(pending_cursor_); |
| 92 visitor->Trace(cursor_key_); | 114 visitor->Trace(cursor_key_); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 return EnqueueResponse(key, primary_key, std::move(value)); | 361 return EnqueueResponse(key, primary_key, std::move(value)); |
| 340 | 362 |
| 341 transaction_->EnqueueResult(WTF::MakeUnique<IDBRequestQueueItem>( | 363 transaction_->EnqueueResult(WTF::MakeUnique<IDBRequestQueueItem>( |
| 342 this, key, primary_key, std::move(value), is_wrapped, | 364 this, key, primary_key, std::move(value), is_wrapped, |
| 343 WTF::Bind(&IDBTransaction::OnResultReady, | 365 WTF::Bind(&IDBTransaction::OnResultReady, |
| 344 WrapPersistent(transaction_.Get())))); | 366 WrapPersistent(transaction_.Get())))); |
| 345 } | 367 } |
| 346 | 368 |
| 347 void IDBRequest::EnqueueResponse(DOMException* error) { | 369 void IDBRequest::EnqueueResponse(DOMException* error) { |
| 348 IDB_TRACE("IDBRequest::EnqueueResponse(DOMException)"); | 370 IDB_TRACE("IDBRequest::EnqueueResponse(DOMException)"); |
| 349 if (!ShouldEnqueueEvent()) | 371 if (!ShouldEnqueueEvent()) { |
| 372 metrics_.RecordAndReset(); |
| 350 return; | 373 return; |
| 374 } |
| 351 | 375 |
| 352 error_ = error; | 376 error_ = error; |
| 353 SetResult(IDBAny::CreateUndefined()); | 377 SetResult(IDBAny::CreateUndefined()); |
| 354 pending_cursor_.Clear(); | 378 pending_cursor_.Clear(); |
| 355 EnqueueEvent(Event::CreateCancelableBubble(EventTypeNames::error)); | 379 EnqueueEvent(Event::CreateCancelableBubble(EventTypeNames::error)); |
| 380 metrics_.RecordAndReset(); |
| 356 } | 381 } |
| 357 | 382 |
| 358 void IDBRequest::EnqueueResponse(const Vector<String>& string_list) { | 383 void IDBRequest::EnqueueResponse(const Vector<String>& string_list) { |
| 359 IDB_TRACE("IDBRequest::onSuccess(StringList)"); | 384 IDB_TRACE("IDBRequest::onSuccess(StringList)"); |
| 360 if (!ShouldEnqueueEvent()) | 385 if (!ShouldEnqueueEvent()) { |
| 386 metrics_.RecordAndReset(); |
| 361 return; | 387 return; |
| 388 } |
| 362 | 389 |
| 363 DOMStringList* dom_string_list = DOMStringList::Create(); | 390 DOMStringList* dom_string_list = DOMStringList::Create(); |
| 364 for (size_t i = 0; i < string_list.size(); ++i) | 391 for (size_t i = 0; i < string_list.size(); ++i) |
| 365 dom_string_list->Append(string_list[i]); | 392 dom_string_list->Append(string_list[i]); |
| 366 EnqueueResultInternal(IDBAny::Create(dom_string_list)); | 393 EnqueueResultInternal(IDBAny::Create(dom_string_list)); |
| 394 metrics_.RecordAndReset(); |
| 367 } | 395 } |
| 368 | 396 |
| 369 void IDBRequest::EnqueueResponse(std::unique_ptr<WebIDBCursor> backend, | 397 void IDBRequest::EnqueueResponse(std::unique_ptr<WebIDBCursor> backend, |
| 370 IDBKey* key, | 398 IDBKey* key, |
| 371 IDBKey* primary_key, | 399 IDBKey* primary_key, |
| 372 RefPtr<IDBValue>&& value) { | 400 RefPtr<IDBValue>&& value) { |
| 373 IDB_TRACE("IDBRequest::EnqueueResponse(IDBCursor)"); | 401 IDB_TRACE("IDBRequest::EnqueueResponse(IDBCursor)"); |
| 374 if (!ShouldEnqueueEvent()) | 402 if (!ShouldEnqueueEvent()) { |
| 403 metrics_.RecordAndReset(); |
| 375 return; | 404 return; |
| 405 } |
| 376 | 406 |
| 377 DCHECK(!pending_cursor_); | 407 DCHECK(!pending_cursor_); |
| 378 IDBCursor* cursor = nullptr; | 408 IDBCursor* cursor = nullptr; |
| 379 switch (cursor_type_) { | 409 switch (cursor_type_) { |
| 380 case IndexedDB::kCursorKeyOnly: | 410 case IndexedDB::kCursorKeyOnly: |
| 381 cursor = IDBCursor::Create(std::move(backend), cursor_direction_, this, | 411 cursor = IDBCursor::Create(std::move(backend), cursor_direction_, this, |
| 382 source_.Get(), transaction_.Get()); | 412 source_.Get(), transaction_.Get()); |
| 383 break; | 413 break; |
| 384 case IndexedDB::kCursorKeyAndValue: | 414 case IndexedDB::kCursorKeyAndValue: |
| 385 cursor = | 415 cursor = |
| 386 IDBCursorWithValue::Create(std::move(backend), cursor_direction_, | 416 IDBCursorWithValue::Create(std::move(backend), cursor_direction_, |
| 387 this, source_.Get(), transaction_.Get()); | 417 this, source_.Get(), transaction_.Get()); |
| 388 break; | 418 break; |
| 389 default: | 419 default: |
| 390 NOTREACHED(); | 420 NOTREACHED(); |
| 391 } | 421 } |
| 392 SetResultCursor(cursor, key, primary_key, std::move(value)); | 422 SetResultCursor(cursor, key, primary_key, std::move(value)); |
| 423 metrics_.RecordAndReset(); |
| 393 } | 424 } |
| 394 | 425 |
| 395 void IDBRequest::EnqueueResponse(IDBKey* idb_key) { | 426 void IDBRequest::EnqueueResponse(IDBKey* idb_key) { |
| 396 IDB_TRACE("IDBRequest::EnqueueResponse(IDBKey)"); | 427 IDB_TRACE("IDBRequest::EnqueueResponse(IDBKey)"); |
| 397 if (!ShouldEnqueueEvent()) | 428 if (!ShouldEnqueueEvent()) { |
| 429 metrics_.RecordAndReset(); |
| 398 return; | 430 return; |
| 431 } |
| 399 | 432 |
| 400 if (idb_key && idb_key->IsValid()) | 433 if (idb_key && idb_key->IsValid()) |
| 401 EnqueueResultInternal(IDBAny::Create(idb_key)); | 434 EnqueueResultInternal(IDBAny::Create(idb_key)); |
| 402 else | 435 else |
| 403 EnqueueResultInternal(IDBAny::CreateUndefined()); | 436 EnqueueResultInternal(IDBAny::CreateUndefined()); |
| 437 metrics_.RecordAndReset(); |
| 404 } | 438 } |
| 405 | 439 |
| 406 void IDBRequest::EnqueueResponse(const Vector<RefPtr<IDBValue>>& values) { | 440 void IDBRequest::EnqueueResponse(const Vector<RefPtr<IDBValue>>& values) { |
| 407 IDB_TRACE("IDBRequest::EnqueueResponse([IDBValue])"); | 441 IDB_TRACE("IDBRequest::EnqueueResponse([IDBValue])"); |
| 408 if (!ShouldEnqueueEvent()) | 442 if (!ShouldEnqueueEvent()) { |
| 443 metrics_.RecordAndReset(); |
| 409 return; | 444 return; |
| 445 } |
| 410 | 446 |
| 411 AckReceivedBlobs(values); | 447 AckReceivedBlobs(values); |
| 412 EnqueueResultInternal(IDBAny::Create(values)); | 448 EnqueueResultInternal(IDBAny::Create(values)); |
| 449 metrics_.RecordAndReset(); |
| 413 } | 450 } |
| 414 | 451 |
| 415 #if DCHECK_IS_ON() | 452 #if DCHECK_IS_ON() |
| 416 static IDBObjectStore* EffectiveObjectStore(IDBAny* source) { | 453 static IDBObjectStore* EffectiveObjectStore(IDBAny* source) { |
| 417 if (source->GetType() == IDBAny::kIDBObjectStoreType) | 454 if (source->GetType() == IDBAny::kIDBObjectStoreType) |
| 418 return source->IdbObjectStore(); | 455 return source->IdbObjectStore(); |
| 419 if (source->GetType() == IDBAny::kIDBIndexType) | 456 if (source->GetType() == IDBAny::kIDBIndexType) |
| 420 return source->IdbIndex()->objectStore(); | 457 return source->IdbIndex()->objectStore(); |
| 421 | 458 |
| 422 NOTREACHED(); | 459 NOTREACHED(); |
| 423 return nullptr; | 460 return nullptr; |
| 424 } | 461 } |
| 425 #endif // DCHECK_IS_ON() | 462 #endif // DCHECK_IS_ON() |
| 426 | 463 |
| 427 void IDBRequest::EnqueueResponse(RefPtr<IDBValue>&& value) { | 464 void IDBRequest::EnqueueResponse(RefPtr<IDBValue>&& value) { |
| 428 IDB_TRACE("IDBRequest::EnqueueResponse(IDBValue)"); | 465 IDB_TRACE("IDBRequest::EnqueueResponse(IDBValue)"); |
| 429 if (!ShouldEnqueueEvent()) | 466 if (!ShouldEnqueueEvent()) { |
| 467 metrics_.RecordAndReset(); |
| 430 return; | 468 return; |
| 469 } |
| 431 | 470 |
| 432 AckReceivedBlobs(value.Get()); | 471 AckReceivedBlobs(value.Get()); |
| 433 | 472 |
| 434 if (pending_cursor_) { | 473 if (pending_cursor_) { |
| 435 // Value should be null, signifying the end of the cursor's range. | 474 // Value should be null, signifying the end of the cursor's range. |
| 436 DCHECK(value->IsNull()); | 475 DCHECK(value->IsNull()); |
| 437 DCHECK(!value->BlobInfo()->size()); | 476 DCHECK(!value->BlobInfo()->size()); |
| 438 pending_cursor_->Close(); | 477 pending_cursor_->Close(); |
| 439 pending_cursor_.Clear(); | 478 pending_cursor_.Clear(); |
| 440 } | 479 } |
| 441 | 480 |
| 442 #if DCHECK_IS_ON() | 481 #if DCHECK_IS_ON() |
| 443 DCHECK(!value->PrimaryKey() || | 482 DCHECK(!value->PrimaryKey() || |
| 444 value->KeyPath() == EffectiveObjectStore(source_)->IdbKeyPath()); | 483 value->KeyPath() == EffectiveObjectStore(source_)->IdbKeyPath()); |
| 445 #endif | 484 #endif |
| 446 | 485 |
| 447 EnqueueResultInternal(IDBAny::Create(std::move(value))); | 486 EnqueueResultInternal(IDBAny::Create(std::move(value))); |
| 487 metrics_.RecordAndReset(); |
| 448 } | 488 } |
| 449 | 489 |
| 450 void IDBRequest::EnqueueResponse(int64_t value) { | 490 void IDBRequest::EnqueueResponse(int64_t value) { |
| 451 IDB_TRACE("IDBRequest::EnqueueResponse(int64_t)"); | 491 IDB_TRACE("IDBRequest::EnqueueResponse(int64_t)"); |
| 452 if (!ShouldEnqueueEvent()) | 492 if (!ShouldEnqueueEvent()) { |
| 493 metrics_.RecordAndReset(); |
| 453 return; | 494 return; |
| 495 } |
| 454 EnqueueResultInternal(IDBAny::Create(value)); | 496 EnqueueResultInternal(IDBAny::Create(value)); |
| 497 metrics_.RecordAndReset(); |
| 455 } | 498 } |
| 456 | 499 |
| 457 void IDBRequest::EnqueueResponse() { | 500 void IDBRequest::EnqueueResponse() { |
| 458 IDB_TRACE("IDBRequest::EnqueueResponse()"); | 501 IDB_TRACE("IDBRequest::EnqueueResponse()"); |
| 459 if (!ShouldEnqueueEvent()) | 502 if (!ShouldEnqueueEvent()) { |
| 503 metrics_.RecordAndReset(); |
| 460 return; | 504 return; |
| 505 } |
| 461 EnqueueResultInternal(IDBAny::CreateUndefined()); | 506 EnqueueResultInternal(IDBAny::CreateUndefined()); |
| 507 metrics_.RecordAndReset(); |
| 462 } | 508 } |
| 463 | 509 |
| 464 void IDBRequest::EnqueueResultInternal(IDBAny* result) { | 510 void IDBRequest::EnqueueResultInternal(IDBAny* result) { |
| 465 DCHECK(GetExecutionContext()); | 511 DCHECK(GetExecutionContext()); |
| 466 DCHECK(!pending_cursor_); | 512 DCHECK(!pending_cursor_); |
| 467 DCHECK(transit_blob_handles_.IsEmpty()); | 513 DCHECK(transit_blob_handles_.IsEmpty()); |
| 468 SetResult(result); | 514 SetResult(result); |
| 469 EnqueueEvent(Event::Create(EventTypeNames::success)); | 515 EnqueueEvent(Event::Create(EventTypeNames::success)); |
| 470 } | 516 } |
| 471 | 517 |
| 472 void IDBRequest::SetResult(IDBAny* result) { | 518 void IDBRequest::SetResult(IDBAny* result) { |
| 473 result_ = result; | 519 result_ = result; |
| 474 result_dirty_ = true; | 520 result_dirty_ = true; |
| 475 } | 521 } |
| 476 | 522 |
| 477 void IDBRequest::EnqueueResponse(IDBKey* key, | 523 void IDBRequest::EnqueueResponse(IDBKey* key, |
| 478 IDBKey* primary_key, | 524 IDBKey* primary_key, |
| 479 RefPtr<IDBValue>&& value) { | 525 RefPtr<IDBValue>&& value) { |
| 480 IDB_TRACE("IDBRequest::EnqueueResponse(IDBKey, IDBKey primaryKey, IDBValue)"); | 526 IDB_TRACE("IDBRequest::EnqueueResponse(IDBKey, IDBKey primaryKey, IDBValue)"); |
| 481 if (!ShouldEnqueueEvent()) | 527 if (!ShouldEnqueueEvent()) { |
| 528 metrics_.RecordAndReset(); |
| 482 return; | 529 return; |
| 530 } |
| 483 | 531 |
| 484 DCHECK(pending_cursor_); | 532 DCHECK(pending_cursor_); |
| 485 SetResultCursor(pending_cursor_.Release(), key, primary_key, | 533 SetResultCursor(pending_cursor_.Release(), key, primary_key, |
| 486 std::move(value)); | 534 std::move(value)); |
| 535 metrics_.RecordAndReset(); |
| 487 } | 536 } |
| 488 | 537 |
| 489 bool IDBRequest::HasPendingActivity() const { | 538 bool IDBRequest::HasPendingActivity() const { |
| 490 // FIXME: In an ideal world, we should return true as long as anyone has a or | 539 // FIXME: In an ideal world, we should return true as long as anyone has a or |
| 491 // can get a handle to us and we have event listeners. This is order to | 540 // can get a handle to us and we have event listeners. This is order to |
| 492 // handle user generated events properly. | 541 // handle user generated events properly. |
| 493 return has_pending_activity_ && GetExecutionContext(); | 542 return has_pending_activity_ && GetExecutionContext(); |
| 494 } | 543 } |
| 495 | 544 |
| 496 void IDBRequest::ContextDestroyed(ExecutionContext*) { | 545 void IDBRequest::ContextDestroyed(ExecutionContext*) { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 } | 712 } |
| 664 | 713 |
| 665 void IDBRequest::DequeueEvent(Event* event) { | 714 void IDBRequest::DequeueEvent(Event* event) { |
| 666 for (size_t i = 0; i < enqueued_events_.size(); ++i) { | 715 for (size_t i = 0; i < enqueued_events_.size(); ++i) { |
| 667 if (enqueued_events_[i].Get() == event) | 716 if (enqueued_events_[i].Get() == event) |
| 668 enqueued_events_.erase(i); | 717 enqueued_events_.erase(i); |
| 669 } | 718 } |
| 670 } | 719 } |
| 671 | 720 |
| 672 } // namespace blink | 721 } // namespace blink |
| OLD | NEW |