IndexedDB: IDBRequest can be GCd during event dispatch
authorjsbell@chromium.org <jsbell@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Aug 2012 02:43:47 +0000 (02:43 +0000)
committerjsbell@chromium.org <jsbell@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Aug 2012 02:43:47 +0000 (02:43 +0000)
commit2d62545e33800dba9add8e5acc830fc5ed3b8c11
treed2d254730d76221a277bfd70af7e8abb66c37936
parent76faf321571ae8b7433efed2dc1059fab1fc02d0
IndexedDB: IDBRequest can be GCd during event dispatch
https://bugs.webkit.org/show_bug.cgi?id=94235

Reviewed by Ojan Vafai.

Source/WebCore:

Avoid a "race" where GC may attempt to reclaim IDB objects that are marked
"done" prior to the completion of the event dispatch. The script runtime
may decide to do a GC pass before calling the event handler, releasing the
object and turning the dispatch into a no-op.

This is a partial reversion (with renames, etc) of r123275, r124842,
and r121492. Added a new test, although it does not exercise the "race"
condition directly.

Test: storage/indexeddb/pending-activity.html
      storage/indexeddb/pending-activity-workers.html

* Modules/indexeddb/IDBCursor.cpp:
(WebCore::IDBCursor::close): Let the IDBRequest know it this cursor won't
make it fire again.
* Modules/indexeddb/IDBRequest.cpp:
(WebCore::IDBRequest::IDBRequest): Reintroduce "am I done?" flag.
(WebCore::IDBRequest::finishCursor): Cursors may fire events at the same
IDBRequest repeatedly, so we need to know when they're are really done.
(WebCore):
(WebCore::IDBRequest::hasPendingActivity): Test the flag.
(WebCore::IDBRequest::dispatchEvent): Set the flag.
* Modules/indexeddb/IDBRequest.h:
(IDBRequest):
* Modules/indexeddb/IDBTransaction.cpp:
(WebCore::IDBTransaction::IDBTransaction): Reintroduce "am I done?" flag.
(WebCore::IDBTransaction::hasPendingActivity): Test the flag.
(WebCore::IDBTransaction::dispatchEvent): Set the flag.
* Modules/indexeddb/IDBTransaction.h:

LayoutTests:

Release references to IDBRequest and IDBTransaction objects and force GC,
to ensure that pending events are still fired. (Doesn't exercise race
condition where GC is triggered by script during dispatch itself, though.)

* storage/indexeddb/pending-activity-expected.txt: Added.
* storage/indexeddb/pending-activity-workers-expected.txt: Added.
* storage/indexeddb/pending-activity-workers.html: Added.
* storage/indexeddb/pending-activity.html: Added.
* storage/indexeddb/resources/pending-activity.js: Added.
(test):
(prepareDatabase.request.onsuccess.request.onsuccess.request.onsuccess):
(prepareDatabase.request.onsuccess.request.onsuccess):
(prepareDatabase.request.onsuccess):
(prepareDatabase):
(testTransaction):
(transactionOnComplete):
(testRequest):
(requestOnSuccess):
(testCursorRequest):
(cursorRequestOnFirstSuccess):
(cursorRequestOnSecondSuccess):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@126254 268f45cc-cd09-0410-ab3c-d52691b4dbfc
12 files changed:
LayoutTests/ChangeLog
LayoutTests/storage/indexeddb/pending-activity-expected.txt [new file with mode: 0644]
LayoutTests/storage/indexeddb/pending-activity-workers-expected.txt [new file with mode: 0644]
LayoutTests/storage/indexeddb/pending-activity-workers.html [new file with mode: 0644]
LayoutTests/storage/indexeddb/pending-activity.html [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/pending-activity.js [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBCursor.cpp
Source/WebCore/Modules/indexeddb/IDBRequest.cpp
Source/WebCore/Modules/indexeddb/IDBRequest.h
Source/WebCore/Modules/indexeddb/IDBTransaction.cpp
Source/WebCore/Modules/indexeddb/IDBTransaction.h