Bug 1426467: Part 3: Create a WorkerRunnable subclass, WorkerDebuggeeRunnable, for runnables that could run debuggee JS. r=baku

Separating these runnables out under a separate subclass will let us delay their
delivery while the content window is paused in the debugger.

CancelingOnParentRunnable, used when the worker calls self.close(), to close the
worker from the parent thread, must also be a WorkerDebuggeeRunnable, since it
must be processed only after all prior messages/errors from the worker.

Depends on D9218

Differential Revision: https://phabricator.services.mozilla.com/D9219

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jim Blandy 2018-10-22 15:46:04 +00:00
Родитель 488ca4192a
Коммит 5ec6faca84
5 изменённых файлов: 63 добавлений и 10 удалений

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

@ -19,7 +19,7 @@ namespace dom {
MessageEventRunnable::MessageEventRunnable(WorkerPrivate* aWorkerPrivate,
TargetAndBusyBehavior aBehavior)
: WorkerRunnable(aWorkerPrivate, aBehavior)
: WorkerDebuggeeRunnable(aWorkerPrivate, aBehavior)
, StructuredCloneHolder(CloningSupported, TransferringSupported,
StructuredCloneScope::SameProcessDifferentThread)
{

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

@ -17,7 +17,7 @@ class DOMEventTargetHelper;
namespace dom {
class MessageEventRunnable final : public WorkerRunnable
class MessageEventRunnable final : public WorkerDebuggeeRunnable
, public StructuredCloneHolder
{
public:

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

@ -26,7 +26,7 @@ namespace dom {
namespace {
class ReportErrorRunnable final : public WorkerRunnable
class ReportErrorRunnable final : public WorkerDebuggeeRunnable
{
WorkerErrorReport mReport;
@ -159,7 +159,7 @@ public:
ReportErrorRunnable(WorkerPrivate* aWorkerPrivate,
const WorkerErrorReport& aReport)
: WorkerRunnable(aWorkerPrivate, ParentThreadUnchangedBusyCount),
: WorkerDebuggeeRunnable(aWorkerPrivate),
mReport(aReport)
{ }
@ -240,7 +240,7 @@ private:
}
};
class ReportGenericErrorRunnable final : public WorkerRunnable
class ReportGenericErrorRunnable final : public WorkerDebuggeeRunnable
{
public:
static void
@ -256,7 +256,7 @@ public:
private:
explicit ReportGenericErrorRunnable(WorkerPrivate* aWorkerPrivate)
: WorkerRunnable(aWorkerPrivate, ParentThreadUnchangedBusyCount)
: WorkerDebuggeeRunnable(aWorkerPrivate)
{
aWorkerPrivate->AssertIsOnWorkerThread();
}

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

@ -933,13 +933,13 @@ PRThreadFromThread(nsIThread* aThread)
// A runnable to cancel the worker from the parent thread when self.close() is
// called. This runnable is executed on the parent process in order to cancel
// the current runnable. It uses a normal WorkerRunnable in order to be sure
// that all the pending WorkerRunnables are executed before this.
class CancelingOnParentRunnable final : public WorkerRunnable
// the current runnable. It uses a normal WorkerDebuggeeRunnable in order to be sure
// that all the pending WorkerDebuggeeRunnables are executed before this.
class CancelingOnParentRunnable final : public WorkerDebuggeeRunnable
{
public:
explicit CancelingOnParentRunnable(WorkerPrivate* aWorkerPrivate)
: WorkerRunnable(aWorkerPrivate, ParentThreadUnchangedBusyCount)
: WorkerDebuggeeRunnable(aWorkerPrivate, ParentThreadUnchangedBusyCount)
{}
bool

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

@ -88,6 +88,21 @@ public:
return mCanceled != 0;
}
// True if this runnable is handled by running JavaScript in some global that
// could possibly be a debuggee, and thus needs to be deferred when the target
// is paused in the debugger, until the JavaScript invocation in progress has
// run to completion. Examples are MessageEventRunnable and
// ReportErrorRunnable. These runnables are segregated into separate
// ThrottledEventQueues, which the debugger pauses.
//
// Note that debugger runnables do not fall in this category, since we don't
// support debugging the debugger server at the moment.
virtual bool
IsDebuggeeRunnable() const
{
return false;
}
static WorkerRunnable*
FromRunnable(nsIRunnable* aRunnable);
@ -498,6 +513,44 @@ private:
DispatchInternal() final;
};
// Runnables handled by content JavaScript (MessageEventRunnable, JavaScript
// error reports, and so on) must not be delivered while that content is in the
// midst of being debugged; the debuggee must be allowed to complete its current
// JavaScript invocation and return to its own event loop. Only then is it
// prepared for messages sent from the worker.
//
// Runnables that need to be deferred in this way should inherit from this
// class. They will be routed to mMainThreadDebuggeeEventTarget, which is paused
// while the window is suspended, as it is whenever the debugger spins its
// nested event loop. When the debugger leaves its nested event loop, it resumes
// the window, so that mMainThreadDebuggeeEventTarget will resume delivering
// runnables from the worker when control returns to the main event loop.
//
// When a page enters the bfcache, it freezes all its workers. Since a frozen
// worker processes only control runnables, it doesn't take any special
// consideration to prevent WorkerDebuggeeRunnables sent from child to parent
// workers from running; they'll never run anyway. But WorkerDebuggeeRunnables
// from a top-level frozen worker to its parent window must not be delivered
// either, even as the main thread event loop continues to spin. Thus, freezing
// a top-level worker also pauses mMainThreadDebuggeeEventTarget.
class WorkerDebuggeeRunnable : public WorkerRunnable
{
protected:
WorkerDebuggeeRunnable(WorkerPrivate* aWorkerPrivate,
TargetAndBusyBehavior aBehavior = ParentThreadUnchangedBusyCount)
: WorkerRunnable(aWorkerPrivate, aBehavior)
{ }
private:
// This override is deliberately private: it doesn't make sense to call it if
// we know statically that we are a WorkerDebuggeeRunnable.
bool
IsDebuggeeRunnable() const override
{
return true;
}
};
} // dom namespace
} // mozilla namespace