bug 1328964 terminate worklet thread during xpcom shutdown r=baku

The final CC does not happen until after threads are shutdown and so we can't
depend on CC to trigger termination.

This management of the worklet thread by worklet code is an intermediate
situation until worklets run on the threads managed by other objects.

MozReview-Commit-ID: 8hWsdRCppC2

--HG--
extra : rebase_source : 1a0bfdc80ffa2d8beaff6249f40d033a0f319d2e
This commit is contained in:
Karl Tomlinson 2018-04-12 16:26:08 +12:00
Родитель c130f353db
Коммит cabef87937
2 изменённых файлов: 30 добавлений и 2 удалений

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

@ -6,6 +6,7 @@
#include "WorkletThread.h"
#include "prthread.h"
#include "nsContentUtils.h"
#include "nsCycleCollector.h"
#include "mozilla/dom/AtomList.h"
#include "mozilla/EventQueue.h"
@ -295,7 +296,10 @@ WorkletThread::WorkletThread(const WorkletLoadInfo& aWorkletLoadInfo)
, mWorkletLoadInfo(aWorkletLoadInfo)
, mCreationTimeStamp(TimeStamp::Now())
, mJSContext(nullptr)
, mIsTerminating(false)
{
MOZ_ASSERT(NS_IsMainThread());
nsContentUtils::RegisterShutdownObserver(this);
}
WorkletThread::~WorkletThread()
@ -399,6 +403,16 @@ WorkletThread::Terminate()
{
MOZ_ASSERT(NS_IsMainThread());
if (mIsTerminating) {
// nsThread::Dispatch() would leak the runnable if the event queue is no
// longer accepting runnables.
return;
}
mIsTerminating = true;
nsContentUtils::UnregisterShutdownObserver(this);
RefPtr<TerminateRunnable> runnable = new TerminateRunnable(this);
DispatchRunnable(runnable.forget());
}
@ -458,7 +472,18 @@ WorkletThread::Get()
static_cast<WorkletThreadContextPrivate*>(cxPrivate)->GetWorkletThread();
}
NS_IMPL_ISUPPORTS_INHERITED0(WorkletThread, nsThread)
// nsIObserver
NS_IMETHODIMP
WorkletThread::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t*)
{
MOZ_ASSERT(strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0);
Terminate();
return NS_OK;
}
NS_IMPL_ISUPPORTS_INHERITED(WorkletThread, nsThread, nsIObserver)
} // namespace dom
} // namespace mozilla

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

@ -20,10 +20,11 @@ class nsIRunnable;
namespace mozilla {
namespace dom {
class WorkletThread final : public nsThread
class WorkletThread final : public nsThread, public nsIObserver
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIOBSERVER
static already_AddRefed<WorkletThread>
Create(const WorkletLoadInfo& aWorkletLoadInfo);
@ -89,6 +90,8 @@ private:
// Touched only on the worklet thread. This is a raw pointer because it's set
// and nullified by RunEventLoop().
JSContext* mJSContext;
bool mIsTerminating; // main thread
};
} // namespace dom