зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1484524: Allow creating a StrongWorkerRef for IPC in the Canceling state r=asuth
By allowing the creation of StrongWorkerRefs in the Canceling state we ensure that IPC will not fail and lead to crashes. Differential Revision: https://phabricator.services.mozilla.com/D21920 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
ff5c70a292
Коммит
842cf2b27c
|
@ -145,8 +145,26 @@ WorkerPrivate* WeakWorkerRef::GetUnsafePrivate() const {
|
|||
|
||||
/* static */
|
||||
already_AddRefed<StrongWorkerRef> StrongWorkerRef::Create(
|
||||
WorkerPrivate* aWorkerPrivate, const char* aName,
|
||||
WorkerPrivate* const aWorkerPrivate, const char* const aName,
|
||||
std::function<void()>&& aCallback) {
|
||||
if (RefPtr<StrongWorkerRef> ref =
|
||||
CreateImpl(aWorkerPrivate, aName, Canceling)) {
|
||||
ref->mCallback = std::move(aCallback);
|
||||
return ref.forget();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<StrongWorkerRef> StrongWorkerRef::CreateForcibly(
|
||||
WorkerPrivate* const aWorkerPrivate, const char* const aName) {
|
||||
return CreateImpl(aWorkerPrivate, aName, Killing);
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<StrongWorkerRef> StrongWorkerRef::CreateImpl(
|
||||
WorkerPrivate* const aWorkerPrivate, const char* const aName,
|
||||
WorkerStatus const aFailStatus) {
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
MOZ_ASSERT(aName);
|
||||
|
||||
|
@ -155,12 +173,11 @@ already_AddRefed<StrongWorkerRef> StrongWorkerRef::Create(
|
|||
// The worker is kept alive by this holder.
|
||||
UniquePtr<Holder> holder(
|
||||
new Holder(aName, ref, WorkerHolder::PreventIdleShutdownStart));
|
||||
if (NS_WARN_IF(!holder->HoldWorker(aWorkerPrivate, Canceling))) {
|
||||
if (NS_WARN_IF(!holder->HoldWorker(aWorkerPrivate, aFailStatus))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ref->mHolder = std::move(holder);
|
||||
ref->mCallback = std::move(aCallback);
|
||||
|
||||
return ref.forget();
|
||||
}
|
||||
|
|
|
@ -129,12 +129,31 @@ class StrongWorkerRef final : public WorkerRef {
|
|||
WorkerPrivate* aWorkerPrivate, const char* aName,
|
||||
std::function<void()>&& aCallback = nullptr);
|
||||
|
||||
// This function creates a StrongWorkerRef even when in the Canceling state of
|
||||
// the worker's lifecycle. It's intended to be used by system code, e.g. code
|
||||
// that needs to perform IPC.
|
||||
//
|
||||
// This method should only be used in cases where the StrongWorkerRef will be
|
||||
// used for an extremely bounded duration that cannot be impacted by content.
|
||||
// For example, IPCStreams use this type of ref in order to immediately
|
||||
// migrate to an actor on another thread. Whether the IPCStream ever actually
|
||||
// is streamed does not matter; the ref will be dropped once the new actor is
|
||||
// created. For this reason, this method does not take a callback. It's
|
||||
// expected and required that callers will drop the reference when they are
|
||||
// done.
|
||||
static already_AddRefed<StrongWorkerRef> CreateForcibly(
|
||||
WorkerPrivate* aWorkerPrivate, const char* aName);
|
||||
|
||||
WorkerPrivate* Private() const;
|
||||
|
||||
private:
|
||||
friend class WeakWorkerRef;
|
||||
friend class ThreadSafeWorkerRef;
|
||||
|
||||
static already_AddRefed<StrongWorkerRef> CreateImpl(
|
||||
WorkerPrivate* aWorkerPrivate, const char* aName,
|
||||
WorkerStatus aFailStatus);
|
||||
|
||||
explicit StrongWorkerRef(WorkerPrivate* aWorkerPrivate);
|
||||
~StrongWorkerRef();
|
||||
};
|
||||
|
|
|
@ -119,12 +119,10 @@ bool IPCStreamSource::Initialize() {
|
|||
// worker threads, but not other threads. Main-thread and PBackground thread
|
||||
// do not need anything special in order to be kept alive.
|
||||
if (!NS_IsMainThread()) {
|
||||
mozilla::dom::WorkerPrivate* workerPrivate =
|
||||
mozilla::dom::GetCurrentThreadWorkerPrivate();
|
||||
if (workerPrivate) {
|
||||
RefPtr<mozilla::dom::StrongWorkerRef> workerRef =
|
||||
mozilla::dom::StrongWorkerRef::Create(workerPrivate,
|
||||
"IPCStreamSource");
|
||||
if (const auto workerPrivate = dom::GetCurrentThreadWorkerPrivate()) {
|
||||
RefPtr<dom::StrongWorkerRef> workerRef =
|
||||
dom::StrongWorkerRef::CreateForcibly(workerPrivate,
|
||||
"IPCStreamSource");
|
||||
if (NS_WARN_IF(!workerRef)) {
|
||||
return false;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче