Bug 1379243 P4 Make worker EventTargetFor() return a "hybrid" WorkerEventTarget. r=baku

This commit is contained in:
Ben Kelly 2017-07-21 08:16:24 -07:00
Родитель 4bbd23623d
Коммит db5d0c6b04
3 изменённых файлов: 29 добавлений и 3 удалений

Просмотреть файл

@ -1672,7 +1672,7 @@ public:
ForgetWorkerPrivate(WorkerPrivate* aWorkerPrivate)
{
MutexAutoLock lock(mMutex);
MOZ_DIAGNOSTIC_ASSERT(mWorkerPrivate == aWorkerPrivate);
MOZ_DIAGNOSTIC_ASSERT(!mWorkerPrivate || mWorkerPrivate == aWorkerPrivate);
mWorkerPrivate = nullptr;
}
@ -4465,6 +4465,8 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
, mMainThreadEventTarget(GetMainThreadEventTarget())
, mWorkerControlEventTarget(new WorkerEventTarget(this,
WorkerEventTarget::Behavior::ControlOnly))
, mWorkerHybridEventTarget(new WorkerEventTarget(this,
WorkerEventTarget::Behavior::Hybrid))
, mErrorHandlerRecursionCount(0)
, mNextTimeoutId(1)
, mStatus(Pending)
@ -4527,6 +4529,12 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
WorkerPrivate::~WorkerPrivate()
{
mWorkerControlEventTarget->ForgetWorkerPrivate(this);
// We force the hybrid event target to forget the thread when we
// enter the Killing state, but we do it again here to be safe.
// Its possible that we may be created and destroyed without progressing
// to Killing via some obscure code path.
mWorkerHybridEventTarget->ForgetWorkerPrivate(this);
}
// static
@ -5234,6 +5242,12 @@ WorkerPrivate::ControlEventTarget()
return mWorkerControlEventTarget;
}
nsISerialEventTarget*
WorkerPrivate::HybridEventTarget()
{
return mWorkerHybridEventTarget;
}
void
WorkerPrivate::InitializeGCTimers()
{
@ -6197,6 +6211,12 @@ WorkerPrivate::NotifyInternal(JSContext* aCx, Status aStatus)
Close();
}
// Make sure the hybrid event target stops dispatching runnables
// once we reaching the killing state.
if (aStatus == Killing) {
mWorkerHybridEventTarget->ForgetWorkerPrivate(this);
}
eventTarget = mEventTarget;
}

Просмотреть файл

@ -1005,6 +1005,7 @@ class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
RefPtr<ThrottledEventQueue> mMainThreadThrottledEventQueue;
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
RefPtr<WorkerEventTarget> mWorkerControlEventTarget;
RefPtr<WorkerEventTarget> mWorkerHybridEventTarget;
struct SyncLoopInfo
{
@ -1464,6 +1465,11 @@ public:
nsISerialEventTarget*
ControlEventTarget();
// Get an event target that will attempt to dispatch a normal WorkerRunnable,
// but if that fails will then fall back to a control runnable.
nsISerialEventTarget*
HybridEventTarget();
private:
WorkerPrivate(WorkerPrivate* aParent,
const nsAString& aScriptURL, bool aIsChromeWorker,

Просмотреть файл

@ -72,7 +72,7 @@ using mozilla::dom::cache::CacheStorage;
using mozilla::ipc::PrincipalInfo;
WorkerGlobalScope::WorkerGlobalScope(WorkerPrivate* aWorkerPrivate)
: mSerialEventTarget(aWorkerPrivate->GetEventTarget())
: mSerialEventTarget(aWorkerPrivate->HybridEventTarget())
, mWindowInteractionsAllowed(0)
, mWorkerPrivate(aWorkerPrivate)
{
@ -860,7 +860,7 @@ ServiceWorkerGlobalScope::OpenWindowEnabled(JSContext* aCx, JSObject* aObj)
WorkerDebuggerGlobalScope::WorkerDebuggerGlobalScope(
WorkerPrivate* aWorkerPrivate)
: mWorkerPrivate(aWorkerPrivate)
, mSerialEventTarget(aWorkerPrivate->GetEventTarget())
, mSerialEventTarget(aWorkerPrivate->HybridEventTarget())
{
mWorkerPrivate->AssertIsOnWorkerThread();