mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 932162 - dispatch IndexedDB FileInfo releases to the main thread. r=khuey
Try runs: Green run prior to b2g mochitest fix and assertion changes: https://tbpl.mozilla.org/?tree=Try&rev=b071f8ef9617 green runs with assertion changes, not b2g disabling: https://tbpl.mozilla.org/?tree=Try&rev=b071f8ef9617 green b2g run: https://tbpl.mozilla.org/?tree=Try&rev=67510897d368
This commit is contained in:
parent
3bfa666329
commit
2c593fddff
@ -10,11 +10,28 @@
|
||||
|
||||
USING_INDEXEDDB_NAMESPACE
|
||||
|
||||
namespace {
|
||||
|
||||
class CleanupFileRunnable MOZ_FINAL : public nsIRunnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
CleanupFileRunnable(FileManager* aFileManager, int64_t aFileId);
|
||||
|
||||
private:
|
||||
nsRefPtr<FileManager> mFileManager;
|
||||
int64_t mFileId;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// static
|
||||
FileInfo*
|
||||
FileInfo::Create(FileManager* aFileManager, int64_t aId)
|
||||
{
|
||||
NS_ASSERTION(aId > 0, "Wrong id!");
|
||||
MOZ_ASSERT(aId > 0, "Wrong id!");
|
||||
|
||||
if (aId <= INT16_MAX) {
|
||||
return new FileInfo16(aFileManager, aId);
|
||||
@ -98,16 +115,40 @@ FileInfo::UpdateReferences(mozilla::ThreadSafeAutoRefCnt& aRefCount,
|
||||
void
|
||||
FileInfo::Cleanup()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
nsRefPtr<CleanupFileRunnable> cleaner =
|
||||
new CleanupFileRunnable(mFileManager, Id());
|
||||
|
||||
if (quota::QuotaManager::IsShuttingDown()) {
|
||||
// IndexedDatabaseManager is main-thread only.
|
||||
if (!NS_IsMainThread()) {
|
||||
NS_DispatchToMainThread(cleaner);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::Get();
|
||||
NS_ASSERTION(mgr, "Shouldn't be null!");
|
||||
cleaner->Run();
|
||||
}
|
||||
|
||||
if (NS_FAILED(mgr->AsyncDeleteFile(mFileManager, Id()))) {
|
||||
CleanupFileRunnable::CleanupFileRunnable(FileManager* aFileManager,
|
||||
int64_t aFileId)
|
||||
: mFileManager(aFileManager), mFileId(aFileId)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(CleanupFileRunnable,
|
||||
nsIRunnable)
|
||||
|
||||
NS_IMETHODIMP
|
||||
CleanupFileRunnable::Run()
|
||||
{
|
||||
if (mozilla::dom::quota::QuotaManager::IsShuttingDown()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::Get();
|
||||
MOZ_ASSERT(mgr);
|
||||
|
||||
if (NS_FAILED(mgr->AsyncDeleteFile(mFileManager, mFileId))) {
|
||||
NS_WARNING("Failed to delete file asynchronously!");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
98
dom/indexedDB/test/blob_worker_crash_iframe.html
Normal file
98
dom/indexedDB/test/blob_worker_crash_iframe.html
Normal file
@ -0,0 +1,98 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Indexed Database Test</title>
|
||||
|
||||
<script type="text/javascript">
|
||||
function report(result) {
|
||||
var message = { source: "iframe" };
|
||||
message.result = result;
|
||||
window.parent.postMessage(message, "*");
|
||||
}
|
||||
|
||||
function runIndexedDBTest() {
|
||||
var db = null;
|
||||
|
||||
// Create the data-store
|
||||
function createDatastore() {
|
||||
try {
|
||||
var request = indexedDB.open(window.location.pathname, 1);
|
||||
request.onupgradeneeded = function(event) {
|
||||
event.target.result.createObjectStore("foo");
|
||||
}
|
||||
request.onsuccess = function(event) {
|
||||
db = event.target.result;
|
||||
createAndStoreBlob();
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
dump("EXCEPTION IN CREATION: " + e + "\n " + e.stack + "\n");
|
||||
report(false);
|
||||
}
|
||||
}
|
||||
|
||||
function createAndStoreBlob() {
|
||||
const BLOB_DATA = ["fun ", "times ", "all ", "around!"];
|
||||
var blob = new Blob(BLOB_DATA, { type: "text/plain" });
|
||||
var objectStore = db.transaction("foo", "readwrite").objectStore("foo");
|
||||
objectStore.add({ blob: blob }, 42).onsuccess = refetchBlob;
|
||||
}
|
||||
|
||||
function refetchBlob() {
|
||||
var foo = db.transaction("foo").objectStore("foo");
|
||||
foo.get(42).onsuccess = fetchedBlobCreateWorkerAndSendBlob;
|
||||
}
|
||||
|
||||
function fetchedBlobCreateWorkerAndSendBlob(event) {
|
||||
var idbBlob = event.target.result.blob;
|
||||
var compositeBlob = new Blob(['I like the following blob: ', idbBlob],
|
||||
{ type: "text/fancy" });
|
||||
|
||||
function workerScript() {
|
||||
onmessage = function(event) {
|
||||
// Save the Blob to the worker's global scope.
|
||||
self.holdOntoBlob = event.data;
|
||||
// Send any message so we can serialize and keep our runtime behaviour
|
||||
// consistent.
|
||||
postMessage('kung fu death grip established');
|
||||
}
|
||||
}
|
||||
|
||||
var url =
|
||||
URL.createObjectURL(new Blob(["(", workerScript.toSource(), ")()"]));
|
||||
|
||||
// Keep a reference to the worker on the window.
|
||||
var worker = window.worker = new Worker(url);
|
||||
worker.postMessage(compositeBlob);
|
||||
worker.onmessage = workerLatchedBlobDeleteFromDB;
|
||||
}
|
||||
|
||||
function workerLatchedBlobDeleteFromDB() {
|
||||
// Delete the reference to the Blob from the database leaving the worker
|
||||
// thread reference as the only live reference once a GC has cleaned
|
||||
// out our references that we sent to the worker. The page that owns
|
||||
// us triggers a GC just for that reason.
|
||||
var objectStore = db.transaction("foo", "readwrite").objectStore("foo");
|
||||
objectStore.delete(42).onsuccess = closeDBTellOwningThread;
|
||||
}
|
||||
|
||||
function closeDBTellOwningThread(event) {
|
||||
// Now that worker has latched the blob, clean up the database.
|
||||
db.close();
|
||||
db = null;
|
||||
report('ready');
|
||||
}
|
||||
|
||||
createDatastore();
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="runIndexedDBTest();">
|
||||
</body>
|
||||
|
||||
</html>
|
@ -2,6 +2,7 @@
|
||||
support-files =
|
||||
bfcache_iframe1.html
|
||||
bfcache_iframe2.html
|
||||
blob_worker_crash_iframe.html
|
||||
error_events_abort_transactions_iframe.html
|
||||
event_propagation_iframe.html
|
||||
exceptions_in_events_iframe.html
|
||||
@ -26,6 +27,7 @@ support-files =
|
||||
[test_bfcache.html]
|
||||
[test_blob_archive.html]
|
||||
[test_blob_simple.html]
|
||||
[test_blob_worker_crash.html]
|
||||
[test_clear.html]
|
||||
[test_complex_keyPaths.html]
|
||||
[test_count.html]
|
||||
|
62
dom/indexedDB/test/test_blob_worker_crash.html
Normal file
62
dom/indexedDB/test/test_blob_worker_crash.html
Normal file
@ -0,0 +1,62 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Indexed Database Blob Worker Crash Test</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="text/javascript;version=1.7">
|
||||
/*
|
||||
* This tests ensures that if the last live reference to a Blob is on the
|
||||
* worker and the database has already been shutdown, that there is no crash
|
||||
* when the owning page gets cleaned up which causes the termination of the
|
||||
* worker which in turn garbage collects during its shutdown.
|
||||
*
|
||||
* We do the IndexedDB stuff in the iframe so we can kill it as part of our
|
||||
* test. Doing it out here is no good.
|
||||
*/
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
info("Open iframe, wait for it to do its IndexedDB stuff.");
|
||||
|
||||
let iframe = document.getElementById("iframe1");
|
||||
window.addEventListener("message", grabEventAndContinueHandler, false);
|
||||
// Put it in a different origin to be safe
|
||||
//allowUnlimitedQuota("http://example.org/");
|
||||
iframe.src = //"http://example.org" +
|
||||
window.location.pathname.replace(
|
||||
"test_blob_worker_crash.html",
|
||||
"blob_worker_crash_iframe.html");
|
||||
|
||||
let event = yield unexpectedSuccessHandler;
|
||||
is(event.data.result, "ready", "worker initialized correctly");
|
||||
|
||||
info("Trigger a GC to clean-up the iframe's main-thread IndexedDB");
|
||||
scheduleGC();
|
||||
yield undefined;
|
||||
|
||||
info("Kill the iframe, forget about it, trigger a GC.");
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
iframe = null;
|
||||
scheduleGC();
|
||||
yield undefined;
|
||||
|
||||
info("If we are still alive, then we win!");
|
||||
ok('Did not crash / trigger an assert!');
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="runTest();"></body>
|
||||
<iframe id="iframe1"></iframe>
|
||||
</html>
|
@ -504,6 +504,7 @@
|
||||
"dom/indexedDB/test/test_autoIncrement_indexes.html": "Bug 931116, b2g desktop specific, initial triage",
|
||||
"dom/indexedDB/test/test_bfcache.html": "Bug 931116, b2g desktop specific, initial triage",
|
||||
"dom/indexedDB/test/test_blob_archive.html": "Bug 931116, b2g desktop specific, initial triage",
|
||||
"dom/indexedDB/test/test_blob_worker_crash.html": "Bug 931116, b2g desktop specific, bug 927889 still present",
|
||||
"dom/indexedDB/test/test_blob_simple.html": "Bug 931116, b2g desktop specific, initial triage",
|
||||
"dom/indexedDB/test/test_clear.html": "Bug 931116, b2g desktop specific, initial triage",
|
||||
"dom/indexedDB/test/test_complex_keyPaths.html": "Bug 931116, b2g desktop specific, initial triage",
|
||||
|
Loading…
Reference in New Issue
Block a user