mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 823953: Improve sync queue handling. r=bent
--HG-- extra : rebase_source : 04c9eb2a7462d2c94c66b8126507fa690df0f13d
This commit is contained in:
parent
2123d3e0de
commit
4cc0a4aebc
@ -306,14 +306,15 @@ public:
|
||||
bool
|
||||
Dispatch(JSContext* aCx)
|
||||
{
|
||||
mSyncQueueKey = mWorkerPrivate->CreateNewSyncLoop();
|
||||
AutoSyncLoopHolder syncLoop(mWorkerPrivate);
|
||||
mSyncQueueKey = syncLoop.SyncQueueKey();
|
||||
|
||||
if (NS_FAILED(NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL))) {
|
||||
JS_ReportError(aCx, "Failed to dispatch to main thread!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return mWorkerPrivate->RunSyncLoop(aCx, mSyncQueueKey);
|
||||
return syncLoop.RunAndForget(aCx);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
|
@ -666,11 +666,11 @@ LoadAllScripts(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
NS_ASSERTION(!aLoadInfos.IsEmpty(), "Bad arguments!");
|
||||
|
||||
uint32_t syncQueueKey = aWorkerPrivate->CreateNewSyncLoop();
|
||||
AutoSyncLoopHolder syncLoop(aWorkerPrivate);
|
||||
|
||||
nsRefPtr<ScriptLoaderRunnable> loader =
|
||||
new ScriptLoaderRunnable(aWorkerPrivate, syncQueueKey, aLoadInfos,
|
||||
aIsWorkerScript);
|
||||
new ScriptLoaderRunnable(aWorkerPrivate, syncLoop.SyncQueueKey(),
|
||||
aLoadInfos, aIsWorkerScript);
|
||||
|
||||
NS_ASSERTION(aLoadInfos.IsEmpty(), "Should have swapped!");
|
||||
|
||||
@ -685,7 +685,7 @@ LoadAllScripts(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
|
||||
return false;
|
||||
}
|
||||
|
||||
return aWorkerPrivate->RunSyncLoop(aCx, syncQueueKey);
|
||||
return syncLoop.RunAndForget(aCx);
|
||||
}
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
@ -3390,7 +3390,7 @@ WorkerPrivate::RunSyncLoop(JSContext* aCx, uint32_t aSyncLoopKey)
|
||||
NS_ASSERTION(syncQueue->mQueue.IsEmpty(), "Unprocessed sync events!");
|
||||
|
||||
bool result = syncQueue->mResult;
|
||||
mSyncQueues.RemoveElementAt(aSyncLoopKey);
|
||||
DestroySyncLoop(aSyncLoopKey);
|
||||
|
||||
#ifdef DEBUG
|
||||
syncQueue = nullptr;
|
||||
@ -3424,6 +3424,14 @@ WorkerPrivate::StopSyncLoop(uint32_t aSyncLoopKey, bool aSyncResult)
|
||||
syncQueue->mComplete = true;
|
||||
}
|
||||
|
||||
void
|
||||
WorkerPrivate::DestroySyncLoop(uint32_t aSyncLoopKey)
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
|
||||
mSyncQueues.RemoveElementAt(aSyncLoopKey);
|
||||
}
|
||||
|
||||
bool
|
||||
WorkerPrivate::PostMessageToParent(JSContext* aCx, jsval aMessage,
|
||||
jsval aTransferable)
|
||||
|
@ -661,6 +661,9 @@ public:
|
||||
void
|
||||
StopSyncLoop(uint32_t aSyncLoopKey, bool aSyncResult);
|
||||
|
||||
void
|
||||
DestroySyncLoop(uint32_t aSyncLoopKey);
|
||||
|
||||
bool
|
||||
PostMessageToParent(JSContext* aCx, jsval aMessage,
|
||||
jsval transferable);
|
||||
@ -848,6 +851,42 @@ WorkerStructuredCloneCallbacks(bool aMainRuntime);
|
||||
JSStructuredCloneCallbacks*
|
||||
ChromeWorkerStructuredCloneCallbacks(bool aMainRuntime);
|
||||
|
||||
class AutoSyncLoopHolder
|
||||
{
|
||||
public:
|
||||
AutoSyncLoopHolder(WorkerPrivate* aWorkerPrivate)
|
||||
: mWorkerPrivate(aWorkerPrivate), mSyncLoopKey(UINT32_MAX)
|
||||
{
|
||||
mSyncLoopKey = mWorkerPrivate->CreateNewSyncLoop();
|
||||
}
|
||||
|
||||
~AutoSyncLoopHolder()
|
||||
{
|
||||
if (mWorkerPrivate) {
|
||||
mWorkerPrivate->StopSyncLoop(mSyncLoopKey, false);
|
||||
mWorkerPrivate->DestroySyncLoop(mSyncLoopKey);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
RunAndForget(JSContext* aCx)
|
||||
{
|
||||
WorkerPrivate* workerPrivate = mWorkerPrivate;
|
||||
mWorkerPrivate = nullptr;
|
||||
return workerPrivate->RunSyncLoop(aCx, mSyncLoopKey);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SyncQueueKey() const
|
||||
{
|
||||
return mSyncLoopKey;
|
||||
}
|
||||
|
||||
private:
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
uint32_t mSyncLoopKey;
|
||||
};
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
||||
#endif /* mozilla_dom_workers_workerprivate_h__ */
|
||||
|
@ -830,18 +830,15 @@ public:
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
mSyncQueueKey = mWorkerPrivate->CreateNewSyncLoop();
|
||||
AutoSyncLoopHolder syncLoop(mWorkerPrivate);
|
||||
mSyncQueueKey = syncLoop.SyncQueueKey();
|
||||
|
||||
if (NS_FAILED(NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL))) {
|
||||
JS_ReportError(aCx, "Failed to dispatch to main thread!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mWorkerPrivate->RunSyncLoop(aCx, mSyncQueueKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return syncLoop.RunAndForget(aCx);
|
||||
}
|
||||
|
||||
virtual nsresult
|
||||
@ -1707,10 +1704,13 @@ XMLHttpRequest::SendInternal(const nsAString& aStringBody,
|
||||
}
|
||||
|
||||
AutoUnpinXHR autoUnpin(this);
|
||||
Maybe<AutoSyncLoopHolder> autoSyncLoop;
|
||||
|
||||
uint32_t syncQueueKey = UINT32_MAX;
|
||||
if (mProxy->mIsSyncXHR) {
|
||||
syncQueueKey = mWorkerPrivate->CreateNewSyncLoop();
|
||||
bool isSyncXHR = mProxy->mIsSyncXHR;
|
||||
if (isSyncXHR) {
|
||||
autoSyncLoop.construct(mWorkerPrivate);
|
||||
syncQueueKey = autoSyncLoop.ref().SyncQueueKey();
|
||||
}
|
||||
|
||||
mProxy->mOuterChannelId++;
|
||||
@ -1724,16 +1724,24 @@ XMLHttpRequest::SendInternal(const nsAString& aStringBody,
|
||||
return;
|
||||
}
|
||||
|
||||
autoUnpin.Clear();
|
||||
if (!isSyncXHR) {
|
||||
autoUnpin.Clear();
|
||||
MOZ_ASSERT(autoSyncLoop.empty());
|
||||
return;
|
||||
}
|
||||
|
||||
// The event loop was spun above, make sure we aren't canceled already.
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (mProxy->mIsSyncXHR && !mWorkerPrivate->RunSyncLoop(cx, syncQueueKey)) {
|
||||
autoUnpin.Clear();
|
||||
|
||||
if (!autoSyncLoop.ref().RunAndForget(cx)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user