Bug 1379243 P3 Rename WorkerControlEventTarget and make it support a "hybrid" dispatch mode. r=baku

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

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

@ -1612,15 +1612,21 @@ public:
nsresult
Cancel() override
{
// First run the default cancelation code
WorkerControlRunnable::Cancel();
// Attempt to cancel the inner runnable as well
nsCOMPtr<nsICancelableRunnable> cr = do_QueryInterface(mInner);
if (cr) {
return cr->Cancel();
// If the inner runnable is not cancellable, then just do the normal
// WorkerControlRunnable thing. This will end up calling Run().
if (!cr) {
WorkerControlRunnable::Cancel();
return NS_OK;
}
return NS_OK;
// Otherwise call the inner runnable's Cancel() and treat this like
// a WorkerRunnable cancel. We can't call WorkerControlRunnable::Cancel()
// in this case since that would result in both Run() and the inner
// Cancel() being called.
Unused << cr->Cancel();
return WorkerRunnable::Cancel();
}
};
@ -1628,17 +1634,36 @@ public:
BEGIN_WORKERS_NAMESPACE
class WorkerControlEventTarget final : public nsISerialEventTarget
class WorkerEventTarget final : public nsISerialEventTarget
{
public:
// The WorkerEventTarget supports different dispatch behaviors:
//
// * Hybrid targets will attempt to dispatch as a normal runnable,
// but fallback to a control runnable if that fails. This is
// often necessary for code that wants normal dispatch order, but
// also needs to execute while the worker is shutting down (possibly
// with a holder in place.)
//
// * ControlOnly targets will simply dispatch a control runnable.
enum class Behavior : uint8_t {
Hybrid,
ControlOnly
};
private:
mozilla::Mutex mMutex;
WorkerPrivate* mWorkerPrivate;
const Behavior mBehavior;
~WorkerControlEventTarget() = default;
~WorkerEventTarget() = default;
public:
explicit WorkerControlEventTarget(WorkerPrivate* aWorkerPrivate)
: mMutex("WorkerControlEventTarget")
WorkerEventTarget(WorkerPrivate* aWorkerPrivate,
Behavior aBehavior)
: mMutex("WorkerEventTarget")
, mWorkerPrivate(aWorkerPrivate)
, mBehavior(aBehavior)
{
MOZ_DIAGNOSTIC_ASSERT(mWorkerPrivate);
}
@ -1667,8 +1692,20 @@ public:
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIRunnable> runnable(aRunnable);
if (mBehavior == Behavior::Hybrid) {
RefPtr<WorkerRunnable> r =
mWorkerPrivate->MaybeWrapAsWorkerRunnable(runnable.forget());
if (r->Dispatch()) {
return NS_OK;
}
runnable = r.forget();
}
RefPtr<WorkerControlRunnable> r = new WrappedControlRunnable(mWorkerPrivate,
Move(aRunnable));
runnable.forget());
if (!r->Dispatch()) {
return NS_ERROR_FAILURE;
}
@ -1704,7 +1741,7 @@ public:
NS_DECL_THREADSAFE_ISUPPORTS
};
NS_IMPL_ISUPPORTS(WorkerControlEventTarget, nsIEventTarget,
NS_IMPL_ISUPPORTS(WorkerEventTarget, nsIEventTarget,
nsISerialEventTarget)
END_WORKERS_NAMESPACE
@ -4426,7 +4463,8 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
, mNumHoldersPreventingShutdownStart(0)
, mDebuggerEventLoopLevel(0)
, mMainThreadEventTarget(GetMainThreadEventTarget())
, mWorkerControlEventTarget(new WorkerControlEventTarget(this))
, mWorkerControlEventTarget(new WorkerEventTarget(this,
WorkerEventTarget::Behavior::ControlOnly))
, mErrorHandlerRecursionCount(0)
, mNextTimeoutId(1)
, mStatus(Pending)

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

@ -87,7 +87,7 @@ BEGIN_WORKERS_NAMESPACE
class AutoSyncLoopHolder;
class SharedWorker;
class ServiceWorkerClientInfo;
class WorkerControlEventTarget;
class WorkerEventTarget;
class WorkerControlRunnable;
class WorkerDebugger;
class WorkerPrivate;
@ -1004,7 +1004,7 @@ class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
uint32_t mDebuggerEventLoopLevel;
RefPtr<ThrottledEventQueue> mMainThreadThrottledEventQueue;
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
RefPtr<WorkerControlEventTarget> mWorkerControlEventTarget;
RefPtr<WorkerEventTarget> mWorkerControlEventTarget;
struct SyncLoopInfo
{