mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 720679 - 'Crash @ WorkerPrivate::CancelAllTimeouts while closing Firefox'. r=khuey.
This commit is contained in:
parent
8df6eccad7
commit
f99b55852b
@ -3164,6 +3164,8 @@ WorkerPrivate::NotifyFeatures(JSContext* aCx, Status aStatus)
|
||||
void
|
||||
WorkerPrivate::CancelAllTimeouts(JSContext* aCx)
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
|
||||
if (mTimerRunning) {
|
||||
NS_ASSERTION(mTimer, "Huh?!");
|
||||
NS_ASSERTION(!mTimeouts.IsEmpty(), "Huh?!");
|
||||
@ -3176,13 +3178,19 @@ WorkerPrivate::CancelAllTimeouts(JSContext* aCx)
|
||||
mTimeouts[index]->mCanceled = true;
|
||||
}
|
||||
|
||||
RunExpiredTimeouts(aCx);
|
||||
if (!RunExpiredTimeouts(aCx)) {
|
||||
JS_ReportPendingException(aCx);
|
||||
}
|
||||
|
||||
mTimer = nsnull;
|
||||
mTimerRunning = false;
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
else if (!mRunningExpiredTimeouts) {
|
||||
NS_ASSERTION(mTimeouts.IsEmpty(), "Huh?!");
|
||||
}
|
||||
#endif
|
||||
|
||||
mTimer = nsnull;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
@ -3511,8 +3519,15 @@ WorkerPrivate::SetTimeout(JSContext* aCx, unsigned aArgc, jsval* aVp,
|
||||
currentStatus = mStatus;
|
||||
}
|
||||
|
||||
if (currentStatus > Running) {
|
||||
// It's a script bug if setTimeout/setInterval are called from a close handler
|
||||
// so throw an exception.
|
||||
if (currentStatus == Closing) {
|
||||
JS_ReportError(aCx, "Cannot schedule timeouts from the close handler!");
|
||||
}
|
||||
|
||||
// If the worker is trying to call setTimeout/setInterval and the parent
|
||||
// thread has initiated the close process then just silently fail.
|
||||
if (currentStatus >= Closing) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -3655,6 +3670,7 @@ WorkerPrivate::RunExpiredTimeouts(JSContext* aCx)
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mTimer, "Must have a timer!");
|
||||
NS_ASSERTION(!mTimeouts.IsEmpty(), "Should have some work to do!");
|
||||
|
||||
bool retval = true;
|
||||
@ -3719,12 +3735,16 @@ WorkerPrivate::RunExpiredTimeouts(JSContext* aCx)
|
||||
}
|
||||
}
|
||||
|
||||
NS_ASSERTION(mRunningExpiredTimeouts, "Someone changed this!");
|
||||
|
||||
// Reschedule intervals.
|
||||
if (info->mIsInterval) {
|
||||
if (info->mIsInterval && !info->mCanceled) {
|
||||
PRUint32 timeoutIndex = mTimeouts.IndexOf(info);
|
||||
NS_ASSERTION(timeoutIndex != PRUint32(-1),
|
||||
"Should still be in the main list!");
|
||||
|
||||
// This is nasty but we have to keep the old nsAutoPtr from deleting the
|
||||
// info we're about to re-add.
|
||||
mTimeouts[timeoutIndex].forget();
|
||||
mTimeouts.RemoveElementAt(timeoutIndex);
|
||||
|
||||
@ -3755,8 +3775,8 @@ WorkerPrivate::RunExpiredTimeouts(JSContext* aCx)
|
||||
}
|
||||
}
|
||||
|
||||
// Signal the parent that we're no longer using timeouts or reschedule the
|
||||
// timer.
|
||||
// Either signal the parent that we're no longer using timeouts or reschedule
|
||||
// the timer.
|
||||
if (mTimeouts.IsEmpty()) {
|
||||
if (!ModifyBusyCountFromWorker(aCx, false)) {
|
||||
retval = false;
|
||||
|
@ -56,6 +56,8 @@ _TEST_FILES = \
|
||||
test_atob.html \
|
||||
atob_worker.js \
|
||||
test_blobWorkers.html \
|
||||
test_clearTimeouts.html \
|
||||
clearTimeouts_worker.js \
|
||||
test_close.html \
|
||||
close_worker.js \
|
||||
test_closeOnGC.html \
|
||||
|
12
dom/workers/test/clearTimeouts_worker.js
Normal file
12
dom/workers/test/clearTimeouts_worker.js
Normal file
@ -0,0 +1,12 @@
|
||||
var count = 0;
|
||||
function timerFunction() {
|
||||
if (++count == 30) {
|
||||
close();
|
||||
postMessage("ready");
|
||||
while (true) { }
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < 10; i++) {
|
||||
setInterval(timerFunction, 500);
|
||||
}
|
30
dom/workers/test/test_clearTimeouts.html
Normal file
30
dom/workers/test/test_clearTimeouts.html
Normal file
@ -0,0 +1,30 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for DOM Worker Threads</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
new Worker("clearTimeouts_worker.js").onmessage = function(event) {
|
||||
event.target.terminate();
|
||||
|
||||
is(event.data, "ready", "Correct message");
|
||||
setTimeout(function() { SimpleTest.finish(); }, 1000);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user