WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
79835
IndexedDB: Resource leak with IDBObjectStore.openCursor
https://bugs.webkit.org/show_bug.cgi?id=79835
Summary
IndexedDB: Resource leak with IDBObjectStore.openCursor
Joshua Bell
Reported
2012-02-28 14:35:35 PST
Created
attachment 129333
[details]
Repro case Run attached page. It will "leak" 123 of each of: IDBRequest: 123 IDBTransaction: 123 IDBCursorWithValue: 123 IDBTransactionBackendImpl: 123 IDBCursor: 123 IDBKey: 123 IDBObjectStore: 123 IDBCursorBackendImpl: 123 (The backend objects are reclaimed on app shutdown, so it's not a true memory leak.) After setting up a database with a single store, and (necessarily) a single record, the script runs: function runtest(db) { for (var i = 0; i < 123; ++i) { db.transaction('store', webkitIDBTransaction.READ_ONLY).objectStore('store').openCursor(); } done(); } done() just runs an explicit GC call to clean up temporary objects that aren't being leaked. The leak goes away if either (1) there are no records in the store, or (2) openCursor() is not called.
Attachments
Repro case
(971 bytes, text/html)
2012-02-28 14:35 PST
,
Joshua Bell
no flags
Details
Patch
(8.76 KB, patch)
2012-02-28 15:58 PST
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch
(12.13 KB, patch)
2012-02-28 17:18 PST
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Patch
(13.47 KB, patch)
2012-02-29 11:15 PST
,
Joshua Bell
no flags
Details
Formatted Diff
Diff
Show Obsolete
(2)
View All
Add attachment
proposed patch, testcase, etc.
Joshua Bell
Comment 1
2012-02-28 15:58:37 PST
Created
attachment 129346
[details]
Patch
David Grogan
Comment 2
2012-02-28 16:18:35 PST
Comment on
attachment 129346
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=129346&action=review
LGTM Hopefully this ref-counting spaghetti gets a bit untangled in idb.next.
> Source/WebCore/storage/IDBCursor.cpp:117 > + if (m_request && m_request->resetReadyState(m_transaction.get())) {
Similar question to below; m_request would only eval to false if continue() is called after close(), which I wouldn't have thought possible. Are there situations where that happens?
> Source/WebCore/storage/IDBCursor.cpp:143 > + if (m_request) {
This check seems to indicate that close can be called twice. When does that happen?
Joshua Bell
Comment 3
2012-02-28 16:27:04 PST
(In reply to
comment #2
)
> (From update of
attachment 129346
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=129346&action=review
> > LGTM > > Hopefully this ref-counting spaghetti gets a bit untangled in idb.next. > > > Source/WebCore/storage/IDBCursor.cpp:117 > > + if (m_request && m_request->resetReadyState(m_transaction.get())) { > > Similar question to below; m_request would only eval to false if continue() is called after close(), which I wouldn't have thought possible. Are there situations where that happens?
This can happen if the user retains a reference to the IDBCursor object but the transaction has finished. Once the transaction finishes, m_request will be cleared out (the new behavior). Previously, it would have called through to IDBCursorBackendImpl::continueFunction which would try and schedule a task against the transaction, which would fail with IDBDatabaseException::TRANSACTION_INACTIVE_ERR So... I should update this to fail early with that error instead if m_request is null. I'll add a test to verify the error.
> > Source/WebCore/storage/IDBCursor.cpp:143 > > + if (m_request) { > > This check seems to indicate that close can be called twice. When does that happen?
Ah, you're right, I can take that out.
Joshua Bell
Comment 4
2012-02-28 17:18:35 PST
Created
attachment 129359
[details]
Patch
Tony Chang
Comment 5
2012-02-28 17:30:46 PST
Comment on
attachment 129359
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=129359&action=review
> Source/WebCore/storage/IDBCursor.cpp:58 > + m_transaction->registerOpenCursor(this);
Is it possible to use a C++ class with scoping for this so you don't have to remember to call unregisterOpenCursor manually?
> Source/WebCore/storage/IDBTransaction.cpp:144 > + for (HashSet<IDBCursor*>::iterator i = cursors.begin(); i != cursors.end(); ++i) > + (*i)->close();
Does calling closeOpenCursors cause unregisterOpenCursor to be called? I guess at that point m_openCursors is an empty HashSet and remove just ignores the call?
Joshua Bell
Comment 6
2012-02-28 17:45:27 PST
(In reply to
comment #5
)
> (From update of
attachment 129359
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=129359&action=review
> > > Source/WebCore/storage/IDBCursor.cpp:58 > > + m_transaction->registerOpenCursor(this); > > Is it possible to use a C++ class with scoping for this so you don't have to remember to call unregisterOpenCursor manually? >
Yep. I was blindly following the pattern used in IDBTransactionBackendImpl but I agree RAII-style is cleaner. I'll update the patch.
> > Source/WebCore/storage/IDBTransaction.cpp:144 > > + for (HashSet<IDBCursor*>::iterator i = cursors.begin(); i != cursors.end(); ++i) > > + (*i)->close(); > > Does calling closeOpenCursors cause unregisterOpenCursor to be called? I guess at that point m_openCursors is an empty HashSet and remove just ignores the call?
It depends on whether there are requests in flight or if script holds any references. I used the swap pattern so such calls are safe.
Joshua Bell
Comment 7
2012-02-29 11:15:58 PST
Created
attachment 129480
[details]
Patch
WebKit Review Bot
Comment 8
2012-02-29 15:03:27 PST
Comment on
attachment 129480
[details]
Patch Clearing flags on attachment: 129480 Committed
r109271
: <
http://trac.webkit.org/changeset/109271
>
WebKit Review Bot
Comment 9
2012-02-29 15:03:31 PST
All reviewed patches have been landed. Closing bug.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug