| 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 |