Log Message
[Chromium] IndexedDB: Don't close database if pending connections are in flight https://bugs.webkit.org/show_bug.cgi?id=89512
Source/WebCore: Add a counter tracking connections between the two phases, which is used along with the completed connection count to determine the total number of connections. Reviewed by Tony Chang. Test: webkit_unit_tests --gtest_filter='IDBDatabaseBackendTest.ConnectionLifecycle' * Modules/indexeddb/IDBDatabaseBackendImpl.cpp: (WebCore::IDBDatabaseBackendImpl::IDBDatabaseBackendImpl): (WebCore::IDBDatabaseBackendImpl::setVersion): (WebCore::IDBDatabaseBackendImpl::connectionCount): (WebCore): (WebCore::IDBDatabaseBackendImpl::processPendingCalls): (WebCore::IDBDatabaseBackendImpl::transaction): (WebCore::IDBDatabaseBackendImpl::registerFrontendCallbacks): (WebCore::IDBDatabaseBackendImpl::openConnection): (WebCore::IDBDatabaseBackendImpl::close): * Modules/indexeddb/IDBDatabaseBackendImpl.h: (IDBDatabaseBackendImpl): * Modules/indexeddb/IDBFactoryBackendImpl.cpp: (WebCore::IDBFactoryBackendImpl::openInternal): * inspector/InspectorIndexedDBAgent.cpp: (WebCore): Source/WebKit/chromium: Reviewed by Tony Chang. * tests/IDBDatabaseBackendTest.cpp: (MockIDBCallbacks): (WebCore::MockIDBCallbacks::create): (WebCore::MockIDBCallbacks::MockIDBCallbacks): (WebCore): (FakeIDBDatabaseCallbacks): (WebCore::FakeIDBDatabaseCallbacks::create): (WebCore::FakeIDBDatabaseCallbacks::FakeIDBDatabaseCallbacks): (WebCore::TEST):
Modified Paths
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp
- trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.h
- trunk/Source/WebCore/Modules/indexeddb/IDBFactoryBackendImpl.cpp
- trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp
- trunk/Source/WebKit/chromium/ChangeLog
- trunk/Source/WebKit/chromium/tests/IDBDatabaseBackendTest.cpp
Diff
Modified: trunk/Source/WebCore/ChangeLog (120827 => 120828)
--- trunk/Source/WebCore/ChangeLog 2012-06-20 16:15:23 UTC (rev 120827)
+++ trunk/Source/WebCore/ChangeLog 2012-06-20 16:17:50 UTC (rev 120828)
@@ -1,3 +1,32 @@
+2012-06-20 Joshua Bell <[email protected]>
+
+ [Chromium] IndexedDB: Don't close database if pending connections are in flight
+ https://bugs.webkit.org/show_bug.cgi?id=89512
+
+ Add a counter tracking connections between the two phases, which is used along with
+ the completed connection count to determine the total number of connections.
+
+ Reviewed by Tony Chang.
+
+ Test: webkit_unit_tests --gtest_filter='IDBDatabaseBackendTest.ConnectionLifecycle'
+
+ * Modules/indexeddb/IDBDatabaseBackendImpl.cpp:
+ (WebCore::IDBDatabaseBackendImpl::IDBDatabaseBackendImpl):
+ (WebCore::IDBDatabaseBackendImpl::setVersion):
+ (WebCore::IDBDatabaseBackendImpl::connectionCount):
+ (WebCore):
+ (WebCore::IDBDatabaseBackendImpl::processPendingCalls):
+ (WebCore::IDBDatabaseBackendImpl::transaction):
+ (WebCore::IDBDatabaseBackendImpl::registerFrontendCallbacks):
+ (WebCore::IDBDatabaseBackendImpl::openConnection):
+ (WebCore::IDBDatabaseBackendImpl::close):
+ * Modules/indexeddb/IDBDatabaseBackendImpl.h:
+ (IDBDatabaseBackendImpl):
+ * Modules/indexeddb/IDBFactoryBackendImpl.cpp:
+ (WebCore::IDBFactoryBackendImpl::openInternal):
+ * inspector/InspectorIndexedDBAgent.cpp:
+ (WebCore):
+
2012-06-20 Sergey Rogulenko <[email protected]>
Web Inspector: duplicating selected text when Enter key is pressed
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp (120827 => 120828)
--- trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp 2012-06-20 16:15:23 UTC (rev 120827)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp 2012-06-20 16:17:50 UTC (rev 120828)
@@ -109,6 +109,7 @@
, m_identifier(uniqueIdentifier)
, m_factory(factory)
, m_transactionCoordinator(coordinator)
+ , m_pendingConnectionCount(0)
{
ASSERT(!m_name.isNull());
}
@@ -222,7 +223,7 @@
// FIXME: Only fire onBlocked if there are open connections after the
// VersionChangeEvents are received, not just set up to fire.
// https://bugs.webkit.org/show_bug.cgi?id=71130
- if (m_databaseCallbacksSet.size() > 1) {
+ if (connectionCount() > 1) {
callbacks->onBlocked();
RefPtr<PendingSetVersionCall> pendingSetVersionCall = PendingSetVersionCall::create(version, callbacks, databaseCallbacks);
m_pendingSetVersionCalls.append(pendingSetVersionCall);
@@ -278,9 +279,14 @@
}
}
+int32_t IDBDatabaseBackendImpl::connectionCount()
+{
+ return m_databaseCallbacksSet.size() + m_pendingConnectionCount;
+}
+
void IDBDatabaseBackendImpl::processPendingCalls()
{
- ASSERT(m_databaseCallbacksSet.size() <= 1);
+ ASSERT(connectionCount() <= 1);
// Pending calls may be requeued or aborted
Deque<RefPtr<PendingSetVersionCall> > pendingSetVersionCalls;
@@ -345,18 +351,24 @@
void IDBDatabaseBackendImpl::registerFrontendCallbacks(PassRefPtr<IDBDatabaseCallbacks> callbacks)
{
+ ASSERT(m_backingStore.get());
+ ASSERT(m_pendingConnectionCount);
+ --m_pendingConnectionCount;
m_databaseCallbacksSet.add(RefPtr<IDBDatabaseCallbacks>(callbacks));
}
void IDBDatabaseBackendImpl::openConnection(PassRefPtr<IDBCallbacks> callbacks)
{
+ ASSERT(m_backingStore.get());
if (!m_pendingDeleteCalls.isEmpty() || m_runningVersionChangeTransaction || !m_pendingSetVersionCalls.isEmpty())
m_pendingOpenCalls.append(PendingOpenCall::create(callbacks));
else {
if (m_id == InvalidId && !openInternal())
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error."));
- else
+ else {
+ ++m_pendingConnectionCount;
callbacks->onSuccess(this);
+ }
}
}
@@ -395,12 +407,12 @@
RefPtr<IDBDatabaseCallbacks> callbacks = prpCallbacks;
ASSERT(m_databaseCallbacksSet.contains(callbacks));
m_databaseCallbacksSet.remove(callbacks);
- if (m_databaseCallbacksSet.size() > 1)
+ if (connectionCount() > 1)
return;
processPendingCalls();
- if (!m_databaseCallbacksSet.size()) {
+ if (!connectionCount()) {
TransactionSet transactions(m_transactions);
for (TransactionSet::const_iterator it = transactions.begin(); it != transactions.end(); ++it)
(*it)->abort();
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.h (120827 => 120828)
--- trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.h 2012-06-20 16:15:23 UTC (rev 120827)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.h 2012-06-20 16:17:50 UTC (rev 120828)
@@ -78,6 +78,7 @@
bool openInternal();
void loadObjectStores();
+ int32_t connectionCount();
void processPendingCalls();
static void createObjectStoreInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl>, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBTransactionBackendInterface>);
@@ -116,6 +117,10 @@
class PendingDeleteCall;
Deque<RefPtr<PendingDeleteCall> > m_pendingDeleteCalls;
+ // FIXME: Eliminate the limbo state between openConnection() and registerFrontendCallbacks()
+ // that this counter tracks.
+ int32_t m_pendingConnectionCount;
+
typedef ListHashSet<RefPtr<IDBDatabaseCallbacks> > DatabaseCallbacksSet;
DatabaseCallbacksSet m_databaseCallbacksSet;
};
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBFactoryBackendImpl.cpp (120827 => 120828)
--- trunk/Source/WebCore/Modules/indexeddb/IDBFactoryBackendImpl.cpp 2012-06-20 16:15:23 UTC (rev 120827)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBFactoryBackendImpl.cpp 2012-06-20 16:17:50 UTC (rev 120828)
@@ -182,8 +182,8 @@
RefPtr<IDBDatabaseBackendImpl> databaseBackend = IDBDatabaseBackendImpl::create(name, backingStore.get(), m_transactionCoordinator.get(), this, uniqueIdentifier);
if (databaseBackend) {
- callbacks->onSuccess(RefPtr<IDBDatabaseBackendInterface>(databaseBackend.get()).release());
m_databaseBackendMap.set(uniqueIdentifier, databaseBackend.get());
+ databaseBackend->openConnection(callbacks);
} else
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error."));
}
Modified: trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp (120827 => 120828)
--- trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp 2012-06-20 16:15:23 UTC (rev 120827)
+++ trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp 2012-06-20 16:17:50 UTC (rev 120828)
@@ -43,6 +43,7 @@
#include "IDBCallbacks.h"
#include "IDBCursor.h"
#include "IDBDatabaseBackendInterface.h"
+#include "IDBDatabaseCallbacks.h"
#include "IDBFactoryBackendInterface.h"
#include "IDBIndexBackendInterface.h"
#include "IDBKey.h"
@@ -115,6 +116,21 @@
virtual void onBlocked() { }
};
+class InspectorIDBDatabaseCallbacks : public IDBDatabaseCallbacks {
+public:
+ static PassRefPtr<InspectorIDBDatabaseCallbacks> create()
+ {
+ return adoptRef(new InspectorIDBDatabaseCallbacks());
+ }
+
+ virtual ~InspectorIDBDatabaseCallbacks() { }
+
+ virtual void onVersionChange(const String& version) { }
+private:
+ InspectorIDBDatabaseCallbacks() { }
+};
+
+
class InspectorIDBTransactionCallback : public IDBTransactionCallbacks {
public:
static PassRefPtr<InspectorIDBTransactionCallback> create()
@@ -172,6 +188,28 @@
virtual void execute(PassRefPtr<IDBDatabaseBackendInterface>) = 0;
};
+class DatabaseConnection {
+public:
+ DatabaseConnection()
+ : m_idbDatabaseCallbacks(InspectorIDBDatabaseCallbacks::create()) { }
+
+ void connect(PassRefPtr<IDBDatabaseBackendInterface> idbDatabase)
+ {
+ m_idbDatabase = idbDatabase;
+ m_idbDatabase->registerFrontendCallbacks(m_idbDatabaseCallbacks);
+ }
+
+ ~DatabaseConnection()
+ {
+ if (m_idbDatabase)
+ m_idbDatabase->close(m_idbDatabaseCallbacks);
+ }
+
+private:
+ RefPtr<IDBDatabaseBackendInterface> m_idbDatabase;
+ RefPtr<IDBDatabaseCallbacks> m_idbDatabaseCallbacks;
+};
+
class OpenDatabaseCallback : public InspectorIDBCallback {
public:
static PassRefPtr<OpenDatabaseCallback> create(ExecutableWithDatabase* executableWithDatabase)
@@ -181,8 +219,9 @@
virtual ~OpenDatabaseCallback() { }
- virtual void onSuccess(PassRefPtr<IDBDatabaseBackendInterface> idbDatabase)
+ virtual void onSuccess(PassRefPtr<IDBDatabaseBackendInterface> prpDatabase)
{
+ RefPtr<IDBDatabaseBackendInterface> idbDatabase = prpDatabase;
m_executableWithDatabase->execute(idbDatabase);
}
@@ -263,8 +302,10 @@
virtual ~DatabaseLoaderCallback() { }
- virtual void execute(PassRefPtr<IDBDatabaseBackendInterface> idbDatabase)
+ virtual void execute(PassRefPtr<IDBDatabaseBackendInterface> prpDatabase)
{
+ RefPtr<IDBDatabaseBackendInterface> idbDatabase = prpDatabase;
+ m_connection.connect(idbDatabase);
if (!m_frontendProvider->frontend())
return;
@@ -315,6 +356,7 @@
, m_requestId(requestId) { }
RefPtr<InspectorIndexedDBAgent::FrontendProvider> m_frontendProvider;
int m_requestId;
+ DatabaseConnection m_connection;
};
static PassRefPtr<IDBKey> idbKeyFromInspectorObject(InspectorObject* key)
@@ -430,6 +472,8 @@
return key.release();
}
+class DataLoaderCallback;
+
class OpenCursorCallback : public InspectorIDBCallback {
public:
enum CursorType {
@@ -437,9 +481,9 @@
IndexDataCursor
};
- static PassRefPtr<OpenCursorCallback> create(PassRefPtr<InspectorIndexedDBAgent::FrontendProvider> frontendProvider, InjectedScript injectedScript, PassRefPtr<IDBTransactionBackendInterface> idbTransaction, CursorType cursorType, int requestId, int skipCount, unsigned pageSize)
+ static PassRefPtr<OpenCursorCallback> create(PassRefPtr<InspectorIndexedDBAgent::FrontendProvider> frontendProvider, InjectedScript injectedScript, PassRefPtr<DataLoaderCallback> dataLoaderCallback, PassRefPtr<IDBTransactionBackendInterface> idbTransaction, CursorType cursorType, int requestId, int skipCount, unsigned pageSize)
{
- return adoptRef(new OpenCursorCallback(frontendProvider, injectedScript, idbTransaction, cursorType, requestId, skipCount, pageSize));
+ return adoptRef(new OpenCursorCallback(frontendProvider, injectedScript, dataLoaderCallback, idbTransaction, cursorType, requestId, skipCount, pageSize));
}
virtual ~OpenCursorCallback() { }
@@ -491,6 +535,7 @@
void end(bool hasMore)
{
+ m_dataLoaderCallback.clear();
if (!m_frontendProvider->frontend())
return;
@@ -509,9 +554,10 @@
}
private:
- OpenCursorCallback(PassRefPtr<InspectorIndexedDBAgent::FrontendProvider> frontendProvider, InjectedScript injectedScript, PassRefPtr<IDBTransactionBackendInterface> idbTransaction, CursorType cursorType, int requestId, int skipCount, unsigned pageSize)
+ OpenCursorCallback(PassRefPtr<InspectorIndexedDBAgent::FrontendProvider> frontendProvider, InjectedScript injectedScript, PassRefPtr<DataLoaderCallback> dataLoaderCallback, PassRefPtr<IDBTransactionBackendInterface> idbTransaction, CursorType cursorType, int requestId, int skipCount, unsigned pageSize)
: m_frontendProvider(frontendProvider)
, m_injectedScript(injectedScript)
+ , m_dataLoaderCallback(dataLoaderCallback)
, m_idbTransaction(idbTransaction)
, m_cursorType(cursorType)
, m_requestId(requestId)
@@ -523,6 +569,7 @@
}
RefPtr<InspectorIndexedDBAgent::FrontendProvider> m_frontendProvider;
InjectedScript m_injectedScript;
+ RefPtr<DataLoaderCallback> m_dataLoaderCallback;
RefPtr<IDBTransactionBackendInterface> m_idbTransaction;
CursorType m_cursorType;
int m_requestId;
@@ -541,8 +588,10 @@
virtual ~DataLoaderCallback() { }
- virtual void execute(PassRefPtr<IDBDatabaseBackendInterface> idbDatabase)
+ virtual void execute(PassRefPtr<IDBDatabaseBackendInterface> prpDatabase)
{
+ RefPtr<IDBDatabaseBackendInterface> idbDatabase = prpDatabase;
+ m_connection.connect(idbDatabase);
if (!m_frontendProvider->frontend())
return;
@@ -558,12 +607,12 @@
if (!idbIndex)
return;
- RefPtr<OpenCursorCallback> openCursorCallback = OpenCursorCallback::create(m_frontendProvider, m_injectedScript, idbTransaction.get(), OpenCursorCallback::IndexDataCursor, m_requestId, m_skipCount, m_pageSize);
+ RefPtr<OpenCursorCallback> openCursorCallback = OpenCursorCallback::create(m_frontendProvider, m_injectedScript, this, idbTransaction.get(), OpenCursorCallback::IndexDataCursor, m_requestId, m_skipCount, m_pageSize);
ExceptionCode ec = 0;
idbIndex->openCursor(m_idbKeyRange, IDBCursor::NEXT, openCursorCallback, idbTransaction.get(), ec);
} else {
- RefPtr<OpenCursorCallback> openCursorCallback = OpenCursorCallback::create(m_frontendProvider, m_injectedScript, idbTransaction.get(), OpenCursorCallback::ObjectStoreDataCursor, m_requestId, m_skipCount, m_pageSize);
+ RefPtr<OpenCursorCallback> openCursorCallback = OpenCursorCallback::create(m_frontendProvider, m_injectedScript, this, idbTransaction.get(), OpenCursorCallback::ObjectStoreDataCursor, m_requestId, m_skipCount, m_pageSize);
ExceptionCode ec = 0;
idbObjectStore->openCursor(m_idbKeyRange, IDBCursor::NEXT, openCursorCallback, idbTransaction.get(), ec);
@@ -588,6 +637,7 @@
RefPtr<IDBKeyRange> m_idbKeyRange;
int m_skipCount;
unsigned m_pageSize;
+ DatabaseConnection m_connection;
};
} // namespace
Modified: trunk/Source/WebKit/chromium/ChangeLog (120827 => 120828)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-06-20 16:15:23 UTC (rev 120827)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-06-20 16:17:50 UTC (rev 120828)
@@ -1,3 +1,20 @@
+2012-06-20 Joshua Bell <[email protected]>
+
+ [Chromium] IndexedDB: Don't close database if pending connections are in flight
+ https://bugs.webkit.org/show_bug.cgi?id=89512
+
+ Reviewed by Tony Chang.
+
+ * tests/IDBDatabaseBackendTest.cpp:
+ (MockIDBCallbacks):
+ (WebCore::MockIDBCallbacks::create):
+ (WebCore::MockIDBCallbacks::MockIDBCallbacks):
+ (WebCore):
+ (FakeIDBDatabaseCallbacks):
+ (WebCore::FakeIDBDatabaseCallbacks::create):
+ (WebCore::FakeIDBDatabaseCallbacks::FakeIDBDatabaseCallbacks):
+ (WebCore::TEST):
+
2012-06-20 Zeev Lieber <[email protected]>
[Chromium] Remove redundant #includes in compositor
Modified: trunk/Source/WebKit/chromium/tests/IDBDatabaseBackendTest.cpp (120827 => 120828)
--- trunk/Source/WebKit/chromium/tests/IDBDatabaseBackendTest.cpp 2012-06-20 16:15:23 UTC (rev 120827)
+++ trunk/Source/WebKit/chromium/tests/IDBDatabaseBackendTest.cpp 2012-06-20 16:17:50 UTC (rev 120828)
@@ -67,6 +67,70 @@
EXPECT_TRUE(backingStore->hasOneRef());
}
+class MockIDBCallbacks : public IDBCallbacks {
+public:
+ static PassRefPtr<MockIDBCallbacks> create() { return adoptRef(new MockIDBCallbacks()); }
+ virtual ~MockIDBCallbacks() OVERRIDE
+ {
+ EXPECT_TRUE(m_wasSuccessDBCalled);
+ }
+ virtual void onError(PassRefPtr<IDBDatabaseError>) OVERRIDE { }
+ virtual void onSuccess(PassRefPtr<DOMStringList>) OVERRIDE { }
+ virtual void onSuccess(PassRefPtr<IDBCursorBackendInterface>) OVERRIDE { }
+ virtual void onSuccess(PassRefPtr<IDBDatabaseBackendInterface>) OVERRIDE
+ {
+ m_wasSuccessDBCalled = true;
+ }
+ virtual void onSuccess(PassRefPtr<IDBKey>) OVERRIDE { }
+ virtual void onSuccess(PassRefPtr<IDBTransactionBackendInterface>) OVERRIDE { }
+ virtual void onSuccess(PassRefPtr<SerializedScriptValue>) OVERRIDE { }
+ virtual void onSuccessWithContinuation() OVERRIDE { }
+ virtual void onSuccessWithPrefetch(const Vector<RefPtr<IDBKey> >&, const Vector<RefPtr<IDBKey> >&, const Vector<RefPtr<SerializedScriptValue> >&) OVERRIDE { }
+ virtual void onBlocked() OVERRIDE { }
+private:
+ MockIDBCallbacks()
+ : m_wasSuccessDBCalled(false) { }
+ bool m_wasSuccessDBCalled;
+};
+
+class FakeIDBDatabaseCallbacks : public IDBDatabaseCallbacks {
+public:
+ static PassRefPtr<FakeIDBDatabaseCallbacks> create() { return adoptRef(new FakeIDBDatabaseCallbacks()); }
+ virtual ~FakeIDBDatabaseCallbacks() OVERRIDE { }
+ virtual void onVersionChange(const String& version) OVERRIDE { }
+private:
+ FakeIDBDatabaseCallbacks() { }
+};
+
+TEST(IDBDatabaseBackendTest, ConnectionLifecycle)
+{
+ RefPtr<IDBFakeBackingStore> backingStore = adoptRef(new IDBFakeBackingStore());
+ EXPECT_TRUE(backingStore->hasOneRef());
+
+ IDBTransactionCoordinator* coordinator = 0;
+ IDBFactoryBackendImpl* factory = 0;
+ RefPtr<IDBDatabaseBackendImpl> db = IDBDatabaseBackendImpl::create("db", backingStore.get(), coordinator, factory, "uniqueid");
+ EXPECT_GT(backingStore->refCount(), 1);
+
+ RefPtr<MockIDBCallbacks> request1 = MockIDBCallbacks::create();
+ db->openConnection(request1);
+
+ RefPtr<FakeIDBDatabaseCallbacks> connection1 = FakeIDBDatabaseCallbacks::create();
+ db->registerFrontendCallbacks(connection1);
+
+ RefPtr<MockIDBCallbacks> request2 = MockIDBCallbacks::create();
+ db->openConnection(request2);
+
+ db->close(connection1);
+ EXPECT_GT(backingStore->refCount(), 1);
+
+ RefPtr<FakeIDBDatabaseCallbacks> connection2 = FakeIDBDatabaseCallbacks::create();
+ db->registerFrontendCallbacks(connection2);
+
+ db->close(connection2);
+ EXPECT_TRUE(backingStore->hasOneRef());
+}
+
} // namespace
#endif // ENABLE(INDEXED_DATABASE)
_______________________________________________ webkit-changes mailing list [email protected] http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes
