Bug 1550519 - Show a translucent parent highlight when a subgrid is highlighted....
[gecko.git] / dom / workers / WorkerRef.cpp
blob255b0ec65e654bc12f56868aa9090db84cf8e4a1
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "WorkerRef.h"
9 #include "mozilla/Unused.h"
10 #include "WorkerHolder.h"
11 #include "WorkerRunnable.h"
12 #include "WorkerPrivate.h"
14 namespace mozilla {
15 namespace dom {
17 namespace {
19 // This runnable is used to release the StrongWorkerRef on the worker thread
20 // when a ThreadSafeWorkerRef is released.
21 class ReleaseRefControlRunnable final : public WorkerControlRunnable {
22 public:
23 ReleaseRefControlRunnable(WorkerPrivate* aWorkerPrivate,
24 already_AddRefed<StrongWorkerRef> aRef)
25 : WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount),
26 mRef(std::move(aRef)) {
27 MOZ_ASSERT(mRef);
30 bool PreDispatch(WorkerPrivate* aWorkerPrivate) override { return true; }
32 void PostDispatch(WorkerPrivate* aWorkerPrivate,
33 bool aDispatchResult) override {}
35 bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override {
36 mRef = nullptr;
37 return true;
40 private:
41 RefPtr<StrongWorkerRef> mRef;
44 } // namespace
46 // ----------------------------------------------------------------------------
47 // WorkerRef::Holder
49 class WorkerRef::Holder final : public mozilla::dom::WorkerHolder {
50 public:
51 Holder(const char* aName, WorkerRef* aWorkerRef, Behavior aBehavior)
52 : mozilla::dom::WorkerHolder(aName, aBehavior), mWorkerRef(aWorkerRef) {}
54 bool Notify(WorkerStatus aStatus) override {
55 MOZ_ASSERT(mWorkerRef);
57 if (aStatus < Canceling) {
58 return true;
61 // Let's keep this object alive for the whole Notify() execution.
62 RefPtr<WorkerRef> workerRef;
63 workerRef = mWorkerRef;
65 workerRef->Notify();
66 return true;
69 public:
70 WorkerRef* mWorkerRef;
73 // ----------------------------------------------------------------------------
74 // WorkerRef
76 WorkerRef::WorkerRef(WorkerPrivate* aWorkerPrivate)
77 : mWorkerPrivate(aWorkerPrivate) {
78 MOZ_ASSERT(aWorkerPrivate);
79 aWorkerPrivate->AssertIsOnWorkerThread();
82 WorkerRef::~WorkerRef() { NS_ASSERT_OWNINGTHREAD(WorkerRef); }
84 void WorkerRef::Notify() {
85 MOZ_ASSERT(mHolder);
86 NS_ASSERT_OWNINGTHREAD(WorkerRef);
88 if (!mCallback) {
89 return;
92 std::function<void()> callback = std::move(mCallback);
93 MOZ_ASSERT(!mCallback);
95 callback();
98 // ----------------------------------------------------------------------------
99 // WeakWorkerRef
101 /* static */
102 already_AddRefed<WeakWorkerRef> WeakWorkerRef::Create(
103 WorkerPrivate* aWorkerPrivate, std::function<void()>&& aCallback) {
104 MOZ_ASSERT(aWorkerPrivate);
105 aWorkerPrivate->AssertIsOnWorkerThread();
107 RefPtr<WeakWorkerRef> ref = new WeakWorkerRef(aWorkerPrivate);
109 // This holder doesn't keep the worker alive.
110 UniquePtr<Holder> holder(new Holder("WeakWorkerRef::Holder", ref,
111 WorkerHolder::AllowIdleShutdownStart));
112 if (NS_WARN_IF(!holder->HoldWorker(aWorkerPrivate, Canceling))) {
113 return nullptr;
116 ref->mHolder = std::move(holder);
117 ref->mCallback = std::move(aCallback);
119 return ref.forget();
122 WeakWorkerRef::WeakWorkerRef(WorkerPrivate* aWorkerPrivate)
123 : WorkerRef(aWorkerPrivate) {}
125 WeakWorkerRef::~WeakWorkerRef() = default;
127 void WeakWorkerRef::Notify() {
128 WorkerRef::Notify();
130 mHolder = nullptr;
131 mWorkerPrivate = nullptr;
134 WorkerPrivate* WeakWorkerRef::GetPrivate() const {
135 NS_ASSERT_OWNINGTHREAD(WeakWorkerRef);
136 return mWorkerPrivate;
139 WorkerPrivate* WeakWorkerRef::GetUnsafePrivate() const {
140 return mWorkerPrivate;
143 // ----------------------------------------------------------------------------
144 // StrongWorkerRef
146 /* static */
147 already_AddRefed<StrongWorkerRef> StrongWorkerRef::Create(
148 WorkerPrivate* const aWorkerPrivate, const char* const aName,
149 std::function<void()>&& aCallback) {
150 if (RefPtr<StrongWorkerRef> ref =
151 CreateImpl(aWorkerPrivate, aName, Canceling)) {
152 ref->mCallback = std::move(aCallback);
153 return ref.forget();
155 return nullptr;
158 /* static */
159 already_AddRefed<StrongWorkerRef> StrongWorkerRef::CreateForcibly(
160 WorkerPrivate* const aWorkerPrivate, const char* const aName) {
161 return CreateImpl(aWorkerPrivate, aName, Killing);
164 /* static */
165 already_AddRefed<StrongWorkerRef> StrongWorkerRef::CreateImpl(
166 WorkerPrivate* const aWorkerPrivate, const char* const aName,
167 WorkerStatus const aFailStatus) {
168 MOZ_ASSERT(aWorkerPrivate);
169 MOZ_ASSERT(aName);
171 RefPtr<StrongWorkerRef> ref = new StrongWorkerRef(aWorkerPrivate);
173 // The worker is kept alive by this holder.
174 UniquePtr<Holder> holder(
175 new Holder(aName, ref, WorkerHolder::PreventIdleShutdownStart));
176 if (NS_WARN_IF(!holder->HoldWorker(aWorkerPrivate, aFailStatus))) {
177 return nullptr;
180 ref->mHolder = std::move(holder);
182 return ref.forget();
185 StrongWorkerRef::StrongWorkerRef(WorkerPrivate* aWorkerPrivate)
186 : WorkerRef(aWorkerPrivate) {}
188 StrongWorkerRef::~StrongWorkerRef() { NS_ASSERT_OWNINGTHREAD(StrongWorkerRef); }
190 WorkerPrivate* StrongWorkerRef::Private() const {
191 MOZ_ASSERT(mHolder);
192 NS_ASSERT_OWNINGTHREAD(StrongWorkerRef);
193 return mWorkerPrivate;
196 // ----------------------------------------------------------------------------
197 // ThreadSafeWorkerRef
199 ThreadSafeWorkerRef::ThreadSafeWorkerRef(StrongWorkerRef* aRef) : mRef(aRef) {
200 MOZ_ASSERT(aRef);
201 aRef->Private()->AssertIsOnWorkerThread();
204 ThreadSafeWorkerRef::~ThreadSafeWorkerRef() {
205 // Let's release the StrongWorkerRef on the correct thread.
206 if (!mRef->mWorkerPrivate->IsOnWorkerThread()) {
207 WorkerPrivate* workerPrivate = mRef->mWorkerPrivate;
208 RefPtr<ReleaseRefControlRunnable> r =
209 new ReleaseRefControlRunnable(workerPrivate, mRef.forget());
210 r->Dispatch();
211 return;
215 WorkerPrivate* ThreadSafeWorkerRef::Private() const {
216 return mRef->mWorkerPrivate;
219 } // namespace dom
220 } // namespace mozilla