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 |
| 54 IDBRequest* IDBRequest::Create(ScriptState* script_state, | 55 IDBRequest::ScopedMetricsTracker::ScopedMetricsTracker(const char* uma_name, |
| 55 IDBAny* source, | 56 const char* tracing_name, |
| 56 IDBTransaction* transaction) { | 57 void* id) |
| 57 IDBRequest* request = new IDBRequest(script_state, source, transaction); | 58 : uma_name_(uma_name), |
| 59 tracing_name_(tracing_name), | |
| 60 id_(id), | |
| 61 start_(uma_name_ ? WTF::TimeTicks::Now() : WTF::TimeTicks()) { | |
| 62 if (tracing_name_) | |
| 63 TRACE_EVENT_ASYNC_BEGIN0("IndexedDB", tracing_name_, id); | |
| 64 } | |
| 65 | |
| 66 IDBRequest::ScopedMetricsTracker::~ScopedMetricsTracker() { | |
| 67 if (tracing_name_) | |
| 68 TRACE_EVENT_ASYNC_END0("IndexedDB", tracing_name_, id_); | |
| 69 } | |
| 70 | |
| 71 void IDBRequest::ScopedMetricsTracker::RecordUMAMetrics() const { | |
| 72 if (uma_name_) | |
| 73 UMA_HISTOGRAM_MEDIUM_TIMES(uma_name_, WTF::TimeTicks::Now() - start_); | |
|
pwnall
2017/05/18 22:14:32
Does this not record UMA data?
dmurph
2017/05/18 23:51:15
not anymore :P
| |
| 74 } | |
| 75 | |
| 76 IDBRequest* IDBRequest::Create( | |
| 77 ScriptState* script_state, | |
| 78 IDBAny* source, | |
| 79 IDBTransaction* transaction, | |
| 80 std::unique_ptr<IDBRequest::ScopedMetricsTracker> metrics) { | |
| 81 IDBRequest* request = | |
| 82 new IDBRequest(script_state, source, transaction, std::move(metrics)); | |
| 58 request->SuspendIfNeeded(); | 83 request->SuspendIfNeeded(); |
| 59 // Requests associated with IDBFactory (open/deleteDatabase/getDatabaseNames) | 84 // Requests associated with IDBFactory (open/deleteDatabase/getDatabaseNames) |
| 60 // are not associated with transactions. | 85 // are not associated with transactions. |
| 61 if (transaction) | 86 if (transaction) |
| 62 transaction->RegisterRequest(request); | 87 transaction->RegisterRequest(request); |
| 63 return request; | 88 return request; |
| 64 } | 89 } |
| 65 | 90 |
| 66 IDBRequest::IDBRequest(ScriptState* script_state, | 91 IDBRequest::IDBRequest(ScriptState* script_state, |
| 67 IDBAny* source, | 92 IDBAny* source, |
| 68 IDBTransaction* transaction) | 93 IDBTransaction* transaction, |
| 94 std::unique_ptr<ScopedMetricsTracker> metrics) | |
| 69 : SuspendableObject(ExecutionContext::From(script_state)), | 95 : SuspendableObject(ExecutionContext::From(script_state)), |
| 70 transaction_(transaction), | 96 transaction_(transaction), |
| 71 isolate_(script_state->GetIsolate()), | 97 isolate_(script_state->GetIsolate()), |
| 72 source_(source) {} | 98 source_(source), |
| 99 metrics_(std::move(metrics)) {} | |
| 73 | 100 |
| 74 IDBRequest::~IDBRequest() { | 101 IDBRequest::~IDBRequest() { |
| 75 DCHECK(ready_state_ == DONE || ready_state_ == kEarlyDeath || | 102 DCHECK(ready_state_ == DONE || ready_state_ == kEarlyDeath || |
| 76 !GetExecutionContext()); | 103 !GetExecutionContext()); |
| 77 } | 104 } |
| 78 | 105 |
| 79 DEFINE_TRACE(IDBRequest) { | 106 DEFINE_TRACE(IDBRequest) { |
| 80 visitor->Trace(transaction_); | 107 visitor->Trace(transaction_); |
| 81 visitor->Trace(source_); | 108 visitor->Trace(source_); |
| 82 visitor->Trace(result_); | 109 visitor->Trace(result_); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 242 void IDBRequest::EnqueueResponse(DOMException* error) { | 269 void IDBRequest::EnqueueResponse(DOMException* error) { |
| 243 IDB_TRACE("IDBRequest::onError()"); | 270 IDB_TRACE("IDBRequest::onError()"); |
| 244 ClearPutOperationBlobs(); | 271 ClearPutOperationBlobs(); |
| 245 if (!ShouldEnqueueEvent()) | 272 if (!ShouldEnqueueEvent()) |
| 246 return; | 273 return; |
| 247 | 274 |
| 248 error_ = error; | 275 error_ = error; |
| 249 SetResult(IDBAny::CreateUndefined()); | 276 SetResult(IDBAny::CreateUndefined()); |
| 250 pending_cursor_.Clear(); | 277 pending_cursor_.Clear(); |
| 251 EnqueueEvent(Event::CreateCancelableBubble(EventTypeNames::error)); | 278 EnqueueEvent(Event::CreateCancelableBubble(EventTypeNames::error)); |
| 279 MaybeRecordMetrics(); | |
| 252 } | 280 } |
| 253 | 281 |
| 254 void IDBRequest::EnqueueResponse(const Vector<String>& string_list) { | 282 void IDBRequest::EnqueueResponse(const Vector<String>& string_list) { |
| 255 IDB_TRACE("IDBRequest::onSuccess(StringList)"); | 283 IDB_TRACE("IDBRequest::onSuccess(StringList)"); |
| 256 if (!ShouldEnqueueEvent()) | 284 if (!ShouldEnqueueEvent()) |
| 257 return; | 285 return; |
| 258 | 286 |
| 259 DOMStringList* dom_string_list = DOMStringList::Create(); | 287 DOMStringList* dom_string_list = DOMStringList::Create(); |
| 260 for (size_t i = 0; i < string_list.size(); ++i) | 288 for (size_t i = 0; i < string_list.size(); ++i) |
| 261 dom_string_list->Append(string_list[i]); | 289 dom_string_list->Append(string_list[i]); |
| 262 EnqueueResultInternal(IDBAny::Create(dom_string_list)); | 290 EnqueueResultInternal(IDBAny::Create(dom_string_list)); |
| 291 MaybeRecordMetrics(); | |
| 263 } | 292 } |
| 264 | 293 |
| 265 void IDBRequest::EnqueueResponse(std::unique_ptr<WebIDBCursor> backend, | 294 void IDBRequest::EnqueueResponse(std::unique_ptr<WebIDBCursor> backend, |
| 266 IDBKey* key, | 295 IDBKey* key, |
| 267 IDBKey* primary_key, | 296 IDBKey* primary_key, |
| 268 PassRefPtr<IDBValue> value) { | 297 PassRefPtr<IDBValue> value) { |
| 269 IDB_TRACE("IDBRequest::onSuccess(IDBCursor)"); | 298 IDB_TRACE("IDBRequest::onSuccess(IDBCursor)"); |
| 270 if (!ShouldEnqueueEvent()) | 299 if (!ShouldEnqueueEvent()) |
| 271 return; | 300 return; |
| 272 | 301 |
| 273 DCHECK(!pending_cursor_); | 302 DCHECK(!pending_cursor_); |
| 274 IDBCursor* cursor = nullptr; | 303 IDBCursor* cursor = nullptr; |
| 275 switch (cursor_type_) { | 304 switch (cursor_type_) { |
| 276 case IndexedDB::kCursorKeyOnly: | 305 case IndexedDB::kCursorKeyOnly: |
| 277 cursor = IDBCursor::Create(std::move(backend), cursor_direction_, this, | 306 cursor = IDBCursor::Create(std::move(backend), cursor_direction_, this, |
| 278 source_.Get(), transaction_.Get()); | 307 source_.Get(), transaction_.Get()); |
| 279 break; | 308 break; |
| 280 case IndexedDB::kCursorKeyAndValue: | 309 case IndexedDB::kCursorKeyAndValue: |
| 281 cursor = | 310 cursor = |
| 282 IDBCursorWithValue::Create(std::move(backend), cursor_direction_, | 311 IDBCursorWithValue::Create(std::move(backend), cursor_direction_, |
| 283 this, source_.Get(), transaction_.Get()); | 312 this, source_.Get(), transaction_.Get()); |
| 284 break; | 313 break; |
| 285 default: | 314 default: |
| 286 NOTREACHED(); | 315 NOTREACHED(); |
| 287 } | 316 } |
| 288 SetResultCursor(cursor, key, primary_key, std::move(value)); | 317 SetResultCursor(cursor, key, primary_key, std::move(value)); |
| 318 MaybeRecordMetrics(); | |
| 289 } | 319 } |
| 290 | 320 |
| 291 void IDBRequest::EnqueueResponse(IDBKey* idb_key) { | 321 void IDBRequest::EnqueueResponse(IDBKey* idb_key) { |
| 292 IDB_TRACE("IDBRequest::onSuccess(IDBKey)"); | 322 IDB_TRACE("IDBRequest::onSuccess(IDBKey)"); |
| 293 ClearPutOperationBlobs(); | 323 ClearPutOperationBlobs(); |
| 294 if (!ShouldEnqueueEvent()) | 324 if (!ShouldEnqueueEvent()) |
| 295 return; | 325 return; |
| 296 | 326 |
| 297 if (idb_key && idb_key->IsValid()) | 327 if (idb_key && idb_key->IsValid()) |
| 298 EnqueueResultInternal(IDBAny::Create(idb_key)); | 328 EnqueueResultInternal(IDBAny::Create(idb_key)); |
| 299 else | 329 else |
| 300 EnqueueResultInternal(IDBAny::CreateUndefined()); | 330 EnqueueResultInternal(IDBAny::CreateUndefined()); |
| 331 MaybeRecordMetrics(); | |
| 301 } | 332 } |
| 302 | 333 |
| 303 void IDBRequest::EnqueueResponse(const Vector<RefPtr<IDBValue>>& values) { | 334 void IDBRequest::EnqueueResponse(const Vector<RefPtr<IDBValue>>& values) { |
| 304 IDB_TRACE("IDBRequest::onSuccess([IDBValue])"); | 335 IDB_TRACE("IDBRequest::onSuccess([IDBValue])"); |
| 305 if (!ShouldEnqueueEvent()) | 336 if (!ShouldEnqueueEvent()) |
| 306 return; | 337 return; |
| 307 | 338 |
| 308 AckReceivedBlobs(values); | 339 AckReceivedBlobs(values); |
| 309 EnqueueResultInternal(IDBAny::Create(values)); | 340 EnqueueResultInternal(IDBAny::Create(values)); |
| 341 MaybeRecordMetrics(); | |
| 310 } | 342 } |
| 311 | 343 |
| 312 #if DCHECK_IS_ON() | 344 #if DCHECK_IS_ON() |
| 313 static IDBObjectStore* EffectiveObjectStore(IDBAny* source) { | 345 static IDBObjectStore* EffectiveObjectStore(IDBAny* source) { |
| 314 if (source->GetType() == IDBAny::kIDBObjectStoreType) | 346 if (source->GetType() == IDBAny::kIDBObjectStoreType) |
| 315 return source->IdbObjectStore(); | 347 return source->IdbObjectStore(); |
| 316 if (source->GetType() == IDBAny::kIDBIndexType) | 348 if (source->GetType() == IDBAny::kIDBIndexType) |
| 317 return source->IdbIndex()->objectStore(); | 349 return source->IdbIndex()->objectStore(); |
| 318 | 350 |
| 319 NOTREACHED(); | 351 NOTREACHED(); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 336 pending_cursor_->Close(); | 368 pending_cursor_->Close(); |
| 337 pending_cursor_.Clear(); | 369 pending_cursor_.Clear(); |
| 338 } | 370 } |
| 339 | 371 |
| 340 #if DCHECK_IS_ON() | 372 #if DCHECK_IS_ON() |
| 341 DCHECK(!value->PrimaryKey() || | 373 DCHECK(!value->PrimaryKey() || |
| 342 value->KeyPath() == EffectiveObjectStore(source_)->IdbKeyPath()); | 374 value->KeyPath() == EffectiveObjectStore(source_)->IdbKeyPath()); |
| 343 #endif | 375 #endif |
| 344 | 376 |
| 345 EnqueueResultInternal(IDBAny::Create(value.Release())); | 377 EnqueueResultInternal(IDBAny::Create(value.Release())); |
| 378 MaybeRecordMetrics(); | |
| 346 } | 379 } |
| 347 | 380 |
| 348 void IDBRequest::EnqueueResponse(int64_t value) { | 381 void IDBRequest::EnqueueResponse(int64_t value) { |
| 349 IDB_TRACE("IDBRequest::onSuccess(int64_t)"); | 382 IDB_TRACE("IDBRequest::onSuccess(int64_t)"); |
| 350 if (!ShouldEnqueueEvent()) | 383 if (!ShouldEnqueueEvent()) |
| 351 return; | 384 return; |
| 352 EnqueueResultInternal(IDBAny::Create(value)); | 385 EnqueueResultInternal(IDBAny::Create(value)); |
| 386 MaybeRecordMetrics(); | |
| 353 } | 387 } |
| 354 | 388 |
| 355 void IDBRequest::EnqueueResponse() { | 389 void IDBRequest::EnqueueResponse() { |
| 356 IDB_TRACE("IDBRequest::onSuccess()"); | 390 IDB_TRACE("IDBRequest::onSuccess()"); |
| 357 if (!ShouldEnqueueEvent()) | 391 if (!ShouldEnqueueEvent()) |
| 358 return; | 392 return; |
| 359 EnqueueResultInternal(IDBAny::CreateUndefined()); | 393 EnqueueResultInternal(IDBAny::CreateUndefined()); |
| 394 MaybeRecordMetrics(); | |
| 360 } | 395 } |
| 361 | 396 |
| 362 void IDBRequest::EnqueueResultInternal(IDBAny* result) { | 397 void IDBRequest::EnqueueResultInternal(IDBAny* result) { |
| 363 DCHECK(GetExecutionContext()); | 398 DCHECK(GetExecutionContext()); |
| 364 DCHECK(!pending_cursor_); | 399 DCHECK(!pending_cursor_); |
| 365 DCHECK(transit_blob_handles_.IsEmpty()); | 400 DCHECK(transit_blob_handles_.IsEmpty()); |
| 366 SetResult(result); | 401 SetResult(result); |
| 367 EnqueueEvent(Event::Create(EventTypeNames::success)); | 402 EnqueueEvent(Event::Create(EventTypeNames::success)); |
| 368 } | 403 } |
| 369 | 404 |
| 370 void IDBRequest::SetResult(IDBAny* result) { | 405 void IDBRequest::SetResult(IDBAny* result) { |
| 371 result_ = result; | 406 result_ = result; |
| 372 result_dirty_ = true; | 407 result_dirty_ = true; |
| 373 } | 408 } |
| 374 | 409 |
| 375 void IDBRequest::EnqueueResponse(IDBKey* key, | 410 void IDBRequest::EnqueueResponse(IDBKey* key, |
| 376 IDBKey* primary_key, | 411 IDBKey* primary_key, |
| 377 PassRefPtr<IDBValue> value) { | 412 PassRefPtr<IDBValue> value) { |
| 378 IDB_TRACE("IDBRequest::onSuccess(key, primaryKey, value)"); | 413 IDB_TRACE("IDBRequest::onSuccess(key, primaryKey, value)"); |
| 379 if (!ShouldEnqueueEvent()) | 414 if (!ShouldEnqueueEvent()) |
| 380 return; | 415 return; |
| 381 | 416 |
| 382 DCHECK(pending_cursor_); | 417 DCHECK(pending_cursor_); |
| 383 SetResultCursor(pending_cursor_.Release(), key, primary_key, | 418 SetResultCursor(pending_cursor_.Release(), key, primary_key, |
| 384 std::move(value)); | 419 std::move(value)); |
| 420 MaybeRecordMetrics(); | |
| 385 } | 421 } |
| 386 | 422 |
| 387 bool IDBRequest::HasPendingActivity() const { | 423 bool IDBRequest::HasPendingActivity() const { |
| 388 // FIXME: In an ideal world, we should return true as long as anyone has a or | 424 // 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 | 425 // can get a handle to us and we have event listeners. This is order to |
| 390 // handle user generated events properly. | 426 // handle user generated events properly. |
| 391 return has_pending_activity_ && GetExecutionContext(); | 427 return has_pending_activity_ && GetExecutionContext(); |
| 392 } | 428 } |
| 393 | 429 |
| 394 void IDBRequest::ContextDestroyed(ExecutionContext*) { | 430 void IDBRequest::ContextDestroyed(ExecutionContext*) { |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 556 } | 592 } |
| 557 | 593 |
| 558 void IDBRequest::DequeueEvent(Event* event) { | 594 void IDBRequest::DequeueEvent(Event* event) { |
| 559 for (size_t i = 0; i < enqueued_events_.size(); ++i) { | 595 for (size_t i = 0; i < enqueued_events_.size(); ++i) { |
| 560 if (enqueued_events_[i].Get() == event) | 596 if (enqueued_events_[i].Get() == event) |
| 561 enqueued_events_.erase(i); | 597 enqueued_events_.erase(i); |
| 562 } | 598 } |
| 563 } | 599 } |
| 564 | 600 |
| 565 } // namespace blink | 601 } // namespace blink |
| OLD | NEW |