Changeset 128533 in webkit
- Timestamp:
- Sep 13, 2012 5:28:38 PM (12 years ago)
- Location:
- trunk/Source
- Files:
-
- 31 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r128531 r128533 1 2012-09-13 Joshua Bell <jsbell@chromium.org> 2 3 IndexedDB: Consolidate two-phase connection to avoid race conditions 4 https://bugs.webkit.org/show_bug.cgi?id=90411 5 6 Reviewed by Tony Chang. 7 8 Previously, IDB connections were opened by having the front-end (1) call through to 9 a back-end open() method, eventually receive a success message with a back-end object 10 handle, and (2) call into the back-end object to register front-end callbacks. This left 11 the back-end's notion of an open connection in a limbo state between these two calls. 12 In multi-process ports, a crash of the front-end process could leave the back-end wedged 13 waiting for this second call (e.g. can't delete until all connections are closed). 14 15 Simplify this by having the front-end pass through the callbacks into the back-end 16 during the initial open() call, which eliminates the limbo state. 17 18 No new tests - no functional changes. Chromium port's webkit_unit_tests updated. 19 20 * Modules/indexeddb/IDBDatabase.cpp: 21 (WebCore::IDBDatabase::create): 22 (WebCore::IDBDatabase::IDBDatabase): Db-callbacks is available at creation time. 23 (WebCore::IDBDatabase::~IDBDatabase): 24 * Modules/indexeddb/IDBDatabase.h: 25 (IDBDatabase): 26 * Modules/indexeddb/IDBDatabaseBackendImpl.cpp: 27 (WebCore::IDBDatabaseBackendImpl::PendingOpenCall::create): Need to track db-callbacks as well. 28 (WebCore::IDBDatabaseBackendImpl::PendingOpenCall::databaseCallbacks): 29 (WebCore::IDBDatabaseBackendImpl::PendingOpenCall::PendingOpenCall): 30 (IDBDatabaseBackendImpl::PendingOpenCall): 31 (WebCore::IDBDatabaseBackendImpl::PendingOpenWithVersionCall::create): Ditto. 32 (WebCore::IDBDatabaseBackendImpl::PendingOpenWithVersionCall::databaseCallbacks): 33 (WebCore::IDBDatabaseBackendImpl::PendingOpenWithVersionCall::PendingOpenWithVersionCall): 34 (IDBDatabaseBackendImpl::PendingOpenWithVersionCall): 35 (WebCore::IDBDatabaseBackendImpl::IDBDatabaseBackendImpl): 36 (WebCore::IDBDatabaseBackendImpl::setVersion): 37 (WebCore::IDBDatabaseBackendImpl::connectionCount): Don't need to count limbo connections any more. 38 (WebCore::IDBDatabaseBackendImpl::processPendingCalls): Pass through db-callbacks. 39 (WebCore::IDBDatabaseBackendImpl::openConnection): No more limbo connections (yay!). 40 (WebCore::IDBDatabaseBackendImpl::runIntVersionChangeTransaction): Pass through db-callbacks. 41 (WebCore::IDBDatabaseBackendImpl::openConnectionWithVersion): Ditto. 42 (WebCore::IDBDatabaseBackendImpl::deleteDatabase): Style. 43 (WebCore::IDBDatabaseBackendImpl::close): Resolve FIXME about connectionCount. 44 * Modules/indexeddb/IDBDatabaseBackendImpl.h: 45 (IDBDatabaseBackendImpl): 46 * Modules/indexeddb/IDBDatabaseBackendInterface.h: 47 (IDBDatabaseBackendInterface): 48 * Modules/indexeddb/IDBDatabaseCallbacksImpl.cpp: 49 (WebCore::IDBDatabaseCallbacksImpl::create): 50 (WebCore::IDBDatabaseCallbacksImpl::IDBDatabaseCallbacksImpl): 51 (WebCore::IDBDatabaseCallbacksImpl::connect): 52 * Modules/indexeddb/IDBDatabaseCallbacksImpl.h: 53 (IDBDatabaseCallbacksImpl): 54 * Modules/indexeddb/IDBFactory.cpp: 55 (WebCore::IDBFactory::open): Mint the db-callbacks here... 56 * Modules/indexeddb/IDBFactoryBackendImpl.cpp: 57 (WebCore::IDBFactoryBackendImpl::open): ...passed through to here... 58 * Modules/indexeddb/IDBFactoryBackendImpl.h: 59 (IDBFactoryBackendImpl): 60 * Modules/indexeddb/IDBFactoryBackendInterface.h: 61 (IDBFactoryBackendInterface): 62 * Modules/indexeddb/IDBOpenDBRequest.cpp: 63 (WebCore::IDBOpenDBRequest::create): ...all the way to here... 64 (WebCore::IDBOpenDBRequest::IDBOpenDBRequest): 65 (WebCore::IDBOpenDBRequest::onUpgradeNeeded): ...and finally hooked up here. 66 (WebCore::IDBOpenDBRequest::onSuccess): (or here, if no upgrade needed). 67 * Modules/indexeddb/IDBOpenDBRequest.h: 68 (WebCore): 69 (IDBOpenDBRequest): 70 * Modules/indexeddb/IDBTransaction.cpp: 71 (WebCore::IDBTransaction::onAbort): Tweak event/notification ordering; the 72 notifying the database that the transaction is finished may unblock closing, 73 which fires more events, and the delivery matters. Previously the close would 74 be blocked by the transaction which gave the desired order. 75 (WebCore::IDBTransaction::onComplete): Ditto. 76 * inspector/InspectorIndexedDBAgent.cpp: New hookup logic. 77 (WebCore): 78 1 79 2012-09-13 Ryosuke Niwa <rniwa@webkit.org> 2 80 -
trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.cpp
r128496 r128533 32 32 #include "ExceptionCode.h" 33 33 #include "IDBAny.h" 34 #include "IDBDatabaseCallbacks Impl.h"34 #include "IDBDatabaseCallbacks.h" 35 35 #include "IDBDatabaseError.h" 36 36 #include "IDBDatabaseException.h" … … 51 51 namespace WebCore { 52 52 53 PassRefPtr<IDBDatabase> IDBDatabase::create(ScriptExecutionContext* context, PassRefPtr<IDBDatabaseBackendInterface> database )54 { 55 RefPtr<IDBDatabase> idbDatabase(adoptRef(new IDBDatabase(context, database )));53 PassRefPtr<IDBDatabase> IDBDatabase::create(ScriptExecutionContext* context, PassRefPtr<IDBDatabaseBackendInterface> database, PassRefPtr<IDBDatabaseCallbacks> callbacks) 54 { 55 RefPtr<IDBDatabase> idbDatabase(adoptRef(new IDBDatabase(context, database, callbacks))); 56 56 idbDatabase->suspendIfNeeded(); 57 57 return idbDatabase.release(); 58 58 } 59 59 60 IDBDatabase::IDBDatabase(ScriptExecutionContext* context, PassRefPtr<IDBDatabaseBackendInterface> backend )60 IDBDatabase::IDBDatabase(ScriptExecutionContext* context, PassRefPtr<IDBDatabaseBackendInterface> backend, PassRefPtr<IDBDatabaseCallbacks> callbacks) 61 61 : ActiveDOMObject(context, this) 62 62 , m_backend(backend) 63 63 , m_closePending(false) 64 64 , m_contextStopped(false) 65 , m_databaseCallbacks(callbacks) 65 66 { 66 67 // We pass a reference of this object before it can be adopted. 67 68 relaxAdoptionRequirement(); 68 m_databaseCallbacks = IDBDatabaseCallbacksImpl::create(this);69 69 m_metadata = m_backend->metadata(); 70 70 } … … 73 73 { 74 74 close(); 75 m_databaseCallbacks->unregisterDatabase(this);76 75 } 77 76 … … 336 335 } 337 336 338 void IDBDatabase::registerFrontendCallbacks()339 {340 ASSERT(m_backend);341 m_backend->registerFrontendCallbacks(m_databaseCallbacks);342 }343 344 337 void IDBDatabase::enqueueEvent(PassRefPtr<Event> event) 345 338 { -
trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.h
r128496 r128533 33 33 #include "EventTarget.h" 34 34 #include "IDBDatabaseBackendInterface.h" 35 #include "IDBDatabaseCallbacks Impl.h"35 #include "IDBDatabaseCallbacks.h" 36 36 #include "IDBMetadata.h" 37 37 #include "IDBObjectStore.h" … … 52 52 class IDBDatabase : public RefCounted<IDBDatabase>, public EventTarget, public ActiveDOMObject { 53 53 public: 54 static PassRefPtr<IDBDatabase> create(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendInterface> );54 static PassRefPtr<IDBDatabase> create(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendInterface>, PassRefPtr<IDBDatabaseCallbacks>); 55 55 ~IDBDatabase(); 56 56 … … 90 90 91 91 void forceClose(); 92 void registerFrontendCallbacks();93 92 const IDBDatabaseMetadata metadata() const { return m_metadata; } 94 93 void enqueueEvent(PassRefPtr<Event>); … … 100 99 101 100 private: 102 IDBDatabase(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendInterface> );101 IDBDatabase(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendInterface>, PassRefPtr<IDBDatabaseCallbacks>); 103 102 104 103 // EventTarget … … 124 123 Vector<RefPtr<Event> > m_enqueuedEvents; 125 124 126 RefPtr<IDBDatabaseCallbacks Impl> m_databaseCallbacks;125 RefPtr<IDBDatabaseCallbacks> m_databaseCallbacks; 127 126 }; 128 127 -
trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp
r128496 r128533 42 42 class IDBDatabaseBackendImpl::PendingOpenCall : public RefCounted<PendingOpenCall> { 43 43 public: 44 static PassRefPtr<PendingOpenCall> create(PassRefPtr<IDBCallbacks> callbacks )45 { 46 return adoptRef(new PendingOpenCall(callbacks ));44 static PassRefPtr<PendingOpenCall> create(PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks) 45 { 46 return adoptRef(new PendingOpenCall(callbacks, databaseCallbacks)); 47 47 } 48 48 PassRefPtr<IDBCallbacks> callbacks() { return m_callbacks; } 49 PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks() { return m_databaseCallbacks; } 49 50 50 51 private: 51 PendingOpenCall(PassRefPtr<IDBCallbacks> callbacks )52 PendingOpenCall(PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks) 52 53 : m_callbacks(callbacks) 54 , m_databaseCallbacks(databaseCallbacks) 53 55 { 54 56 } 55 57 56 58 RefPtr<IDBCallbacks> m_callbacks; 59 RefPtr<IDBDatabaseCallbacks> m_databaseCallbacks; 57 60 }; 58 61 59 62 class IDBDatabaseBackendImpl::PendingOpenWithVersionCall : public RefCounted<PendingOpenWithVersionCall> { 60 63 public: 61 static PassRefPtr<PendingOpenWithVersionCall> create(PassRefPtr<IDBCallbacks> callbacks, int64_t version)62 { 63 return adoptRef(new PendingOpenWithVersionCall(callbacks, version));64 static PassRefPtr<PendingOpenWithVersionCall> create(PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks, int64_t version) 65 { 66 return adoptRef(new PendingOpenWithVersionCall(callbacks, databaseCallbacks, version)); 64 67 } 65 68 PassRefPtr<IDBCallbacks> callbacks() { return m_callbacks; } 69 PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks() { return m_databaseCallbacks; } 66 70 int64_t version() { return m_version; } 67 71 68 72 private: 69 PendingOpenWithVersionCall(PassRefPtr<IDBCallbacks> callbacks, int64_t version)73 PendingOpenWithVersionCall(PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks, int64_t version) 70 74 : m_callbacks(callbacks) 75 , m_databaseCallbacks(databaseCallbacks) 71 76 , m_version(version) 72 77 { 73 78 } 74 79 RefPtr<IDBCallbacks> m_callbacks; 80 RefPtr<IDBDatabaseCallbacks> m_databaseCallbacks; 75 81 int64_t m_version; 76 82 }; … … 131 137 , m_factory(factory) 132 138 , m_transactionCoordinator(coordinator) 133 , m_pendingConnectionCount(0)134 139 { 135 140 ASSERT(!m_name.isNull()); … … 241 246 } 242 247 for (DatabaseCallbacksSet::const_iterator it = m_databaseCallbacksSet.begin(); it != m_databaseCallbacksSet.end(); ++it) { 248 // Front end ensures the event is not fired at connections that have closePending set. 243 249 if (*it != databaseCallbacks) 244 250 (*it)->onVersionChange(version); … … 343 349 } 344 350 345 int32_t IDBDatabaseBackendImpl::connectionCount() 346 { 347 return m_databaseCallbacksSet.size() + m_pendingConnectionCount; 351 size_t IDBDatabaseBackendImpl::connectionCount() 352 { 353 // This does not include pending open calls, as those should not block version changes and deletes. 354 return m_databaseCallbacksSet.size(); 348 355 } 349 356 … … 356 363 ASSERT(pendingOpenWithVersionCall->version() == m_intVersion); 357 364 ASSERT(m_id != InvalidId); 358 ++m_pendingConnectionCount;359 365 pendingOpenWithVersionCall->callbacks()->onSuccess(this); 360 return;366 // Fall through when complete, as pending deletes may be (partially) unblocked. 361 367 } 362 368 … … 401 407 while (!pendingOpenWithVersionCalls.isEmpty()) { 402 408 RefPtr<PendingOpenWithVersionCall> pendingOpenWithVersionCall = pendingOpenWithVersionCalls.takeFirst(); 403 openConnectionWithVersion(pendingOpenWithVersionCall->callbacks(), pendingOpenWithVersionCall-> version());409 openConnectionWithVersion(pendingOpenWithVersionCall->callbacks(), pendingOpenWithVersionCall->databaseCallbacks(), pendingOpenWithVersionCall->version()); 404 410 } 405 411 … … 410 416 while (!pendingOpenCalls.isEmpty()) { 411 417 RefPtr<PendingOpenCall> pendingOpenCall = pendingOpenCalls.takeFirst(); 412 openConnection(pendingOpenCall->callbacks() );418 openConnection(pendingOpenCall->callbacks(), pendingOpenCall->databaseCallbacks()); 413 419 } 414 420 ASSERT(m_pendingOpenCalls.isEmpty()); … … 429 435 } 430 436 431 void IDBDatabaseBackendImpl::registerFrontendCallbacks(PassRefPtr<IDBDatabaseCallbacks> callbacks) 432 { 433 ASSERT(m_backingStore.get()); 434 ASSERT(m_pendingConnectionCount); 435 --m_pendingConnectionCount; 436 m_databaseCallbacksSet.add(RefPtr<IDBDatabaseCallbacks>(callbacks)); 437 // We give max priority to open calls that follow upgradeneeded 438 // events; trigger the rest of the queues to be serviced when those open 439 // calls are finished. 440 processPendingCalls(); 441 } 442 443 void IDBDatabaseBackendImpl::openConnection(PassRefPtr<IDBCallbacks> callbacks) 437 void IDBDatabaseBackendImpl::openConnection(PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks) 444 438 { 445 439 ASSERT(m_backingStore.get()); 446 440 if (!m_pendingDeleteCalls.isEmpty() || m_runningVersionChangeTransaction || !m_pendingSetVersionCalls.isEmpty()) 447 m_pendingOpenCalls.append(PendingOpenCall::create(callbacks ));441 m_pendingOpenCalls.append(PendingOpenCall::create(callbacks, databaseCallbacks)); 448 442 else { 449 443 if (m_id == InvalidId && !openInternal()) 450 444 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error.")); 451 445 else { 452 ++m_pendingConnectionCount;446 m_databaseCallbacksSet.add(RefPtr<IDBDatabaseCallbacks>(databaseCallbacks)); 453 447 callbacks->onSuccess(this); 454 448 } … … 456 450 } 457 451 458 void IDBDatabaseBackendImpl::runIntVersionChangeTransaction(int64_t requestedVersion, PassRefPtr<IDBCallbacks> prpCallbacks )452 void IDBDatabaseBackendImpl::runIntVersionChangeTransaction(int64_t requestedVersion, PassRefPtr<IDBCallbacks> prpCallbacks, PassRefPtr<IDBDatabaseCallbacks> prpDatabaseCallbacks) 459 453 { 460 454 RefPtr<IDBCallbacks> callbacks = prpCallbacks; 455 RefPtr<IDBDatabaseCallbacks> databaseCallbacks = prpDatabaseCallbacks; 461 456 ASSERT(callbacks); 462 457 for (DatabaseCallbacksSet::const_iterator it = m_databaseCallbacksSet.begin(); it != m_databaseCallbacksSet.end(); ++it) { 463 // Note that some connections might close in the versionchange event 464 // handler for some other connection, after which its own versionchange 465 // event should not be fired. The backend doesn't worry about this, we 466 // just queue up a version change event for every connection. The 467 // frontend takes care to only dispatch to open connections. 468 (*it)->onVersionChange(m_intVersion, requestedVersion); 458 // Front end ensures the event is not fired at connections that have closePending set. 459 if (*it != databaseCallbacks) 460 (*it)->onVersionChange(m_intVersion, requestedVersion); 469 461 } 470 462 // The spec dictates we wait until all the version change events are … … 475 467 // tells us that all the blocked events have been delivered. See 476 468 // https://bugs.webkit.org/show_bug.cgi?id=71130 477 if (connectionCount() > 0)469 if (connectionCount()) 478 470 callbacks->onBlocked(m_intVersion); 479 471 // FIXME: Add test for m_runningVersionChangeTransaction. 480 if (m_runningVersionChangeTransaction || connectionCount() > 0) {481 m_pendingOpenWithVersionCalls.append(PendingOpenWithVersionCall::create(callbacks, requestedVersion));472 if (m_runningVersionChangeTransaction || connectionCount()) { 473 m_pendingOpenWithVersionCalls.append(PendingOpenWithVersionCall::create(callbacks, databaseCallbacks, requestedVersion)); 482 474 return; 483 475 } … … 498 490 } 499 491 ASSERT_WITH_MESSAGE(!m_pendingSecondHalfOpenWithVersionCalls.size(), "m_pendingSecondHalfOpenWithVersionCalls.size = %zu", m_pendingSecondHalfOpenWithVersionCalls.size()); 500 m_pendingSecondHalfOpenWithVersionCalls.append(PendingOpenWithVersionCall::create(callbacks, requestedVersion)); 501 } 502 503 void IDBDatabaseBackendImpl::openConnectionWithVersion(PassRefPtr<IDBCallbacks> prpCallbacks, int64_t version) 492 m_pendingSecondHalfOpenWithVersionCalls.append(PendingOpenWithVersionCall::create(callbacks, databaseCallbacks, requestedVersion)); 493 m_databaseCallbacksSet.add(databaseCallbacks); 494 } 495 496 void IDBDatabaseBackendImpl::openConnectionWithVersion(PassRefPtr<IDBCallbacks> prpCallbacks, PassRefPtr<IDBDatabaseCallbacks> prpDatabaseCallbacks, int64_t version) 504 497 { 505 498 RefPtr<IDBCallbacks> callbacks = prpCallbacks; 499 RefPtr<IDBDatabaseCallbacks> databaseCallbacks = prpDatabaseCallbacks; 506 500 if (!m_pendingDeleteCalls.isEmpty() || m_runningVersionChangeTransaction || !m_pendingSetVersionCalls.isEmpty()) { 507 m_pendingOpenWithVersionCalls.append(PendingOpenWithVersionCall::create(callbacks, version));501 m_pendingOpenWithVersionCalls.append(PendingOpenWithVersionCall::create(callbacks, databaseCallbacks, version)); 508 502 return; 509 503 } … … 517 511 } 518 512 if (version > m_intVersion) { 519 runIntVersionChangeTransaction(version, callbacks );513 runIntVersionChangeTransaction(version, callbacks, databaseCallbacks); 520 514 return; 521 515 } … … 525 519 } 526 520 ASSERT(version == m_intVersion); 527 ++m_pendingConnectionCount;521 m_databaseCallbacksSet.add(databaseCallbacks); 528 522 callbacks->onSuccess(this); 529 523 } … … 536 530 } 537 531 RefPtr<IDBCallbacks> callbacks = prpCallbacks; 538 // FIXME: Only fire onVersionChange if there the connection isn't in 539 // the process of closing. 540 // https://bugs.webkit.org/show_bug.cgi?id=71129 541 for (DatabaseCallbacksSet::const_iterator it = m_databaseCallbacksSet.begin(); it != m_databaseCallbacksSet.end(); ++it) 532 for (DatabaseCallbacksSet::const_iterator it = m_databaseCallbacksSet.begin(); it != m_databaseCallbacksSet.end(); ++it) { 533 // Front end ensures the event is not fired at connections that have closePending set. 542 534 (*it)->onVersionChange(""); 535 } 543 536 // FIXME: Only fire onBlocked if there are open connections after the 544 537 // VersionChangeEvents are received, not just set up to fire. 545 538 // https://bugs.webkit.org/show_bug.cgi?id=71130 546 if (connectionCount() >= 1) {539 if (connectionCount()) { 547 540 m_pendingDeleteCalls.append(PendingDeleteCall::create(callbacks)); 548 541 callbacks->onBlocked(); … … 565 558 RefPtr<IDBDatabaseCallbacks> callbacks = prpCallbacks; 566 559 ASSERT(m_databaseCallbacksSet.contains(callbacks)); 560 567 561 m_databaseCallbacksSet.remove(callbacks); 562 // FIXME: If callbacks is also held in m_pendingSecondHalfOpenWithVersionCalls 563 // it should be removed and onError fired against it. 564 568 565 if (connectionCount() > 1) 569 566 return; 570 567 571 TransactionSet transactions(m_transactions);572 568 processPendingCalls(); 573 569 574 ASSERT(m_transactions.size() - transactions.size() <= 1); 575 // FIXME: Instead of relying on transactions.size(), make connectionCount 576 // aware of in-flight upgradeneeded events as well as in-flight success 577 // events. 578 if (!connectionCount() && !m_pendingDeleteCalls.size() && m_transactions.size() == transactions.size()) { 570 // FIXME: Add a test for the m_pendingOpenCalls·and m_pendingOpenWithVersionCalls cases below. 571 if (!connectionCount() && !m_pendingOpenCalls.size() && !m_pendingOpenWithVersionCalls.size() && !m_pendingDeleteCalls.size()) { 572 TransactionSet transactions(m_transactions); 579 573 for (TransactionSet::const_iterator it = transactions.begin(); it != transactions.end(); ++it) 580 574 (*it)->abort(); -
trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.h
r128496 r128533 56 56 int64_t id() const { return m_id; } 57 57 58 void registerFrontendCallbacks(PassRefPtr<IDBDatabaseCallbacks>); 59 void openConnection(PassRefPtr<IDBCallbacks>); 60 void openConnectionWithVersion(PassRefPtr<IDBCallbacks>, int64_t version); 58 void openConnection(PassRefPtr<IDBCallbacks>, PassRefPtr<IDBDatabaseCallbacks>); 59 void openConnectionWithVersion(PassRefPtr<IDBCallbacks>, PassRefPtr<IDBDatabaseCallbacks>, int64_t version); 61 60 void deleteDatabase(PassRefPtr<IDBCallbacks>); 62 61 … … 80 79 81 80 bool openInternal(); 82 void runIntVersionChangeTransaction(int64_t requestedVersion, PassRefPtr<IDBCallbacks> );81 void runIntVersionChangeTransaction(int64_t requestedVersion, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBDatabaseCallbacks>); 83 82 void loadObjectStores(); 84 int32_t connectionCount();83 size_t connectionCount(); 85 84 void processPendingCalls(); 86 85 … … 128 127 Deque<RefPtr<PendingDeleteCall> > m_pendingDeleteCalls; 129 128 130 // FIXME: Eliminate the limbo state between openConnection() and registerFrontendCallbacks()131 // that this counter tracks.132 int32_t m_pendingConnectionCount;133 134 129 typedef ListHashSet<RefPtr<IDBDatabaseCallbacks> > DatabaseCallbacksSet; 135 130 DatabaseCallbacksSet m_databaseCallbacksSet; -
trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendInterface.h
r128496 r128533 36 36 37 37 class DOMStringList; 38 class Frame;39 38 class IDBCallbacks; 40 39 class IDBDatabaseCallbacks; … … 61 60 virtual PassRefPtr<IDBTransactionBackendInterface> transaction(DOMStringList* storeNames, unsigned short mode, ExceptionCode&) = 0; 62 61 virtual void close(PassRefPtr<IDBDatabaseCallbacks>) = 0; 63 64 virtual void registerFrontendCallbacks(PassRefPtr<IDBDatabaseCallbacks>) = 0;65 62 }; 66 63 -
trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseCallbacksImpl.cpp
r128496 r128533 33 33 namespace WebCore { 34 34 35 PassRefPtr<IDBDatabaseCallbacksImpl> IDBDatabaseCallbacksImpl::create( IDBDatabase* database)35 PassRefPtr<IDBDatabaseCallbacksImpl> IDBDatabaseCallbacksImpl::create() 36 36 { 37 return adoptRef(new IDBDatabaseCallbacksImpl( database));37 return adoptRef(new IDBDatabaseCallbacksImpl()); 38 38 } 39 39 40 IDBDatabaseCallbacksImpl::IDBDatabaseCallbacksImpl( IDBDatabase* database)41 : m_database( database)40 IDBDatabaseCallbacksImpl::IDBDatabaseCallbacksImpl() 41 : m_database(0) 42 42 { 43 43 } … … 65 65 } 66 66 67 void IDBDatabaseCallbacksImpl:: unregisterDatabase(IDBDatabase* database)67 void IDBDatabaseCallbacksImpl::connect(IDBDatabase* database) 68 68 { 69 ASSERT_UNUSED(database, database == m_database); 70 m_database = 0; 69 ASSERT(!m_database); 70 ASSERT(database); 71 m_database = database; 71 72 } 72 73 -
trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseCallbacksImpl.h
r128496 r128533 39 39 class IDBDatabaseCallbacksImpl : public IDBDatabaseCallbacks { 40 40 public: 41 static PassRefPtr<IDBDatabaseCallbacksImpl> create( IDBDatabase*);41 static PassRefPtr<IDBDatabaseCallbacksImpl> create(); 42 42 virtual ~IDBDatabaseCallbacksImpl(); 43 43 44 // IDBDatabaseCallbacks 44 45 virtual void onForcedClose(); 45 46 virtual void onVersionChange(const String& version); 46 47 virtual void onVersionChange(int64_t oldVersion, int64_t newVersion); 47 void unregisterDatabase(IDBDatabase*); 48 49 void connect(IDBDatabase*); 48 50 49 51 private: 50 IDBDatabaseCallbacksImpl( IDBDatabase*);52 IDBDatabaseCallbacksImpl(); 51 53 52 // m_database has a RefPtr to this, so use a weak pointer to avoid a cycle.54 // The initial IDBOpenDBRequest or final IDBDatabase maintains a RefPtr to this 53 55 IDBDatabase* m_database; 54 56 }; -
trunk/Source/WebCore/Modules/indexeddb/IDBFactory.cpp
r128496 r128533 38 38 #include "GroupSettings.h" 39 39 #include "IDBDatabase.h" 40 #include "IDBDatabaseCallbacksImpl.h" 40 41 #include "IDBDatabaseException.h" 41 42 #include "IDBFactoryBackendInterface.h" … … 121 122 return 0; 122 123 123 RefPtr<IDBOpenDBRequest> request = IDBOpenDBRequest::create(context, IDBAny::createNull(), version); 124 m_backend->open(name, version, request, context->securityOrigin(), context, getIndexedDBDatabasePath(context)); 124 RefPtr<IDBDatabaseCallbacksImpl> databaseCallbacks = IDBDatabaseCallbacksImpl::create(); 125 RefPtr<IDBOpenDBRequest> request = IDBOpenDBRequest::create(context, IDBAny::createNull(), databaseCallbacks, version); 126 m_backend->open(name, version, request, databaseCallbacks, context->securityOrigin(), context, getIndexedDBDatabasePath(context)); 125 127 return request; 126 128 } -
trunk/Source/WebCore/Modules/indexeddb/IDBFactoryBackendImpl.cpp
r128496 r128533 151 151 } 152 152 153 void IDBFactoryBackendImpl::open(const String& name, int64_t version, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr< SecurityOrigin> prpSecurityOrigin, ScriptExecutionContext*, const String& dataDirectory)153 void IDBFactoryBackendImpl::open(const String& name, int64_t version, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks, PassRefPtr<SecurityOrigin> prpSecurityOrigin, ScriptExecutionContext*, const String& dataDirectory) 154 154 { 155 155 RefPtr<SecurityOrigin> securityOrigin = prpSecurityOrigin; … … 176 176 177 177 if (version == IDBDatabaseMetadata::NoIntVersion) 178 databaseBackend->openConnection(callbacks );178 databaseBackend->openConnection(callbacks, databaseCallbacks); 179 179 else 180 databaseBackend->openConnectionWithVersion(callbacks, version);180 databaseBackend->openConnectionWithVersion(callbacks, databaseCallbacks, version); 181 181 } 182 182 -
trunk/Source/WebCore/Modules/indexeddb/IDBFactoryBackendImpl.h
r128496 r128533 58 58 59 59 virtual void getDatabaseNames(PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, ScriptExecutionContext*, const String& dataDir); 60 virtual void open(const String& name, int64_t version, PassRefPtr<IDBCallbacks>, PassRefPtr< SecurityOrigin>, ScriptExecutionContext*, const String& dataDir);60 virtual void open(const String& name, int64_t version, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBDatabaseCallbacks>, PassRefPtr<SecurityOrigin>, ScriptExecutionContext*, const String& dataDir); 61 61 virtual void deleteDatabase(const String& name, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, ScriptExecutionContext*, const String& dataDir); 62 62 -
trunk/Source/WebCore/Modules/indexeddb/IDBFactoryBackendInterface.h
r128496 r128533 29 29 #define IDBFactoryBackendInterface_h 30 30 31 #include "IDBCallbacks.h"31 #include <wtf/PassRefPtr.h> 32 32 #include <wtf/Threading.h> 33 #include <wtf/Vector.h>34 33 #include <wtf/text/WTFString.h> 35 34 … … 38 37 namespace WebCore { 39 38 40 class Frame;39 class IDBCallbacks; 41 40 class IDBDatabase; 41 class IDBDatabaseCallbacks; 42 42 class SecurityOrigin; 43 class WorkerContext;43 class ScriptExecutionContext; 44 44 45 45 typedef int ExceptionCode; … … 55 55 56 56 virtual void getDatabaseNames(PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, ScriptExecutionContext*, const String& dataDir) = 0; 57 virtual void open(const String& name, int64_t version, PassRefPtr<IDBCallbacks>, PassRefPtr< SecurityOrigin>, ScriptExecutionContext*, const String& dataDir) = 0;57 virtual void open(const String& name, int64_t version, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBDatabaseCallbacks>, PassRefPtr<SecurityOrigin>, ScriptExecutionContext*, const String& dataDir) = 0; 58 58 virtual void deleteDatabase(const String& name, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, ScriptExecutionContext*, const String& dataDir) = 0; 59 59 }; -
trunk/Source/WebCore/Modules/indexeddb/IDBOpenDBRequest.cpp
r128496 r128533 30 30 31 31 #include "IDBDatabase.h" 32 #include "IDBDatabaseCallbacksImpl.h" 32 33 #include "IDBPendingTransactionMonitor.h" 33 34 #include "IDBTracing.h" … … 37 38 namespace WebCore { 38 39 39 PassRefPtr<IDBOpenDBRequest> IDBOpenDBRequest::create(ScriptExecutionContext* context, PassRefPtr<IDBAny> source, int64_t version)40 PassRefPtr<IDBOpenDBRequest> IDBOpenDBRequest::create(ScriptExecutionContext* context, PassRefPtr<IDBAny> source, PassRefPtr<IDBDatabaseCallbacksImpl> callbacks, int64_t version) 40 41 { 41 RefPtr<IDBOpenDBRequest> request(adoptRef(new IDBOpenDBRequest(context, source, version)));42 RefPtr<IDBOpenDBRequest> request(adoptRef(new IDBOpenDBRequest(context, source, callbacks, version))); 42 43 request->suspendIfNeeded(); 43 44 return request.release(); 44 45 } 45 46 46 IDBOpenDBRequest::IDBOpenDBRequest(ScriptExecutionContext* context, PassRefPtr<IDBAny> source, int64_t version)47 IDBOpenDBRequest::IDBOpenDBRequest(ScriptExecutionContext* context, PassRefPtr<IDBAny> source, PassRefPtr<IDBDatabaseCallbacksImpl> callbacks, int64_t version) 47 48 : IDBRequest(context, source, IDBTransactionBackendInterface::NormalTask, 0) 49 , m_databaseCallbacks(callbacks) 48 50 , m_version(version) 49 51 { … … 73 75 return; 74 76 77 ASSERT(m_databaseCallbacks); 78 75 79 RefPtr<IDBDatabaseBackendInterface> databaseBackend = prpDatabaseBackend; 76 80 RefPtr<IDBTransactionBackendInterface> transactionBackend = prpTransactionBackend; 77 RefPtr<IDBDatabase> idbDatabase = IDBDatabase::create(scriptExecutionContext(), databaseBackend); 81 RefPtr<IDBDatabase> idbDatabase = IDBDatabase::create(scriptExecutionContext(), databaseBackend, m_databaseCallbacks); 82 m_databaseCallbacks->connect(idbDatabase.get()); 83 m_databaseCallbacks = 0; 78 84 79 85 RefPtr<IDBTransaction> frontend = IDBTransaction::create(scriptExecutionContext(), transactionBackend, IDBTransaction::VERSION_CHANGE, idbDatabase.get(), this); … … 99 105 idbDatabase = m_result->idbDatabase(); 100 106 ASSERT(idbDatabase); 107 ASSERT(!m_databaseCallbacks); 101 108 } else { 102 idbDatabase = IDBDatabase::create(scriptExecutionContext(), backend); 109 ASSERT(m_databaseCallbacks); 110 idbDatabase = IDBDatabase::create(scriptExecutionContext(), backend, m_databaseCallbacks); 111 m_databaseCallbacks->connect(idbDatabase.get()); 112 m_databaseCallbacks = 0; 103 113 m_result = IDBAny::create(idbDatabase.get()); 104 114 } 105 idbDatabase->registerFrontendCallbacks();106 115 enqueueEvent(Event::create(eventNames().successEvent, false, false)); 107 116 } -
trunk/Source/WebCore/Modules/indexeddb/IDBOpenDBRequest.h
r128496 r128533 33 33 namespace WebCore { 34 34 35 class IDBDatabaseCallbacksImpl; 36 35 37 class IDBOpenDBRequest : public IDBRequest { 36 38 public: 37 static PassRefPtr<IDBOpenDBRequest> create(ScriptExecutionContext*, PassRefPtr<IDBAny> source, int64_t version);39 static PassRefPtr<IDBOpenDBRequest> create(ScriptExecutionContext*, PassRefPtr<IDBAny> source, PassRefPtr<IDBDatabaseCallbacksImpl>, int64_t version); 38 40 virtual ~IDBOpenDBRequest(); 39 41 … … 54 56 55 57 private: 56 IDBOpenDBRequest(ScriptExecutionContext*, PassRefPtr<IDBAny> source, int64_t version);58 IDBOpenDBRequest(ScriptExecutionContext*, PassRefPtr<IDBAny> source, PassRefPtr<IDBDatabaseCallbacksImpl>, int64_t version); 57 59 60 RefPtr<IDBDatabaseCallbacksImpl> m_databaseCallbacks; 58 61 int64_t m_version; 59 62 }; -
trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp
r128496 r128533 295 295 m_objectStoreCleanupMap.clear(); 296 296 closeOpenCursors(); 297 298 // Enqueue events before notifying database, as database may close which enqueues more events and order matters. 299 enqueueEvent(Event::create(eventNames().abortEvent, true, false)); 297 300 m_database->transactionFinished(this); 298 299 if (m_contextStopped || !scriptExecutionContext())300 return;301 302 enqueueEvent(Event::create(eventNames().abortEvent, true, false));303 301 } 304 302 … … 310 308 m_objectStoreCleanupMap.clear(); 311 309 closeOpenCursors(); 310 311 // Enqueue events before notifying database, as database may close which enqueues more events and order matters. 312 enqueueEvent(Event::create(eventNames().completeEvent, false, false)); 312 313 m_database->transactionFinished(this); 313 314 if (m_contextStopped || !scriptExecutionContext())315 return;316 317 enqueueEvent(Event::create(eventNames().completeEvent, false, false));318 314 } 319 315 -
trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp
r128496 r128533 173 173 }; 174 174 175 class DatabaseConnection { 176 public: 177 DatabaseConnection() 178 : m_idbDatabaseCallbacks(InspectorIDBDatabaseCallbacks::create()) { } 179 180 ~DatabaseConnection() 181 { 182 if (m_idbDatabase) 183 m_idbDatabase->close(m_idbDatabaseCallbacks); 184 } 185 186 void connect(PassRefPtr<IDBDatabaseBackendInterface> database) { m_idbDatabase = database; } 187 PassRefPtr<IDBDatabaseCallbacks> callbacks() { return m_idbDatabaseCallbacks; } 188 189 private: 190 RefPtr<IDBDatabaseBackendInterface> m_idbDatabase; 191 RefPtr<IDBDatabaseCallbacks> m_idbDatabaseCallbacks; 192 }; 193 175 194 class ExecutableWithDatabase : public RefCounted<ExecutableWithDatabase> { 176 195 public: 177 196 virtual ~ExecutableWithDatabase() { }; 178 197 void start(IDBFactoryBackendInterface*, SecurityOrigin*, ScriptExecutionContext*, const String& databaseName); 198 void connect(PassRefPtr<IDBDatabaseBackendInterface> database) { m_connection.connect(database); } 179 199 virtual void execute(PassRefPtr<IDBDatabaseBackendInterface>) = 0; 180 }; 181 182 class DatabaseConnection { 183 public: 184 DatabaseConnection() 185 : m_idbDatabaseCallbacks(InspectorIDBDatabaseCallbacks::create()) { } 186 187 void connect(PassRefPtr<IDBDatabaseBackendInterface> idbDatabase) 188 { 189 m_idbDatabase = idbDatabase; 190 m_idbDatabase->registerFrontendCallbacks(m_idbDatabaseCallbacks); 191 } 192 193 ~DatabaseConnection() 194 { 195 if (m_idbDatabase) 196 m_idbDatabase->close(m_idbDatabaseCallbacks); 197 } 198 199 private: 200 RefPtr<IDBDatabaseBackendInterface> m_idbDatabase; 201 RefPtr<IDBDatabaseCallbacks> m_idbDatabaseCallbacks; 200 private: 201 DatabaseConnection m_connection; 202 202 }; 203 203 … … 214 214 { 215 215 RefPtr<IDBDatabaseBackendInterface> idbDatabase = prpDatabase; 216 m_executableWithDatabase->connect(idbDatabase); 216 217 m_executableWithDatabase->execute(idbDatabase); 217 218 } … … 226 227 { 227 228 RefPtr<OpenDatabaseCallback> callback = OpenDatabaseCallback::create(this); 228 idbFactory->open(databaseName, IDBDatabaseMetadata::NoIntVersion, callback .get(), securityOrigin, context, String());229 idbFactory->open(databaseName, IDBDatabaseMetadata::NoIntVersion, callback, m_connection.callbacks(), securityOrigin, context, String()); 229 230 } 230 231 … … 297 298 { 298 299 RefPtr<IDBDatabaseBackendInterface> idbDatabase = prpDatabase; 299 m_connection.connect(idbDatabase);300 300 if (!m_requestCallback->isActive()) 301 301 return; … … 340 340 : m_requestCallback(requestCallback) { } 341 341 RefPtr<RequestDatabaseCallback> m_requestCallback; 342 DatabaseConnection m_connection;343 342 }; 344 343 … … 556 555 { 557 556 RefPtr<IDBDatabaseBackendInterface> idbDatabase = prpDatabase; 558 m_connection.connect(idbDatabase);559 557 if (!m_requestCallback->isActive()) 560 558 return; … … 598 596 int m_skipCount; 599 597 unsigned m_pageSize; 600 DatabaseConnection m_connection;601 598 }; 602 599 -
trunk/Source/WebKit/chromium/ChangeLog
r128526 r128533 1 2012-09-13 Joshua Bell <jsbell@chromium.org> 2 3 IndexedDB: Consolidate two-phase connection to avoid race conditions 4 https://bugs.webkit.org/show_bug.cgi?id=90411 5 6 Reviewed by Tony Chang. 7 8 API plumbing for simplified single-phase connection opening, and tests updated 9 to exercise the new APIs. 10 11 * public/WebIDBDatabase.h: 12 (WebIDBDatabase): Just a FIXME to remove the old second-phase hookup API. 13 * public/WebIDBFactory.h: 14 (WebKit): 15 (WebIDBFactory): 16 (WebKit::WebIDBFactory::open): New overload that takes db-callbacks. 17 * src/IDBCallbacksProxy.cpp: The db-callbacks plumbing is needed earlier. 18 (WebKit::IDBCallbacksProxy::onSuccess): 19 (WebKit::IDBCallbacksProxy::onUpgradeNeeded): 20 (WebKit): 21 (WebKit::IDBCallbacksProxy::setDatabaseCallbacks): Needs to hold on to 22 the db-callbacks and hook it up when the onSuccess callback comes through. 23 * src/IDBCallbacksProxy.h: 24 (WebKit): 25 (IDBCallbacksProxy): 26 * src/IDBDatabaseBackendProxy.cpp: 27 * src/IDBDatabaseBackendProxy.h: 28 (IDBDatabaseBackendProxy): 29 * src/IDBFactoryBackendProxy.cpp: 30 (WebKit::IDBFactoryBackendProxy::open): 31 * src/IDBFactoryBackendProxy.h: 32 (IDBFactoryBackendProxy): 33 * src/WebIDBDatabaseImpl.cpp: 34 (WebKit::WebIDBDatabaseImpl::WebIDBDatabaseImpl): 35 (WebKit::WebIDBDatabaseImpl::close): 36 * src/WebIDBDatabaseImpl.h: 37 (WebIDBDatabaseImpl): 38 * src/WebIDBFactoryImpl.cpp: 39 (WebKit::WebIDBFactoryImpl::open): 40 * src/WebIDBFactoryImpl.h: 41 (WebIDBFactoryImpl): 42 * tests/IDBAbortOnCorruptTest.cpp: 43 (FakeIDBDatabaseCallbacks): 44 (WebCore::FakeIDBDatabaseCallbacks::create): 45 (WebCore::FakeIDBDatabaseCallbacks::~FakeIDBDatabaseCallbacks): 46 (WebCore::FakeIDBDatabaseCallbacks::FakeIDBDatabaseCallbacks): 47 (WebCore): 48 (WebCore::TEST): Updated connection sequence. 49 * tests/IDBDatabaseBackendTest.cpp: Ditto. 50 1 51 2012-09-13 James Robinson <jamesr@chromium.org> 2 52 -
trunk/Source/WebKit/chromium/public/WebIDBDatabase.h
r128496 r128533 67 67 virtual void forceClose() { WEBKIT_ASSERT_NOT_REACHED(); } 68 68 69 // FIXME: Remove this method after WK90411 cleanup is complete on the Chromium side. 69 70 virtual void open(WebIDBDatabaseCallbacks*) { WEBKIT_ASSERT_NOT_REACHED(); } 70 71 -
trunk/Source/WebKit/chromium/public/WebIDBFactory.h
r128496 r128533 56 56 virtual void getDatabaseNames(WebIDBCallbacks* callbacks, const WebSecurityOrigin& origin, WebFrame* frame, const WebString& dataDir) { WEBKIT_ASSERT_NOT_REACHED(); } 57 57 58 // FIXME: This overload should be removed when WK90411 lands.58 // FIXME: Remove this overload after WK90411 cleanup is complete on the Chromium side. 59 59 // The WebKit implementation of open ignores the WebFrame* parameter. 60 60 virtual void open(const WebString& name, long long version, WebIDBCallbacks* callbacks, const WebSecurityOrigin& origin, WebFrame* frame, const WebString& dataDir) { WEBKIT_ASSERT_NOT_REACHED(); } -
trunk/Source/WebKit/chromium/src/IDBCallbacksProxy.cpp
r128496 r128533 35 35 #include "IDBDatabaseBackendInterface.h" 36 36 #include "IDBDatabaseBackendProxy.h" 37 #include "IDBDatabaseCallbacksProxy.h" 37 38 #include "IDBDatabaseError.h" 38 39 #include "IDBObjectStoreBackendInterface.h" … … 40 41 #include "WebIDBCallbacks.h" 41 42 #include "WebIDBCursorImpl.h" 43 #include "WebIDBDatabaseCallbacks.h" 44 #include "WebIDBDatabaseError.h" 42 45 #include "WebIDBDatabaseImpl.h" 43 #include "WebIDBDatabaseError.h"44 46 #include "WebIDBKey.h" 45 47 #include "WebIDBTransactionImpl.h" … … 76 78 void IDBCallbacksProxy::onSuccess(PassRefPtr<IDBDatabaseBackendInterface> backend) 77 79 { 78 m_callbacks->onSuccess(new WebIDBDatabaseImpl(backend)); 80 ASSERT(m_databaseCallbacks.get()); 81 m_callbacks->onSuccess(new WebIDBDatabaseImpl(backend, m_databaseCallbacks.release())); 79 82 } 80 83 … … 138 141 void IDBCallbacksProxy::onUpgradeNeeded(int64_t oldVersion, PassRefPtr<IDBTransactionBackendInterface> transaction, PassRefPtr<IDBDatabaseBackendInterface> database) 139 142 { 140 m_callbacks->onUpgradeNeeded(oldVersion, new WebIDBTransactionImpl(transaction), new WebIDBDatabaseImpl(database)); 143 ASSERT(m_databaseCallbacks); 144 m_callbacks->onUpgradeNeeded(oldVersion, new WebIDBTransactionImpl(transaction), new WebIDBDatabaseImpl(database, m_databaseCallbacks)); 145 } 146 147 void IDBCallbacksProxy::setDatabaseCallbacks(PassRefPtr<IDBDatabaseCallbacksProxy> databaseCallbacks) 148 { 149 ASSERT(!m_databaseCallbacks); 150 m_databaseCallbacks = databaseCallbacks; 141 151 } 142 152 143 153 } // namespace WebKit 144 154 155 145 156 #endif // ENABLE(INDEXED_DATABASE) -
trunk/Source/WebKit/chromium/src/IDBCallbacksProxy.h
r128496 r128533 40 40 41 41 class WebIDBCallbacks; 42 class IDBDatabaseCallbacksProxy; 42 43 43 44 class IDBCallbacksProxy : public WebCore::IDBCallbacks { … … 60 61 virtual void onUpgradeNeeded(int64_t oldVersion, PassRefPtr<WebCore::IDBTransactionBackendInterface>, PassRefPtr<WebCore::IDBDatabaseBackendInterface>); 61 62 63 void setDatabaseCallbacks(PassRefPtr<IDBDatabaseCallbacksProxy>); 64 62 65 private: 63 66 IDBCallbacksProxy(PassOwnPtr<WebIDBCallbacks>); 64 67 65 68 OwnPtr<WebIDBCallbacks> m_callbacks; 69 RefPtr<IDBDatabaseCallbacksProxy> m_databaseCallbacks; 66 70 }; 67 71 -
trunk/Source/WebKit/chromium/src/IDBDatabaseBackendProxy.cpp
r128496 r128533 108 108 } 109 109 110 void IDBDatabaseBackendProxy::registerFrontendCallbacks(PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks)111 {112 m_webIDBDatabase->open(new WebIDBDatabaseCallbacksImpl(databaseCallbacks));113 }114 115 110 } // namespace WebKit 116 111 -
trunk/Source/WebKit/chromium/src/IDBDatabaseBackendProxy.h
r128496 r128533 51 51 virtual void close(PassRefPtr<WebCore::IDBDatabaseCallbacks>); 52 52 53 virtual void registerFrontendCallbacks(PassRefPtr<WebCore::IDBDatabaseCallbacks>);54 55 53 private: 56 54 IDBDatabaseBackendProxy(PassOwnPtr<WebIDBDatabase>); -
trunk/Source/WebKit/chromium/src/IDBFactoryBackendProxy.cpp
r128496 r128533 35 35 #include "DOMStringList.h" 36 36 #include "IDBDatabaseBackendProxy.h" 37 #include "IDBDatabaseCallbacks.h" 37 38 #include "IDBDatabaseError.h" 38 39 #include "ScriptExecutionContext.h" … … 41 42 #include "WebIDBCallbacksImpl.h" 42 43 #include "WebIDBDatabase.h" 44 #include "WebIDBDatabaseCallbacksImpl.h" 43 45 #include "WebIDBDatabaseError.h" 44 46 #include "WebIDBFactory.h" … … 204 206 205 207 206 void IDBFactoryBackendProxy::open(const String& name, int64_t version, PassRefPtr<IDBCallbacks> prpCallbacks, PassRefPtr<SecurityOrigin> securityOrigin, ScriptExecutionContext* context, const String& dataDir) 208 void IDBFactoryBackendProxy::open(const String& name, int64_t version, PassRefPtr<IDBCallbacks> prpCallbacks, PassRefPtr<IDBDatabaseCallbacks> prpDatabaseCallbacks, PassRefPtr<SecurityOrigin> securityOrigin, ScriptExecutionContext* context, const String& dataDir) 209 { 210 RefPtr<IDBCallbacks> callbacks(prpCallbacks); 211 RefPtr<IDBDatabaseCallbacks> databaseCallbacks(prpDatabaseCallbacks); 212 WebSecurityOrigin origin(securityOrigin); 213 if (!allowIndexedDB(context, name, origin, callbacks)) 214 return; 215 216 WebFrameImpl* webFrame = getWebFrame(context); 217 m_webIDBFactory->open(name, version, new WebIDBCallbacksImpl(callbacks), new WebIDBDatabaseCallbacksImpl(databaseCallbacks), origin, webFrame, dataDir); 218 } 219 220 void IDBFactoryBackendProxy::deleteDatabase(const String& name, PassRefPtr<IDBCallbacks> prpCallbacks, PassRefPtr<SecurityOrigin> securityOrigin, ScriptExecutionContext* context, const String& dataDir) 207 221 { 208 222 RefPtr<IDBCallbacks> callbacks(prpCallbacks); … … 212 226 213 227 WebFrameImpl* webFrame = getWebFrame(context); 214 m_webIDBFactory->open(name, version, new WebIDBCallbacksImpl(callbacks), origin, webFrame, dataDir);215 }216 217 void IDBFactoryBackendProxy::deleteDatabase(const String& name, PassRefPtr<IDBCallbacks> prpCallbacks, PassRefPtr<SecurityOrigin> securityOrigin, ScriptExecutionContext* context, const String& dataDir)218 {219 RefPtr<IDBCallbacks> callbacks(prpCallbacks);220 WebSecurityOrigin origin(securityOrigin);221 if (!allowIndexedDB(context, name, origin, callbacks))222 return;223 224 WebFrameImpl* webFrame = getWebFrame(context);225 228 m_webIDBFactory->deleteDatabase(name, new WebIDBCallbacksImpl(callbacks), origin, webFrame, dataDir); 226 229 } -
trunk/Source/WebKit/chromium/src/IDBFactoryBackendProxy.h
r128496 r128533 50 50 51 51 virtual void getDatabaseNames(PassRefPtr<WebCore::IDBCallbacks>, PassRefPtr<WebCore::SecurityOrigin>, WebCore::ScriptExecutionContext*, const String& dataDir); 52 virtual void open(const String& name, int64_t version, PassRefPtr<WebCore::IDBCallbacks>, PassRefPtr<WebCore:: SecurityOrigin>, WebCore::ScriptExecutionContext*, const String& dataDir);52 virtual void open(const String& name, int64_t version, PassRefPtr<WebCore::IDBCallbacks>, PassRefPtr<WebCore::IDBDatabaseCallbacks>, PassRefPtr<WebCore::SecurityOrigin>, WebCore::ScriptExecutionContext*, const String& dataDir); 53 53 virtual void deleteDatabase(const String& name, PassRefPtr<WebCore::IDBCallbacks>, PassRefPtr<WebCore::SecurityOrigin>, WebCore::ScriptExecutionContext*, const String& dataDir); 54 54 -
trunk/Source/WebKit/chromium/src/WebIDBDatabaseImpl.cpp
r128496 r128533 46 46 namespace WebKit { 47 47 48 WebIDBDatabaseImpl::WebIDBDatabaseImpl(PassRefPtr<IDBDatabaseBackendInterface> databaseBackend )48 WebIDBDatabaseImpl::WebIDBDatabaseImpl(PassRefPtr<IDBDatabaseBackendInterface> databaseBackend, WTF::PassRefPtr<IDBDatabaseCallbacksProxy> databaseCallbacks) 49 49 : m_databaseBackend(databaseBackend) 50 , m_databaseCallbacks(databaseCallbacks) 50 51 , m_closePending(false) 51 52 { … … 94 95 void WebIDBDatabaseImpl::close() 95 96 { 96 // Use the callbacks that ::open gave usso that the backend in97 // Use the callbacks passed in to the constructor so that the backend in 97 98 // multi-process chromium knows which database connection is closing. 98 99 if (!m_databaseCallbacks) { … … 114 115 } 115 116 116 void WebIDBDatabaseImpl::open(WebIDBDatabaseCallbacks* callbacks)117 {118 ASSERT(!m_databaseCallbacks);119 m_databaseCallbacks = IDBDatabaseCallbacksProxy::create(adoptPtr(callbacks));120 m_databaseBackend->registerFrontendCallbacks(m_databaseCallbacks);121 if (m_closePending)122 close();123 }124 125 117 } // namespace WebKit 126 118 -
trunk/Source/WebKit/chromium/src/WebIDBDatabaseImpl.h
r128496 r128533 48 48 class WebIDBDatabaseImpl : public WebIDBDatabase { 49 49 public: 50 WebIDBDatabaseImpl(WTF::PassRefPtr<WebCore::IDBDatabaseBackendInterface> );50 WebIDBDatabaseImpl(WTF::PassRefPtr<WebCore::IDBDatabaseBackendInterface>, WTF::PassRefPtr<IDBDatabaseCallbacksProxy>); 51 51 virtual ~WebIDBDatabaseImpl(); 52 52 … … 59 59 virtual void forceClose(); 60 60 virtual void close(); 61 62 // FIXME: Rename "open" to registerFrontendCallbacks.63 virtual void open(WebIDBDatabaseCallbacks*);64 61 65 62 private: -
trunk/Source/WebKit/chromium/src/WebIDBFactoryImpl.cpp
r128496 r128533 36 36 #include "DOMStringList.h" 37 37 #include "IDBCallbacksProxy.h" 38 #include "IDBDatabaseCallbacksProxy.h" 38 39 #include "IDBFactoryBackendImpl.h" 39 40 #include "SecurityOrigin.h" 41 #include "WebIDBDatabaseCallbacks.h" 40 42 #include "WebIDBDatabaseError.h" 41 43 #include <wtf/OwnPtr.h> … … 64 66 } 65 67 66 void WebIDBFactoryImpl::open(const WebString& name, long long version, WebIDBCallbacks* callbacks, const WebSecurityOrigin& origin, WebFrame*, const WebString& dataDir)68 void WebIDBFactoryImpl::open(const WebString& name, long long version, WebIDBCallbacks* callbacks, WebIDBDatabaseCallbacks* databaseCallbacks, const WebSecurityOrigin& origin, WebFrame*, const WebString& dataDir) 67 69 { 68 m_idbFactoryBackend->open(name, version, IDBCallbacksProxy::create(adoptPtr(callbacks)).get(), origin, 0, dataDir); 70 RefPtr<IDBCallbacksProxy> callbacksProxy = IDBCallbacksProxy::create(adoptPtr(callbacks)); 71 RefPtr<IDBDatabaseCallbacksProxy> databaseCallbacksProxy = IDBDatabaseCallbacksProxy::create(adoptPtr(databaseCallbacks)); 72 callbacksProxy->setDatabaseCallbacks(databaseCallbacksProxy); 73 m_idbFactoryBackend->open(name, version, callbacksProxy.get(), databaseCallbacksProxy.get(), origin, 0, dataDir); 69 74 } 70 75 -
trunk/Source/WebKit/chromium/src/WebIDBFactoryImpl.h
r128496 r128533 46 46 47 47 virtual void getDatabaseNames(WebIDBCallbacks*, const WebSecurityOrigin&, WebFrame*, const WebString& dataDir); 48 virtual void open(const WebString& name, long long version, WebIDBCallbacks*, const WebSecurityOrigin&, WebFrame*, const WebString& dataDir);48 virtual void open(const WebString& name, long long version, WebIDBCallbacks*, WebIDBDatabaseCallbacks*, const WebSecurityOrigin&, WebFrame*, const WebString& dataDir); 49 49 virtual void deleteDatabase(const WebString& name, WebIDBCallbacks*, const WebSecurityOrigin&, WebFrame*, const WebString& dataDir); 50 50 -
trunk/Source/WebKit/chromium/tests/IDBAbortOnCorruptTest.cpp
r128496 r128533 27 27 #include "IDBCursorBackendInterface.h" 28 28 #include "IDBDatabaseBackendInterface.h" 29 #include "IDBDatabaseCallbacks.h" 29 30 #include "IDBFactoryBackendImpl.h" 30 31 #include "IDBFakeBackingStore.h" … … 97 98 }; 98 99 100 class FakeIDBDatabaseCallbacks : public IDBDatabaseCallbacks { 101 public: 102 static PassRefPtr<FakeIDBDatabaseCallbacks> create() { return adoptRef(new FakeIDBDatabaseCallbacks()); } 103 virtual ~FakeIDBDatabaseCallbacks() { } 104 virtual void onVersionChange(const String& version) OVERRIDE { } 105 virtual void onVersionChange(int64_t oldVersion, int64_t newVersion) OVERRIDE { } 106 virtual void onForcedClose() OVERRIDE { } 107 private: 108 FakeIDBDatabaseCallbacks() { } 109 }; 110 99 111 TEST(IDBAbortTest, TheTest) 100 112 { … … 102 114 const String& name = "db name"; 103 115 MockIDBCallbacks callbacks; 116 RefPtr<FakeIDBDatabaseCallbacks> databaseCallbacks = FakeIDBDatabaseCallbacks::create(); 104 117 RefPtr<SecurityOrigin> origin = SecurityOrigin::create("http", "localhost", 81); 105 118 const int64_t DummyVersion = 2; 106 factory->open(name, DummyVersion, &callbacks, origin, 0 /*Frame*/, String() /*path*/);119 factory->open(name, DummyVersion, &callbacks, databaseCallbacks, origin, 0 /*Frame*/, String() /*path*/); 107 120 } 108 121 -
trunk/Source/WebKit/chromium/tests/IDBDatabaseBackendTest.cpp
r128496 r128533 28 28 #include "IDBCursorBackendInterface.h" 29 29 #include "IDBDatabaseBackendImpl.h" 30 #include "IDBDatabaseCallbacksProxy.h" 30 31 #include "IDBFactoryBackendImpl.h" 31 32 #include "IDBFakeBackingStore.h" … … 41 42 42 43 using namespace WebCore; 44 using WebKit::IDBDatabaseCallbacksProxy; 43 45 using WebKit::WebIDBDatabase; 46 using WebKit::WebIDBDatabaseImpl; 44 47 using WebKit::WebIDBDatabaseCallbacksImpl; 45 using WebKit::WebIDBDatabaseImpl;46 48 47 49 namespace { … … 123 125 124 126 RefPtr<MockIDBCallbacks> request1 = MockIDBCallbacks::create(); 125 db->openConnection(request1);126 127 127 RefPtr<FakeIDBDatabaseCallbacks> connection1 = FakeIDBDatabaseCallbacks::create(); 128 db-> registerFrontendCallbacks(connection1);128 db->openConnection(request1, connection1); 129 129 130 130 RefPtr<MockIDBCallbacks> request2 = MockIDBCallbacks::create(); 131 db->openConnection(request2); 131 RefPtr<FakeIDBDatabaseCallbacks> connection2 = FakeIDBDatabaseCallbacks::create(); 132 db->openConnection(request2, connection2); 132 133 133 134 db->close(connection1); 134 135 EXPECT_GT(backingStore->refCount(), 1); 135 136 RefPtr<FakeIDBDatabaseCallbacks> connection2 = FakeIDBDatabaseCallbacks::create();137 db->registerFrontendCallbacks(connection2);138 136 139 137 db->close(connection2); … … 150 148 ~MockIDBDatabaseBackendProxy() 151 149 { 152 EXPECT_TRUE(m_was RegisterFrontendCallbacksCalled);150 EXPECT_TRUE(m_wasCloseCalled); 153 151 } 154 152 … … 164 162 m_webDatabase.close(); 165 163 } 166 virtual void registerFrontendCallbacks(PassRefPtr<IDBDatabaseCallbacks> connection)167 {168 m_wasRegisterFrontendCallbacksCalled = true;169 m_webDatabase.open(new WebIDBDatabaseCallbacksImpl(connection));170 }171 164 172 165 private: 173 166 MockIDBDatabaseBackendProxy(WebIDBDatabaseImpl& webDatabase) 174 : m_wasRegisterFrontendCallbacksCalled(false) 175 , m_wasCloseCalled(false) 167 : m_wasCloseCalled(false) 176 168 , m_webDatabase(webDatabase) { } 177 169 178 bool m_wasRegisterFrontendCallbacksCalled;179 170 bool m_wasCloseCalled; 180 171 … … 192 183 EXPECT_GT(backingStore->refCount(), 1); 193 184 194 WebIDBDatabaseImpl webDatabase(backend); 195 196 RefPtr<MockIDBCallbacks> request1 = MockIDBCallbacks::create(); 197 backend->openConnection(request1); 185 RefPtr<FakeIDBDatabaseCallbacks> connection = FakeIDBDatabaseCallbacks::create(); 186 RefPtr<IDBDatabaseCallbacksProxy> connectionProxy = IDBDatabaseCallbacksProxy::create(adoptPtr(new WebIDBDatabaseCallbacksImpl(connection))); 187 WebIDBDatabaseImpl webDatabase(backend, connectionProxy); 198 188 199 189 RefPtr<MockIDBDatabaseBackendProxy> proxy = MockIDBDatabaseBackendProxy::create(webDatabase); 190 RefPtr<MockIDBCallbacks> request = MockIDBCallbacks::create(); 191 backend->openConnection(request, connectionProxy); 200 192 201 193 ScriptExecutionContext* context = 0; 202 RefPtr<IDBDatabase> idbDatabase = IDBDatabase::create(context, proxy); 203 idbDatabase->registerFrontendCallbacks(); 194 RefPtr<IDBDatabase> idbDatabase = IDBDatabase::create(context, proxy, connection); 204 195 205 196 webDatabase.forceClose(); 197 206 198 EXPECT_TRUE(backingStore->hasOneRef()); 207 199 }
Note: See TracChangeset
for help on using the changeset viewer.