зеркало из https://github.com/mozilla/gecko-dev.git
Bug 859591 - 'Aborted transactions sometimes block all remaining transactions forever'. r=khuey.
This commit is contained in:
Родитель
c6978dde42
Коммит
ebc89f5e51
|
@ -167,8 +167,7 @@ TransactionThreadPool::MaybeUnblockTransaction(nsPtrHashKey<TransactionInfo>* aK
|
|||
NS_ASSERTION(maybeUnblockedInfo->blockedOn.Contains(finishedInfo),
|
||||
"Huh?");
|
||||
maybeUnblockedInfo->blockedOn.RemoveEntry(finishedInfo);
|
||||
if (!maybeUnblockedInfo->blockedOn.Count() &&
|
||||
!maybeUnblockedInfo->transaction->IsAborted()) {
|
||||
if (!maybeUnblockedInfo->blockedOn.Count()) {
|
||||
// Let this transaction run.
|
||||
maybeUnblockedInfo->queue->Unblock();
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ MOCHITEST_FILES = \
|
|||
test_third_party.html \
|
||||
test_traffic_jam.html \
|
||||
test_transaction_abort.html \
|
||||
test_transaction_abort_hang.html \
|
||||
test_transaction_lifetimes.html \
|
||||
test_transaction_lifetimes_nested.html \
|
||||
test_transaction_ordering.html \
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Indexed Database Property 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" src="unit/test_transaction_abort_hang.js"></script>
|
||||
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="runTest();"></body>
|
||||
|
||||
</html>
|
|
@ -63,6 +63,7 @@ MOCHITEST_FILES = \
|
|||
test_success_events_after_abort.js \
|
||||
test_traffic_jam.js \
|
||||
test_transaction_abort.js \
|
||||
test_transaction_abort_hang.js \
|
||||
test_transaction_lifetimes.js \
|
||||
test_transaction_lifetimes_nested.js \
|
||||
test_transaction_ordering.js \
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
var self = this;
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const dbName = self.window ?
|
||||
window.location.pathname :
|
||||
"test_transaction_abort_hang";
|
||||
const objStoreName = "foo";
|
||||
const transactionCount = 30;
|
||||
|
||||
let completedTransactionCount = 0;
|
||||
let caughtError = false;
|
||||
|
||||
let abortedTransactionIndex = Math.floor(transactionCount / 2);
|
||||
if (abortedTransactionIndex % 2 == 0) {
|
||||
abortedTransactionIndex++;
|
||||
}
|
||||
|
||||
let request = indexedDB.open(dbName, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
||||
request.result.createObjectStore(objStoreName, { autoIncrement: true });
|
||||
|
||||
request.onupgradeneeded = null;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield;
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
for (let i = 0; i < transactionCount; i++) {
|
||||
const readonly = i % 2 == 0;
|
||||
const mode = readonly ? "readonly" : "readwrite";
|
||||
|
||||
let transaction = db.transaction(objStoreName, mode);
|
||||
|
||||
if (i == transactionCount - 1) {
|
||||
// Last one, finish the test.
|
||||
transaction.oncomplete = grabEventAndContinueHandler;
|
||||
} else if (i == abortedTransactionIndex - 1) {
|
||||
transaction.oncomplete = function(event) {
|
||||
ok(true, "Completed transaction " + ++completedTransactionCount +
|
||||
" (We may hang after this!)");
|
||||
};
|
||||
} else if (i == abortedTransactionIndex) {
|
||||
// Special transaction that we abort outside the normal event flow.
|
||||
transaction.onerror = function(event) {
|
||||
ok(true, "Aborted transaction " + ++completedTransactionCount +
|
||||
" (We didn't hang!)");
|
||||
is(event.target.error.name, "AbortError",
|
||||
"AbortError set as the error on the request");
|
||||
is(event.target.transaction.error, null,
|
||||
"No error set on the transaction");
|
||||
ok(!caughtError, "Haven't seen the error event yet");
|
||||
caughtError = true;
|
||||
event.preventDefault();
|
||||
};
|
||||
// This has to happen after the we return to the event loop but before the
|
||||
// transaction starts running.
|
||||
executeSoon(function() { transaction.abort(); });
|
||||
} else {
|
||||
transaction.oncomplete = function(event) {
|
||||
ok(true, "Completed transaction " + ++completedTransactionCount);
|
||||
};
|
||||
}
|
||||
|
||||
if (readonly) {
|
||||
transaction.objectStore(objStoreName).get(0);
|
||||
} else {
|
||||
try { transaction.objectStore(objStoreName).add({}); } catch(e) { }
|
||||
}
|
||||
}
|
||||
ok(true, "Created all transactions");
|
||||
|
||||
event = yield;
|
||||
|
||||
ok(true, "Completed transaction " + ++completedTransactionCount);
|
||||
ok(caughtError, "Caught the error event when we aborted the transaction");
|
||||
|
||||
finishTest();
|
||||
yield;
|
||||
}
|
|
@ -56,6 +56,7 @@ tail =
|
|||
[test_success_events_after_abort.js]
|
||||
[test_traffic_jam.js]
|
||||
[test_transaction_abort.js]
|
||||
[test_transaction_abort_hang.js]
|
||||
[test_transaction_lifetimes.js]
|
||||
[test_transaction_lifetimes_nested.js]
|
||||
[test_transaction_ordering.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче