Bug 1825333 - Make toolkit/components/sessionstore buildable outside of a unified...
[gecko.git] / dom / workers / WorkerEventTarget.cpp
blob446123334c5da1001980ed0d6bf6758f18fca5db
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 "WorkerEventTarget.h"
8 #include "WorkerPrivate.h"
9 #include "WorkerRunnable.h"
11 #include "mozilla/dom/ReferrerInfo.h"
13 namespace mozilla::dom {
15 namespace {
17 class WrappedControlRunnable final : public WorkerControlRunnable {
18 nsCOMPtr<nsIRunnable> mInner;
20 ~WrappedControlRunnable() = default;
22 public:
23 WrappedControlRunnable(WorkerPrivate* aWorkerPrivate,
24 nsCOMPtr<nsIRunnable>&& aInner)
25 : WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount),
26 mInner(std::move(aInner)) {}
28 virtual bool PreDispatch(WorkerPrivate* aWorkerPrivate) override {
29 // Silence bad assertions, this can be dispatched from any thread.
30 return true;
33 virtual void PostDispatch(WorkerPrivate* aWorkerPrivate,
34 bool aDispatchResult) override {
35 // Silence bad assertions, this can be dispatched from any thread.
38 bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override {
39 mInner->Run();
40 return true;
43 nsresult Cancel() override {
44 nsCOMPtr<nsICancelableRunnable> cr = do_QueryInterface(mInner);
46 // If the inner runnable is not cancellable, then just do the normal
47 // WorkerControlRunnable thing. This will end up calling Run().
48 if (!cr) {
49 WorkerControlRunnable::Cancel();
50 return NS_OK;
53 // Otherwise call the inner runnable's Cancel() and treat this like
54 // a WorkerRunnable cancel. We can't call WorkerControlRunnable::Cancel()
55 // in this case since that would result in both Run() and the inner
56 // Cancel() being called.
57 Unused << cr->Cancel();
58 return WorkerRunnable::Cancel();
62 } // anonymous namespace
64 NS_IMPL_ISUPPORTS(WorkerEventTarget, nsIEventTarget, nsISerialEventTarget)
66 WorkerEventTarget::WorkerEventTarget(WorkerPrivate* aWorkerPrivate,
67 Behavior aBehavior)
68 : mMutex("WorkerEventTarget"),
69 mWorkerPrivate(aWorkerPrivate),
70 mBehavior(aBehavior) {
71 MOZ_DIAGNOSTIC_ASSERT(mWorkerPrivate);
74 void WorkerEventTarget::ForgetWorkerPrivate(WorkerPrivate* aWorkerPrivate) {
75 MutexAutoLock lock(mMutex);
76 MOZ_DIAGNOSTIC_ASSERT(!mWorkerPrivate || mWorkerPrivate == aWorkerPrivate);
77 mWorkerPrivate = nullptr;
80 NS_IMETHODIMP
81 WorkerEventTarget::DispatchFromScript(nsIRunnable* aRunnable, uint32_t aFlags) {
82 nsCOMPtr<nsIRunnable> runnable(aRunnable);
83 return Dispatch(runnable.forget(), aFlags);
86 NS_IMETHODIMP
87 WorkerEventTarget::Dispatch(already_AddRefed<nsIRunnable> aRunnable,
88 uint32_t aFlags) {
89 nsCOMPtr<nsIRunnable> runnable(aRunnable);
91 MutexAutoLock lock(mMutex);
93 if (!mWorkerPrivate) {
94 return NS_ERROR_FAILURE;
97 if (mBehavior == Behavior::Hybrid) {
98 RefPtr<WorkerRunnable> r =
99 mWorkerPrivate->MaybeWrapAsWorkerRunnable(runnable.forget());
100 if (r->Dispatch()) {
101 return NS_OK;
104 runnable = std::move(r);
107 RefPtr<WorkerControlRunnable> r =
108 new WrappedControlRunnable(mWorkerPrivate, std::move(runnable));
109 if (!r->Dispatch()) {
110 return NS_ERROR_FAILURE;
113 return NS_OK;
116 NS_IMETHODIMP
117 WorkerEventTarget::DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t) {
118 return NS_ERROR_NOT_IMPLEMENTED;
121 NS_IMETHODIMP
122 WorkerEventTarget::RegisterShutdownTask(nsITargetShutdownTask* aTask) {
123 NS_ENSURE_ARG(aTask);
125 MutexAutoLock lock(mMutex);
127 // If mWorkerPrivate is gone, the event target is already late during
128 // shutdown, return NS_ERROR_UNEXPECTED as documented in `nsIEventTarget.idl`.
129 if (!mWorkerPrivate) {
130 return NS_ERROR_UNEXPECTED;
133 return mWorkerPrivate->RegisterShutdownTask(aTask);
136 NS_IMETHODIMP
137 WorkerEventTarget::UnregisterShutdownTask(nsITargetShutdownTask* aTask) {
138 NS_ENSURE_ARG(aTask);
140 MutexAutoLock lock(mMutex);
142 if (!mWorkerPrivate) {
143 return NS_ERROR_UNEXPECTED;
146 return mWorkerPrivate->UnregisterShutdownTask(aTask);
149 NS_IMETHODIMP_(bool)
150 WorkerEventTarget::IsOnCurrentThreadInfallible() {
151 MutexAutoLock lock(mMutex);
153 if (!mWorkerPrivate) {
154 return false;
157 return mWorkerPrivate->IsOnCurrentThread();
160 NS_IMETHODIMP
161 WorkerEventTarget::IsOnCurrentThread(bool* aIsOnCurrentThread) {
162 MOZ_ASSERT(aIsOnCurrentThread);
163 *aIsOnCurrentThread = IsOnCurrentThreadInfallible();
164 return NS_OK;
167 } // namespace mozilla::dom