Chromium Code Reviews| 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 26 matching lines...) Expand all Loading... | |
| 37 #include "core/dom/ExceptionCode.h" | 37 #include "core/dom/ExceptionCode.h" |
| 38 #include "core/dom/ExecutionContext.h" | 38 #include "core/dom/ExecutionContext.h" |
| 39 #include "core/events/EventQueue.h" | 39 #include "core/events/EventQueue.h" |
| 40 #include "modules/IndexedDBNames.h" | 40 #include "modules/IndexedDBNames.h" |
| 41 #include "modules/indexeddb/IDBCursorWithValue.h" | 41 #include "modules/indexeddb/IDBCursorWithValue.h" |
| 42 #include "modules/indexeddb/IDBDatabase.h" | 42 #include "modules/indexeddb/IDBDatabase.h" |
| 43 #include "modules/indexeddb/IDBEventDispatcher.h" | 43 #include "modules/indexeddb/IDBEventDispatcher.h" |
| 44 #include "modules/indexeddb/IDBTracing.h" | 44 #include "modules/indexeddb/IDBTracing.h" |
| 45 #include "modules/indexeddb/IDBValue.h" | 45 #include "modules/indexeddb/IDBValue.h" |
| 46 #include "modules/indexeddb/WebIDBCallbacksImpl.h" | 46 #include "modules/indexeddb/WebIDBCallbacksImpl.h" |
| 47 #include "platform/Histogram.h" | |
| 47 #include "platform/SharedBuffer.h" | 48 #include "platform/SharedBuffer.h" |
| 48 #include "public/platform/WebBlobInfo.h" | 49 #include "public/platform/WebBlobInfo.h" |
| 49 | 50 |
| 50 using blink::WebIDBCursor; | 51 using blink::WebIDBCursor; |
| 51 | 52 |
| 52 namespace blink { | 53 namespace blink { |
| 53 | 54 |
| 55 IDBRequest::AsyncTraceState::AsyncTraceState() | |
|
pwnall
2017/05/25 23:04:25
You seem to use tracing_name_ for all the decision
dmurph
2017/05/31 19:26:25
Done.
| |
| 56 : tracing_name_(nullptr), id_(nullptr) {} | |
| 57 | |
| 58 IDBRequest::AsyncTraceState::AsyncTraceState(const char* tracing_name, void* id) | |
| 59 : tracing_name_(tracing_name), id_(id) { | |
| 60 if (tracing_name_) | |
| 61 TRACE_EVENT_ASYNC_BEGIN0("IndexedDB", tracing_name_, id); | |
| 62 } | |
| 63 | |
| 64 IDBRequest::AsyncTraceState::AsyncTraceState( | |
|
pwnall
2017/05/25 23:04:25
I think that the constructor and assignment operat
dmurph
2017/05/31 19:26:25
Done.
| |
| 65 IDBRequest::AsyncTraceState&& other) { | |
| 66 this->tracing_name_ = other.tracing_name_; | |
| 67 other.tracing_name_ = nullptr; | |
| 68 this->id_ = other.id_; | |
| 69 other.id_ = nullptr; | |
| 70 } | |
| 71 | |
| 72 IDBRequest::AsyncTraceState& IDBRequest::AsyncTraceState::operator=( | |
| 73 IDBRequest::AsyncTraceState&& rhs) { | |
| 74 this->tracing_name_ = rhs.tracing_name_; | |
| 75 rhs.tracing_name_ = nullptr; | |
| 76 this->id_ = rhs.id_; | |
| 77 rhs.id_ = nullptr; | |
| 78 return *this; | |
| 79 } | |
| 80 | |
| 81 void IDBRequest::AsyncTraceState::RecordAndReset() { | |
| 82 if (tracing_name_) | |
| 83 TRACE_EVENT_ASYNC_END0("IndexedDB", tracing_name_, id_); | |
| 84 tracing_name_ = nullptr; | |
| 85 id_ = nullptr; | |
| 86 } | |
| 87 | |
| 88 IDBRequest::AsyncTraceState::~AsyncTraceState() { | |
| 89 if (tracing_name_) | |
| 90 TRACE_EVENT_ASYNC_END0("IndexedDB", tracing_name_, id_); | |
| 91 } | |
| 92 | |
| 54 IDBRequest* IDBRequest::Create(ScriptState* script_state, | 93 IDBRequest* IDBRequest::Create(ScriptState* script_state, |
| 55 IDBAny* source, | 94 IDBAny* source, |
| 56 IDBTransaction* transaction) { | 95 IDBTransaction* transaction, |
| 57 IDBRequest* request = new IDBRequest(script_state, source, transaction); | 96 IDBRequest::AsyncTraceState metrics) { |
| 97 IDBRequest* request = | |
| 98 new IDBRequest(script_state, source, transaction, std::move(metrics)); | |
| 58 request->SuspendIfNeeded(); | 99 request->SuspendIfNeeded(); |
| 59 // Requests associated with IDBFactory (open/deleteDatabase/getDatabaseNames) | 100 // Requests associated with IDBFactory (open/deleteDatabase/getDatabaseNames) |
| 60 // are not associated with transactions. | 101 // are not associated with transactions. |
| 61 if (transaction) | 102 if (transaction) |
| 62 transaction->RegisterRequest(request); | 103 transaction->RegisterRequest(request); |
| 63 return request; | 104 return request; |
| 64 } | 105 } |
| 65 | 106 |
| 66 IDBRequest::IDBRequest(ScriptState* script_state, | 107 IDBRequest::IDBRequest(ScriptState* script_state, |
| 67 IDBAny* source, | 108 IDBAny* source, |
| 68 IDBTransaction* transaction) | 109 IDBTransaction* transaction, |
| 110 AsyncTraceState metrics) | |
| 69 : SuspendableObject(ExecutionContext::From(script_state)), | 111 : SuspendableObject(ExecutionContext::From(script_state)), |
| 70 transaction_(transaction), | 112 transaction_(transaction), |
| 71 isolate_(script_state->GetIsolate()), | 113 isolate_(script_state->GetIsolate()), |
| 72 source_(source) {} | 114 source_(source), |
| 115 metrics_(std::move(metrics)) {} | |
| 73 | 116 |
| 74 IDBRequest::~IDBRequest() { | 117 IDBRequest::~IDBRequest() { |
| 75 DCHECK(ready_state_ == DONE || ready_state_ == kEarlyDeath || | 118 DCHECK((ready_state_ == DONE && !metrics_.is_valid()) || |
| 76 !GetExecutionContext()); | 119 ready_state_ == kEarlyDeath || !GetExecutionContext()); |
| 77 } | 120 } |
| 78 | 121 |
| 79 DEFINE_TRACE(IDBRequest) { | 122 DEFINE_TRACE(IDBRequest) { |
| 80 visitor->Trace(transaction_); | 123 visitor->Trace(transaction_); |
| 81 visitor->Trace(source_); | 124 visitor->Trace(source_); |
| 82 visitor->Trace(result_); | 125 visitor->Trace(result_); |
| 83 visitor->Trace(error_); | 126 visitor->Trace(error_); |
| 84 visitor->Trace(enqueued_events_); | 127 visitor->Trace(enqueued_events_); |
| 85 visitor->Trace(pending_cursor_); | 128 visitor->Trace(pending_cursor_); |
| 86 visitor->Trace(cursor_key_); | 129 visitor->Trace(cursor_key_); |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 if (request_aborted_) | 278 if (request_aborted_) |
| 236 return false; | 279 return false; |
| 237 DCHECK_EQ(ready_state_, PENDING); | 280 DCHECK_EQ(ready_state_, PENDING); |
| 238 DCHECK(!error_ && !result_); | 281 DCHECK(!error_ && !result_); |
| 239 return true; | 282 return true; |
| 240 } | 283 } |
| 241 | 284 |
| 242 void IDBRequest::EnqueueResponse(DOMException* error) { | 285 void IDBRequest::EnqueueResponse(DOMException* error) { |
| 243 IDB_TRACE("IDBRequest::onError()"); | 286 IDB_TRACE("IDBRequest::onError()"); |
| 244 ClearPutOperationBlobs(); | 287 ClearPutOperationBlobs(); |
| 245 if (!ShouldEnqueueEvent()) | 288 if (!ShouldEnqueueEvent()) { |
| 289 metrics_.RecordAndReset(); | |
| 246 return; | 290 return; |
| 291 } | |
| 247 | 292 |
| 248 error_ = error; | 293 error_ = error; |
| 249 SetResult(IDBAny::CreateUndefined()); | 294 SetResult(IDBAny::CreateUndefined()); |
| 250 pending_cursor_.Clear(); | 295 pending_cursor_.Clear(); |
| 251 EnqueueEvent(Event::CreateCancelableBubble(EventTypeNames::error)); | 296 EnqueueEvent(Event::CreateCancelableBubble(EventTypeNames::error)); |
| 297 metrics_.RecordAndReset(); | |
| 252 } | 298 } |
| 253 | 299 |
| 254 void IDBRequest::EnqueueResponse(const Vector<String>& string_list) { | 300 void IDBRequest::EnqueueResponse(const Vector<String>& string_list) { |
| 255 IDB_TRACE("IDBRequest::onSuccess(StringList)"); | 301 IDB_TRACE("IDBRequest::onSuccess(StringList)"); |
| 256 if (!ShouldEnqueueEvent()) | 302 if (!ShouldEnqueueEvent()) { |
| 303 metrics_.RecordAndReset(); | |
| 257 return; | 304 return; |
| 305 } | |
| 258 | 306 |
| 259 DOMStringList* dom_string_list = DOMStringList::Create(); | 307 DOMStringList* dom_string_list = DOMStringList::Create(); |
| 260 for (size_t i = 0; i < string_list.size(); ++i) | 308 for (size_t i = 0; i < string_list.size(); ++i) |
| 261 dom_string_list->Append(string_list[i]); | 309 dom_string_list->Append(string_list[i]); |
| 262 EnqueueResultInternal(IDBAny::Create(dom_string_list)); | 310 EnqueueResultInternal(IDBAny::Create(dom_string_list)); |
| 311 metrics_.RecordAndReset(); | |
| 263 } | 312 } |
| 264 | 313 |
| 265 void IDBRequest::EnqueueResponse(std::unique_ptr<WebIDBCursor> backend, | 314 void IDBRequest::EnqueueResponse(std::unique_ptr<WebIDBCursor> backend, |
| 266 IDBKey* key, | 315 IDBKey* key, |
| 267 IDBKey* primary_key, | 316 IDBKey* primary_key, |
| 268 PassRefPtr<IDBValue> value) { | 317 PassRefPtr<IDBValue> value) { |
| 269 IDB_TRACE("IDBRequest::onSuccess(IDBCursor)"); | 318 IDB_TRACE("IDBRequest::onSuccess(IDBCursor)"); |
| 270 if (!ShouldEnqueueEvent()) | 319 if (!ShouldEnqueueEvent()) { |
| 320 metrics_.RecordAndReset(); | |
| 271 return; | 321 return; |
| 322 } | |
| 272 | 323 |
| 273 DCHECK(!pending_cursor_); | 324 DCHECK(!pending_cursor_); |
| 274 IDBCursor* cursor = nullptr; | 325 IDBCursor* cursor = nullptr; |
| 275 switch (cursor_type_) { | 326 switch (cursor_type_) { |
| 276 case IndexedDB::kCursorKeyOnly: | 327 case IndexedDB::kCursorKeyOnly: |
| 277 cursor = IDBCursor::Create(std::move(backend), cursor_direction_, this, | 328 cursor = IDBCursor::Create(std::move(backend), cursor_direction_, this, |
| 278 source_.Get(), transaction_.Get()); | 329 source_.Get(), transaction_.Get()); |
| 279 break; | 330 break; |
| 280 case IndexedDB::kCursorKeyAndValue: | 331 case IndexedDB::kCursorKeyAndValue: |
| 281 cursor = | 332 cursor = |
| 282 IDBCursorWithValue::Create(std::move(backend), cursor_direction_, | 333 IDBCursorWithValue::Create(std::move(backend), cursor_direction_, |
| 283 this, source_.Get(), transaction_.Get()); | 334 this, source_.Get(), transaction_.Get()); |
| 284 break; | 335 break; |
| 285 default: | 336 default: |
| 286 NOTREACHED(); | 337 NOTREACHED(); |
| 287 } | 338 } |
| 288 SetResultCursor(cursor, key, primary_key, std::move(value)); | 339 SetResultCursor(cursor, key, primary_key, std::move(value)); |
| 340 metrics_.RecordAndReset(); | |
| 289 } | 341 } |
| 290 | 342 |
| 291 void IDBRequest::EnqueueResponse(IDBKey* idb_key) { | 343 void IDBRequest::EnqueueResponse(IDBKey* idb_key) { |
| 292 IDB_TRACE("IDBRequest::onSuccess(IDBKey)"); | 344 IDB_TRACE("IDBRequest::onSuccess(IDBKey)"); |
| 293 ClearPutOperationBlobs(); | 345 ClearPutOperationBlobs(); |
| 294 if (!ShouldEnqueueEvent()) | 346 if (!ShouldEnqueueEvent()) { |
| 347 metrics_.RecordAndReset(); | |
| 295 return; | 348 return; |
| 349 } | |
| 296 | 350 |
| 297 if (idb_key && idb_key->IsValid()) | 351 if (idb_key && idb_key->IsValid()) |
| 298 EnqueueResultInternal(IDBAny::Create(idb_key)); | 352 EnqueueResultInternal(IDBAny::Create(idb_key)); |
| 299 else | 353 else |
| 300 EnqueueResultInternal(IDBAny::CreateUndefined()); | 354 EnqueueResultInternal(IDBAny::CreateUndefined()); |
| 355 metrics_.RecordAndReset(); | |
| 301 } | 356 } |
| 302 | 357 |
| 303 void IDBRequest::EnqueueResponse(const Vector<RefPtr<IDBValue>>& values) { | 358 void IDBRequest::EnqueueResponse(const Vector<RefPtr<IDBValue>>& values) { |
| 304 IDB_TRACE("IDBRequest::onSuccess([IDBValue])"); | 359 IDB_TRACE("IDBRequest::onSuccess([IDBValue])"); |
| 305 if (!ShouldEnqueueEvent()) | 360 if (!ShouldEnqueueEvent()) { |
| 361 metrics_.RecordAndReset(); | |
| 306 return; | 362 return; |
| 363 } | |
| 307 | 364 |
| 308 AckReceivedBlobs(values); | 365 AckReceivedBlobs(values); |
| 309 EnqueueResultInternal(IDBAny::Create(values)); | 366 EnqueueResultInternal(IDBAny::Create(values)); |
| 367 metrics_.RecordAndReset(); | |
| 310 } | 368 } |
| 311 | 369 |
| 312 #if DCHECK_IS_ON() | 370 #if DCHECK_IS_ON() |
| 313 static IDBObjectStore* EffectiveObjectStore(IDBAny* source) { | 371 static IDBObjectStore* EffectiveObjectStore(IDBAny* source) { |
| 314 if (source->GetType() == IDBAny::kIDBObjectStoreType) | 372 if (source->GetType() == IDBAny::kIDBObjectStoreType) |
| 315 return source->IdbObjectStore(); | 373 return source->IdbObjectStore(); |
| 316 if (source->GetType() == IDBAny::kIDBIndexType) | 374 if (source->GetType() == IDBAny::kIDBIndexType) |
| 317 return source->IdbIndex()->objectStore(); | 375 return source->IdbIndex()->objectStore(); |
| 318 | 376 |
| 319 NOTREACHED(); | 377 NOTREACHED(); |
| 320 return nullptr; | 378 return nullptr; |
| 321 } | 379 } |
| 322 #endif // DCHECK_IS_ON() | 380 #endif // DCHECK_IS_ON() |
| 323 | 381 |
| 324 void IDBRequest::EnqueueResponse(PassRefPtr<IDBValue> prp_value) { | 382 void IDBRequest::EnqueueResponse(PassRefPtr<IDBValue> prp_value) { |
| 325 IDB_TRACE("IDBRequest::onSuccess(IDBValue)"); | 383 IDB_TRACE("IDBRequest::onSuccess(IDBValue)"); |
| 326 if (!ShouldEnqueueEvent()) | 384 if (!ShouldEnqueueEvent()) { |
| 385 metrics_.RecordAndReset(); | |
| 327 return; | 386 return; |
| 387 } | |
| 328 | 388 |
| 329 RefPtr<IDBValue> value(std::move(prp_value)); | 389 RefPtr<IDBValue> value(std::move(prp_value)); |
| 330 AckReceivedBlobs(value.Get()); | 390 AckReceivedBlobs(value.Get()); |
| 331 | 391 |
| 332 if (pending_cursor_) { | 392 if (pending_cursor_) { |
| 333 // Value should be null, signifying the end of the cursor's range. | 393 // Value should be null, signifying the end of the cursor's range. |
| 334 DCHECK(value->IsNull()); | 394 DCHECK(value->IsNull()); |
| 335 DCHECK(!value->BlobInfo()->size()); | 395 DCHECK(!value->BlobInfo()->size()); |
| 336 pending_cursor_->Close(); | 396 pending_cursor_->Close(); |
| 337 pending_cursor_.Clear(); | 397 pending_cursor_.Clear(); |
| 338 } | 398 } |
| 339 | 399 |
| 340 #if DCHECK_IS_ON() | 400 #if DCHECK_IS_ON() |
| 341 DCHECK(!value->PrimaryKey() || | 401 DCHECK(!value->PrimaryKey() || |
| 342 value->KeyPath() == EffectiveObjectStore(source_)->IdbKeyPath()); | 402 value->KeyPath() == EffectiveObjectStore(source_)->IdbKeyPath()); |
| 343 #endif | 403 #endif |
| 344 | 404 |
| 345 EnqueueResultInternal(IDBAny::Create(value.Release())); | 405 EnqueueResultInternal(IDBAny::Create(value.Release())); |
| 406 metrics_.RecordAndReset(); | |
| 346 } | 407 } |
| 347 | 408 |
| 348 void IDBRequest::EnqueueResponse(int64_t value) { | 409 void IDBRequest::EnqueueResponse(int64_t value) { |
| 349 IDB_TRACE("IDBRequest::onSuccess(int64_t)"); | 410 IDB_TRACE("IDBRequest::onSuccess(int64_t)"); |
| 350 if (!ShouldEnqueueEvent()) | 411 if (!ShouldEnqueueEvent()) { |
| 412 metrics_.RecordAndReset(); | |
| 351 return; | 413 return; |
| 414 } | |
| 352 EnqueueResultInternal(IDBAny::Create(value)); | 415 EnqueueResultInternal(IDBAny::Create(value)); |
| 416 metrics_.RecordAndReset(); | |
| 353 } | 417 } |
| 354 | 418 |
| 355 void IDBRequest::EnqueueResponse() { | 419 void IDBRequest::EnqueueResponse() { |
| 356 IDB_TRACE("IDBRequest::onSuccess()"); | 420 IDB_TRACE("IDBRequest::onSuccess()"); |
| 357 if (!ShouldEnqueueEvent()) | 421 if (!ShouldEnqueueEvent()) { |
| 422 metrics_.RecordAndReset(); | |
| 358 return; | 423 return; |
| 424 } | |
| 359 EnqueueResultInternal(IDBAny::CreateUndefined()); | 425 EnqueueResultInternal(IDBAny::CreateUndefined()); |
| 426 metrics_.RecordAndReset(); | |
| 360 } | 427 } |
| 361 | 428 |
| 362 void IDBRequest::EnqueueResultInternal(IDBAny* result) { | 429 void IDBRequest::EnqueueResultInternal(IDBAny* result) { |
| 363 DCHECK(GetExecutionContext()); | 430 DCHECK(GetExecutionContext()); |
| 364 DCHECK(!pending_cursor_); | 431 DCHECK(!pending_cursor_); |
| 365 DCHECK(transit_blob_handles_.IsEmpty()); | 432 DCHECK(transit_blob_handles_.IsEmpty()); |
| 366 SetResult(result); | 433 SetResult(result); |
| 367 EnqueueEvent(Event::Create(EventTypeNames::success)); | 434 EnqueueEvent(Event::Create(EventTypeNames::success)); |
| 368 } | 435 } |
| 369 | 436 |
| 370 void IDBRequest::SetResult(IDBAny* result) { | 437 void IDBRequest::SetResult(IDBAny* result) { |
| 371 result_ = result; | 438 result_ = result; |
| 372 result_dirty_ = true; | 439 result_dirty_ = true; |
| 373 } | 440 } |
| 374 | 441 |
| 375 void IDBRequest::EnqueueResponse(IDBKey* key, | 442 void IDBRequest::EnqueueResponse(IDBKey* key, |
| 376 IDBKey* primary_key, | 443 IDBKey* primary_key, |
| 377 PassRefPtr<IDBValue> value) { | 444 PassRefPtr<IDBValue> value) { |
| 378 IDB_TRACE("IDBRequest::onSuccess(key, primaryKey, value)"); | 445 IDB_TRACE("IDBRequest::onSuccess(key, primaryKey, value)"); |
| 379 if (!ShouldEnqueueEvent()) | 446 if (!ShouldEnqueueEvent()) { |
| 447 metrics_.RecordAndReset(); | |
| 380 return; | 448 return; |
| 449 } | |
| 381 | 450 |
| 382 DCHECK(pending_cursor_); | 451 DCHECK(pending_cursor_); |
| 383 SetResultCursor(pending_cursor_.Release(), key, primary_key, | 452 SetResultCursor(pending_cursor_.Release(), key, primary_key, |
| 384 std::move(value)); | 453 std::move(value)); |
| 454 metrics_.RecordAndReset(); | |
| 385 } | 455 } |
| 386 | 456 |
| 387 bool IDBRequest::HasPendingActivity() const { | 457 bool IDBRequest::HasPendingActivity() const { |
| 388 // FIXME: In an ideal world, we should return true as long as anyone has a or | 458 // FIXME: In an ideal world, we should return true as long as anyone has a or |
| 389 // can get a handle to us and we have event listeners. This is order to | 459 // can get a handle to us and we have event listeners. This is order to |
| 390 // handle user generated events properly. | 460 // handle user generated events properly. |
| 391 return has_pending_activity_ && GetExecutionContext(); | 461 return has_pending_activity_ && GetExecutionContext(); |
| 392 } | 462 } |
| 393 | 463 |
| 394 void IDBRequest::ContextDestroyed(ExecutionContext*) { | 464 void IDBRequest::ContextDestroyed(ExecutionContext*) { |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 556 } | 626 } |
| 557 | 627 |
| 558 void IDBRequest::DequeueEvent(Event* event) { | 628 void IDBRequest::DequeueEvent(Event* event) { |
| 559 for (size_t i = 0; i < enqueued_events_.size(); ++i) { | 629 for (size_t i = 0; i < enqueued_events_.size(); ++i) { |
| 560 if (enqueued_events_[i].Get() == event) | 630 if (enqueued_events_[i].Get() == event) |
| 561 enqueued_events_.erase(i); | 631 enqueued_events_.erase(i); |
| 562 } | 632 } |
| 563 } | 633 } |
| 564 | 634 |
| 565 } // namespace blink | 635 } // namespace blink |
| OLD | NEW |