mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 957693: Fix a worker hang and other related bugs. r=bent
This commit is contained in:
parent
8267f04e5f
commit
45cb351d71
@ -177,6 +177,13 @@ private:
|
||||
virtual void
|
||||
PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate, bool aRunResult)
|
||||
MOZ_OVERRIDE;
|
||||
|
||||
NS_DECL_NSICANCELABLERUNNABLE
|
||||
|
||||
void
|
||||
ShutdownScriptLoader(JSContext* aCx,
|
||||
WorkerPrivate* aWorkerPrivate,
|
||||
bool aResult);
|
||||
};
|
||||
|
||||
class ScriptLoaderRunnable MOZ_FINAL : public WorkerFeature,
|
||||
@ -740,11 +747,26 @@ ScriptExecutorRunnable::PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
|
||||
}
|
||||
}
|
||||
|
||||
aWorkerPrivate->RemoveFeature(aCx, &mScriptLoader);
|
||||
aWorkerPrivate->StopSyncLoop(mSyncLoopTarget, result);
|
||||
ShutdownScriptLoader(aCx, aWorkerPrivate, result);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ScriptExecutorRunnable::Cancel()
|
||||
{
|
||||
ShutdownScriptLoader(mWorkerPrivate->GetJSContext(), mWorkerPrivate, false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ScriptExecutorRunnable::ShutdownScriptLoader(JSContext* aCx,
|
||||
WorkerPrivate* aWorkerPrivate,
|
||||
bool aResult)
|
||||
{
|
||||
aWorkerPrivate->RemoveFeature(aCx, &mScriptLoader);
|
||||
aWorkerPrivate->StopSyncLoop(mSyncLoopTarget, aResult);
|
||||
}
|
||||
|
||||
bool
|
||||
LoadAllScripts(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
|
||||
nsTArray<ScriptLoadInfo>& aLoadInfos, bool aIsWorkerScript)
|
||||
|
@ -1067,8 +1067,8 @@ public:
|
||||
: WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount),
|
||||
mStatus(aStatus)
|
||||
{
|
||||
MOZ_ASSERT(aStatus == Terminating || aStatus == Canceling ||
|
||||
aStatus == Killing);
|
||||
MOZ_ASSERT(aStatus == Closing || aStatus == Terminating ||
|
||||
aStatus == Canceling || aStatus == Killing);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -4873,11 +4873,26 @@ WorkerPrivate::RunCurrentSyncLoop()
|
||||
}
|
||||
|
||||
// Make sure that the stack didn't change underneath us.
|
||||
MOZ_ASSERT(!mSyncLoopStack.IsEmpty());
|
||||
MOZ_ASSERT(mSyncLoopStack.Length() - 1 == currentLoopIndex);
|
||||
MOZ_ASSERT(mSyncLoopStack[currentLoopIndex] == loopInfo);
|
||||
|
||||
// We're about to delete |loop|, stash its event target and result.
|
||||
return DestroySyncLoop(currentLoopIndex);
|
||||
}
|
||||
|
||||
bool
|
||||
WorkerPrivate::DestroySyncLoop(uint32_t aLoopIndex, nsIThreadInternal* aThread)
|
||||
{
|
||||
MOZ_ASSERT(!mSyncLoopStack.IsEmpty());
|
||||
MOZ_ASSERT(mSyncLoopStack.Length() - 1 == aLoopIndex);
|
||||
|
||||
if (!aThread) {
|
||||
nsCOMPtr<nsIThreadInternal> thread = do_QueryInterface(mThread);
|
||||
MOZ_ASSERT(thread);
|
||||
|
||||
aThread = thread.get();
|
||||
}
|
||||
|
||||
// We're about to delete the loop, stash its event target and result.
|
||||
SyncLoopInfo* loopInfo = mSyncLoopStack[aLoopIndex];
|
||||
nsIEventTarget* nestedEventTarget =
|
||||
loopInfo->mEventTarget->GetWeakNestedEventTarget();
|
||||
MOZ_ASSERT(nestedEventTarget);
|
||||
@ -4891,11 +4906,11 @@ WorkerPrivate::RunCurrentSyncLoop()
|
||||
MutexAutoLock lock(mMutex);
|
||||
#endif
|
||||
|
||||
// This will delete |loop|!
|
||||
mSyncLoopStack.RemoveElementAt(currentLoopIndex);
|
||||
// This will delete |loopInfo|!
|
||||
mSyncLoopStack.RemoveElementAt(aLoopIndex);
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(thread->PopEventQueue(nestedEventTarget)));
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aThread->PopEventQueue(nestedEventTarget)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ class nsIEventTarget;
|
||||
class nsIPrincipal;
|
||||
class nsIScriptContext;
|
||||
class nsIThread;
|
||||
class nsIThreadInternal;
|
||||
class nsITimer;
|
||||
class nsIURI;
|
||||
|
||||
@ -1098,6 +1099,9 @@ private:
|
||||
bool
|
||||
RunCurrentSyncLoop();
|
||||
|
||||
bool
|
||||
DestroySyncLoop(uint32_t aLoopIndex, nsIThreadInternal* aThread = nullptr);
|
||||
|
||||
void
|
||||
InitializeGCTimers();
|
||||
|
||||
@ -1157,10 +1161,13 @@ class AutoSyncLoopHolder
|
||||
{
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
nsCOMPtr<nsIEventTarget> mTarget;
|
||||
uint32_t mIndex;
|
||||
|
||||
public:
|
||||
AutoSyncLoopHolder(WorkerPrivate* aWorkerPrivate)
|
||||
: mWorkerPrivate(aWorkerPrivate), mTarget(aWorkerPrivate->CreateNewSyncLoop())
|
||||
: mWorkerPrivate(aWorkerPrivate)
|
||||
, mTarget(aWorkerPrivate->CreateNewSyncLoop())
|
||||
, mIndex(aWorkerPrivate->mSyncLoopStack.Length() - 1)
|
||||
{
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
@ -1170,6 +1177,7 @@ public:
|
||||
if (mWorkerPrivate) {
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
mWorkerPrivate->StopSyncLoop(mTarget, false);
|
||||
mWorkerPrivate->DestroySyncLoop(mIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -508,8 +508,8 @@ private:
|
||||
{
|
||||
MOZ_ASSERT(NS_FAILED(mErrorCode));
|
||||
|
||||
Throw(aCx, mErrorCode);
|
||||
}
|
||||
Throw(aCx, mErrorCode);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
@ -1807,14 +1807,6 @@ XMLHttpRequest::SendInternal(const nsAString& aStringBody,
|
||||
return;
|
||||
}
|
||||
|
||||
// If our sync XHR was canceled during the send call the worker is going
|
||||
// away. We have no idea how far through the send call we got. There may
|
||||
// be a ProxyCompleteRunnable in the sync loop, but rather than run the loop
|
||||
// to get it we just let our RAII helpers clean up.
|
||||
if (mCanceled) {
|
||||
return;
|
||||
}
|
||||
|
||||
autoUnpin.Clear();
|
||||
|
||||
if (!autoSyncLoop.ref().Run()) {
|
||||
|
Loading…
Reference in New Issue
Block a user