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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 const char IDBDatabase::objectStoreDeletedErrorMessage[] = "The object store has
been deleted."; | 61 const char IDBDatabase::objectStoreDeletedErrorMessage[] = "The object store has
been deleted."; |
62 const char IDBDatabase::requestNotFinishedErrorMessage[] = "The request has not
finished."; | 62 const char IDBDatabase::requestNotFinishedErrorMessage[] = "The request has not
finished."; |
63 const char IDBDatabase::sourceDeletedErrorMessage[] = "The cursor's source or ef
fective object store has been deleted."; | 63 const char IDBDatabase::sourceDeletedErrorMessage[] = "The cursor's source or ef
fective object store has been deleted."; |
64 const char IDBDatabase::transactionInactiveErrorMessage[] = "The transaction is
not active."; | 64 const char IDBDatabase::transactionInactiveErrorMessage[] = "The transaction is
not active."; |
65 const char IDBDatabase::transactionFinishedErrorMessage[] = "The transaction has
finished."; | 65 const char IDBDatabase::transactionFinishedErrorMessage[] = "The transaction has
finished."; |
66 const char IDBDatabase::transactionReadOnlyErrorMessage[] = "The transaction is
read-only."; | 66 const char IDBDatabase::transactionReadOnlyErrorMessage[] = "The transaction is
read-only."; |
67 const char IDBDatabase::databaseClosedErrorMessage[] = "The database connection
is closed."; | 67 const char IDBDatabase::databaseClosedErrorMessage[] = "The database connection
is closed."; |
68 | 68 |
69 IDBDatabase* IDBDatabase::create(ExecutionContext* context, PassOwnPtr<WebIDBDat
abase> database, IDBDatabaseCallbacks* callbacks) | 69 IDBDatabase* IDBDatabase::create(ExecutionContext* context, PassOwnPtr<WebIDBDat
abase> database, IDBDatabaseCallbacks* callbacks) |
70 { | 70 { |
71 IDBDatabase* idbDatabase = new IDBDatabase(context, database, callbacks); | 71 return new IDBDatabase(context, database, callbacks); |
72 idbDatabase->suspendIfNeeded(); | |
73 return idbDatabase; | |
74 } | 72 } |
75 | 73 |
76 IDBDatabase::IDBDatabase(ExecutionContext* context, PassOwnPtr<WebIDBDatabase> b
ackend, IDBDatabaseCallbacks* callbacks) | 74 IDBDatabase::IDBDatabase(ExecutionContext* context, PassOwnPtr<WebIDBDatabase> b
ackend, IDBDatabaseCallbacks* callbacks) |
77 : ActiveDOMObject(context) | 75 : ContextLifecycleObserver(context) |
78 , m_backend(backend) | 76 , m_backend(backend) |
79 , m_databaseCallbacks(callbacks) | 77 , m_databaseCallbacks(callbacks) |
80 { | 78 { |
81 m_databaseCallbacks->connect(this); | 79 m_databaseCallbacks->connect(this); |
82 } | 80 } |
83 | 81 |
84 IDBDatabase::~IDBDatabase() | 82 IDBDatabase::~IDBDatabase() |
85 { | 83 { |
86 if (!m_closePending && m_backend) | 84 if (!m_closePending && m_backend) |
87 m_backend->close(); | 85 m_backend->close(); |
88 } | 86 } |
89 | 87 |
90 DEFINE_TRACE(IDBDatabase) | 88 DEFINE_TRACE(IDBDatabase) |
91 { | 89 { |
92 visitor->trace(m_versionChangeTransaction); | 90 visitor->trace(m_versionChangeTransaction); |
93 visitor->trace(m_transactions); | 91 visitor->trace(m_transactions); |
94 visitor->trace(m_enqueuedEvents); | 92 visitor->trace(m_enqueuedEvents); |
95 visitor->trace(m_databaseCallbacks); | 93 visitor->trace(m_databaseCallbacks); |
96 RefCountedGarbageCollectedEventTargetWithInlineData<IDBDatabase>::trace(visi
tor); | 94 RefCountedGarbageCollectedEventTargetWithInlineData<IDBDatabase>::trace(visi
tor); |
97 ActiveDOMObject::trace(visitor); | 95 ContextLifecycleObserver::trace(visitor); |
98 } | 96 } |
99 | 97 |
100 int64_t IDBDatabase::nextTransactionId() | 98 int64_t IDBDatabase::nextTransactionId() |
101 { | 99 { |
102 // Only keep a 32-bit counter to allow ports to use the other 32 | 100 // Only keep a 32-bit counter to allow ports to use the other 32 |
103 // bits of the id. | 101 // bits of the id. |
104 static int currentTransactionId = 0; | 102 static int currentTransactionId = 0; |
105 return atomicIncrement(¤tTransactionId); | 103 return atomicIncrement(¤tTransactionId); |
106 } | 104 } |
107 | 105 |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 void IDBDatabase::closeConnection() | 336 void IDBDatabase::closeConnection() |
339 { | 337 { |
340 ASSERT(m_closePending); | 338 ASSERT(m_closePending); |
341 ASSERT(m_transactions.isEmpty()); | 339 ASSERT(m_transactions.isEmpty()); |
342 | 340 |
343 if (m_backend) { | 341 if (m_backend) { |
344 m_backend->close(); | 342 m_backend->close(); |
345 m_backend.clear(); | 343 m_backend.clear(); |
346 } | 344 } |
347 | 345 |
348 if (m_contextStopped || !executionContext()) | 346 if (!executionContext()) |
349 return; | 347 return; |
350 | 348 |
351 EventQueue* eventQueue = executionContext()->eventQueue(); | 349 EventQueue* eventQueue = executionContext()->eventQueue(); |
352 // Remove any pending versionchange events scheduled to fire on this | 350 // Remove any pending versionchange events scheduled to fire on this |
353 // connection. They would have been scheduled by the backend when another | 351 // connection. They would have been scheduled by the backend when another |
354 // connection attempted an upgrade, but the frontend connection is being | 352 // connection attempted an upgrade, but the frontend connection is being |
355 // closed before they could fire. | 353 // closed before they could fire. |
356 for (size_t i = 0; i < m_enqueuedEvents.size(); ++i) { | 354 for (size_t i = 0; i < m_enqueuedEvents.size(); ++i) { |
357 bool removed = eventQueue->cancelEvent(m_enqueuedEvents[i].get()); | 355 bool removed = eventQueue->cancelEvent(m_enqueuedEvents[i].get()); |
358 ASSERT_UNUSED(removed, removed); | 356 ASSERT_UNUSED(removed, removed); |
359 } | 357 } |
360 } | 358 } |
361 | 359 |
362 void IDBDatabase::onVersionChange(int64_t oldVersion, int64_t newVersion) | 360 void IDBDatabase::onVersionChange(int64_t oldVersion, int64_t newVersion) |
363 { | 361 { |
364 IDB_TRACE("IDBDatabase::onVersionChange"); | 362 IDB_TRACE("IDBDatabase::onVersionChange"); |
365 if (m_contextStopped || !executionContext()) | 363 if (!executionContext()) |
366 return; | 364 return; |
367 | 365 |
368 if (m_closePending) { | 366 if (m_closePending) { |
369 // If we're pending, that means there's a busy transaction. We won't | 367 // If we're pending, that means there's a busy transaction. We won't |
370 // fire 'versionchange' but since we're not closing immediately the | 368 // fire 'versionchange' but since we're not closing immediately the |
371 // back-end should still send out 'blocked'. | 369 // back-end should still send out 'blocked'. |
372 m_backend->versionChangeIgnored(); | 370 m_backend->versionChangeIgnored(); |
373 return; | 371 return; |
374 } | 372 } |
375 | 373 |
376 Nullable<unsigned long long> newVersionNullable = (newVersion == IDBDatabase
Metadata::NoVersion) ? Nullable<unsigned long long>() : Nullable<unsigned long l
ong>(newVersion); | 374 Nullable<unsigned long long> newVersionNullable = (newVersion == IDBDatabase
Metadata::NoVersion) ? Nullable<unsigned long long>() : Nullable<unsigned long l
ong>(newVersion); |
377 enqueueEvent(IDBVersionChangeEvent::create(EventTypeNames::versionchange, ol
dVersion, newVersionNullable)); | 375 enqueueEvent(IDBVersionChangeEvent::create(EventTypeNames::versionchange, ol
dVersion, newVersionNullable)); |
378 } | 376 } |
379 | 377 |
380 void IDBDatabase::enqueueEvent(PassRefPtrWillBeRawPtr<Event> event) | 378 void IDBDatabase::enqueueEvent(PassRefPtrWillBeRawPtr<Event> event) |
381 { | 379 { |
382 ASSERT(!m_contextStopped); | |
383 ASSERT(executionContext()); | 380 ASSERT(executionContext()); |
384 EventQueue* eventQueue = executionContext()->eventQueue(); | 381 EventQueue* eventQueue = executionContext()->eventQueue(); |
385 event->setTarget(this); | 382 event->setTarget(this); |
386 eventQueue->enqueueEvent(event.get()); | 383 eventQueue->enqueueEvent(event.get()); |
387 m_enqueuedEvents.append(event); | 384 m_enqueuedEvents.append(event); |
388 } | 385 } |
389 | 386 |
390 DispatchEventResult IDBDatabase::dispatchEventInternal(PassRefPtrWillBeRawPtr<Ev
ent> event) | 387 DispatchEventResult IDBDatabase::dispatchEventInternal(PassRefPtrWillBeRawPtr<Ev
ent> event) |
391 { | 388 { |
392 IDB_TRACE("IDBDatabase::dispatchEvent"); | 389 IDB_TRACE("IDBDatabase::dispatchEvent"); |
393 if (m_contextStopped || !executionContext()) | 390 if (!executionContext()) |
394 return DispatchEventResult::CanceledBeforeDispatch; | 391 return DispatchEventResult::CanceledBeforeDispatch; |
395 ASSERT(event->type() == EventTypeNames::versionchange || event->type() == Ev
entTypeNames::close); | 392 ASSERT(event->type() == EventTypeNames::versionchange || event->type() == Ev
entTypeNames::close); |
396 for (size_t i = 0; i < m_enqueuedEvents.size(); ++i) { | 393 for (size_t i = 0; i < m_enqueuedEvents.size(); ++i) { |
397 if (m_enqueuedEvents[i].get() == event.get()) | 394 if (m_enqueuedEvents[i].get() == event.get()) |
398 m_enqueuedEvents.remove(i); | 395 m_enqueuedEvents.remove(i); |
399 } | 396 } |
400 | 397 |
401 DispatchEventResult dispatchResult = EventTarget::dispatchEventInternal(even
t.get()); | 398 DispatchEventResult dispatchResult = EventTarget::dispatchEventInternal(even
t.get()); |
402 if (event->type() == EventTypeNames::versionchange && !m_closePending && m_b
ackend) | 399 if (event->type() == EventTypeNames::versionchange && !m_closePending && m_b
ackend) |
403 m_backend->versionChangeIgnored(); | 400 m_backend->versionChangeIgnored(); |
404 return dispatchResult; | 401 return dispatchResult; |
405 } | 402 } |
406 | 403 |
407 int64_t IDBDatabase::findObjectStoreId(const String& name) const | 404 int64_t IDBDatabase::findObjectStoreId(const String& name) const |
408 { | 405 { |
409 for (const auto& it : m_metadata.objectStores) { | 406 for (const auto& it : m_metadata.objectStores) { |
410 if (it.value.name == name) { | 407 if (it.value.name == name) { |
411 ASSERT(it.key != IDBObjectStoreMetadata::InvalidId); | 408 ASSERT(it.key != IDBObjectStoreMetadata::InvalidId); |
412 return it.key; | 409 return it.key; |
413 } | 410 } |
414 } | 411 } |
415 return IDBObjectStoreMetadata::InvalidId; | 412 return IDBObjectStoreMetadata::InvalidId; |
416 } | 413 } |
417 | 414 |
418 bool IDBDatabase::hasPendingActivity() const | 415 bool IDBDatabase::hasPendingActivity() const |
419 { | 416 { |
420 // The script wrapper must not be collected before the object is closed or | 417 // The script wrapper must not be collected before the object is closed or |
421 // we can't fire a "versionchange" event to let script manually close the co
nnection. | 418 // we can't fire a "versionchange" event to let script manually close the co
nnection. |
422 return !m_closePending && hasEventListeners() && !m_contextStopped; | 419 return !m_closePending && hasEventListeners() && executionContext(); |
423 } | 420 } |
424 | 421 |
425 void IDBDatabase::stop() | 422 void IDBDatabase::contextDestroyed() |
426 { | 423 { |
427 m_contextStopped = true; | |
428 | |
429 // Immediately close the connection to the back end. Don't attempt a | 424 // Immediately close the connection to the back end. Don't attempt a |
430 // normal close() since that may wait on transactions which require a | 425 // normal close() since that may wait on transactions which require a |
431 // round trip to the back-end to abort. | 426 // round trip to the back-end to abort. |
432 if (m_backend) { | 427 if (m_backend) { |
433 m_backend->close(); | 428 m_backend->close(); |
434 m_backend.clear(); | 429 m_backend.clear(); |
435 } | 430 } |
436 } | 431 } |
437 | 432 |
438 const AtomicString& IDBDatabase::interfaceName() const | 433 const AtomicString& IDBDatabase::interfaceName() const |
439 { | 434 { |
440 return EventTargetNames::IDBDatabase; | 435 return EventTargetNames::IDBDatabase; |
441 } | 436 } |
442 | 437 |
443 ExecutionContext* IDBDatabase::executionContext() const | 438 ExecutionContext* IDBDatabase::executionContext() const |
444 { | 439 { |
445 return ActiveDOMObject::executionContext(); | 440 return ContextLifecycleObserver::executionContext(); |
446 } | 441 } |
447 | 442 |
448 void IDBDatabase::recordApiCallsHistogram(IndexedDatabaseMethods method) | 443 void IDBDatabase::recordApiCallsHistogram(IndexedDatabaseMethods method) |
449 { | 444 { |
450 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, apiCallsHistogram, new
EnumerationHistogram("WebCore.IndexedDB.FrontEndAPICalls", IDBMethodsMax)); | 445 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, apiCallsHistogram, new
EnumerationHistogram("WebCore.IndexedDB.FrontEndAPICalls", IDBMethodsMax)); |
451 apiCallsHistogram.count(method); | 446 apiCallsHistogram.count(method); |
452 } | 447 } |
453 | 448 |
454 } // namespace blink | 449 } // namespace blink |
OLD | NEW |