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) ForgetWorkerPrivate(WorkerPrivate* aWorkerPrivate)
{ {
MutexAutoLock lock(mMutex); MutexAutoLock lock(mMutex);
MOZ_DIAGNOSTIC_ASSERT(mWorkerPrivate == aWorkerPrivate); MOZ_DIAGNOSTIC_ASSERT(!mWorkerPrivate || mWorkerPrivate == aWorkerPrivate);
mWorkerPrivate = nullptr; mWorkerPrivate = nullptr;
} }
@ -4465,6 +4465,8 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
, mMainThreadEventTarget(GetMainThreadEventTarget()) , mMainThreadEventTarget(GetMainThreadEventTarget())
, mWorkerControlEventTarget(new WorkerEventTarget(this, , mWorkerControlEventTarget(new WorkerEventTarget(this,
WorkerEventTarget::Behavior::ControlOnly)) WorkerEventTarget::Behavior::ControlOnly))
, mWorkerHybridEventTarget(new WorkerEventTarget(this,
WorkerEventTarget::Behavior::Hybrid))
, mErrorHandlerRecursionCount(0) , mErrorHandlerRecursionCount(0)
, mNextTimeoutId(1) , mNextTimeoutId(1)
, mStatus(Pending) , mStatus(Pending)
@ -4527,6 +4529,12 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
WorkerPrivate::~WorkerPrivate() WorkerPrivate::~WorkerPrivate()
{ {
mWorkerControlEventTarget->ForgetWorkerPrivate(this); 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 // static
@ -5234,6 +5242,12 @@ WorkerPrivate::ControlEventTarget()
return mWorkerControlEventTarget; return mWorkerControlEventTarget;
} }
nsISerialEventTarget*
WorkerPrivate::HybridEventTarget()
{
return mWorkerHybridEventTarget;
}
void void
WorkerPrivate::InitializeGCTimers() WorkerPrivate::InitializeGCTimers()
{ {
@ -6197,6 +6211,12 @@ WorkerPrivate::NotifyInternal(JSContext* aCx, Status aStatus)
Close(); Close();
} }
// Make sure the hybrid event target stops dispatching runnables
// once we reaching the killing state.
if (aStatus == Killing) {
mWorkerHybridEventTarget->ForgetWorkerPrivate(this);
}
eventTarget = mEventTarget; eventTarget = mEventTarget;
} }

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

@ -1005,6 +1005,7 @@ class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
RefPtr<ThrottledEventQueue> mMainThreadThrottledEventQueue; RefPtr<ThrottledEventQueue> mMainThreadThrottledEventQueue;
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget; nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
RefPtr<WorkerEventTarget> mWorkerControlEventTarget; RefPtr<WorkerEventTarget> mWorkerControlEventTarget;
RefPtr<WorkerEventTarget> mWorkerHybridEventTarget;
struct SyncLoopInfo struct SyncLoopInfo
{ {
@ -1464,6 +1465,11 @@ public:
nsISerialEventTarget* nsISerialEventTarget*
ControlEventTarget(); 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: private:
WorkerPrivate(WorkerPrivate* aParent, WorkerPrivate(WorkerPrivate* aParent,
const nsAString& aScriptURL, bool aIsChromeWorker, const nsAString& aScriptURL, bool aIsChromeWorker,

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

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