Bug 1559919 - Finish the WorkerHolder cleanup - part 3 - IPCWorkerRef r=asuth

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andrea Marchesini 2019-07-12 11:16:03 +00:00
Родитель 492ae88ae0
Коммит 6e86832cf2
2 изменённых файлов: 84 добавлений и 0 удалений

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

@ -216,5 +216,41 @@ WorkerPrivate* ThreadSafeWorkerRef::Private() const {
return mRef->mWorkerPrivate; return mRef->mWorkerPrivate;
} }
// ----------------------------------------------------------------------------
// IPCWorkerRef
/* static */
already_AddRefed<IPCWorkerRef> IPCWorkerRef::Create(
WorkerPrivate* aWorkerPrivate, const char* aName,
std::function<void()>&& aCallback) {
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
RefPtr<IPCWorkerRef> ref = new IPCWorkerRef(aWorkerPrivate);
// This holder doesn't keep the worker alive.
UniquePtr<Holder> holder(
new Holder(aName, ref, WorkerHolder::AllowIdleShutdownStart));
if (NS_WARN_IF(!holder->HoldWorker(aWorkerPrivate, Canceling))) {
return nullptr;
}
ref->mHolder = std::move(holder);
ref->mCallback = std::move(aCallback);
return ref.forget();
}
IPCWorkerRef::IPCWorkerRef(WorkerPrivate* aWorkerPrivate)
: WorkerRef(aWorkerPrivate) {}
IPCWorkerRef::~IPCWorkerRef() = default;
WorkerPrivate* IPCWorkerRef::Private() const {
MOZ_ASSERT(mHolder);
NS_ASSERT_OWNINGTHREAD(IPCWorkerRef);
return mWorkerPrivate;
}
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla

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

@ -79,6 +79,23 @@ namespace dom {
* ThreadSafeWorkerRef can be destroyed in any thread. Internally it keeps a * ThreadSafeWorkerRef can be destroyed in any thread. Internally it keeps a
* reference to its StrongWorkerRef creator and this ref will be dropped on the * reference to its StrongWorkerRef creator and this ref will be dropped on the
* correct thread when the ThreadSafeWorkerRef is deleted. * correct thread when the ThreadSafeWorkerRef is deleted.
*
* IPC WorkerRef
* ~~~~~~~~~~~~~
*
* IPDL protocols require a correct shutdown sequence. Because of this, they
* need a special configuration:
* 1. they need to be informed when the Worker starts the shutting down
* 2. they don't want to prevent the shutdown
* 3. but at the same time, they need to block the shutdown until the WorkerRef
* is not longer alive.
*
* Point 1 is a standard feature of WorkerRef; point 2 is similar to
* WeakWorkerRef; point 3 is similar to StrongWorkerRef.
*
* You can create a special IPC WorkerRef using this static method:
* mozilla::dom::IPCWorkerRef::Create(WorkerPrivate* aWorkerPrivate,
* const char* * aName);
*/ */
class WorkerPrivate; class WorkerPrivate;
@ -174,6 +191,37 @@ class ThreadSafeWorkerRef final {
RefPtr<StrongWorkerRef> mRef; RefPtr<StrongWorkerRef> mRef;
}; };
class IPCWorkerRef final : public WorkerRef {
public:
static already_AddRefed<IPCWorkerRef> Create(
WorkerPrivate* aWorkerPrivate, const char* aName,
std::function<void()>&& aCallback = nullptr);
WorkerPrivate* Private() const;
private:
explicit IPCWorkerRef(WorkerPrivate* aWorkerPrivate);
~IPCWorkerRef();
};
// Template class to keep an Actor pointer, as a raw pointer, in a ref-counted
// way when passed to lambdas.
template <class ActorPtr>
class IPCWorkerRefHelper final {
public:
NS_INLINE_DECL_REFCOUNTING(IPCWorkerRefHelper);
explicit IPCWorkerRefHelper(ActorPtr* aActor) : mActor(aActor) {}
ActorPtr* Actor() const { return mActor; }
private:
~IPCWorkerRefHelper() = default;
// Raw pointer
ActorPtr* mActor;
};
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla