зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1379243 P3 Rename WorkerControlEventTarget and make it support a "hybrid" dispatch mode. r=baku
This commit is contained in:
Родитель
460403c359
Коммит
4bbd23623d
|
@ -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
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче