Backed out changeset b462e7b742d8 (bug 1908261) for causing multiple reftest failures...
[gecko.git] / dom / workers / EventWithOptionsRunnable.cpp
blob5c4988c9a7045296952eeee3d309b3d0061fe9de
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=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 https://mozilla.org/MPL/2.0/. */
7 #include "EventWithOptionsRunnable.h"
8 #include "WorkerScope.h"
9 #include "mozilla/dom/WorkerRunnable.h"
10 #include "mozilla/dom/StructuredCloneHolder.h"
11 #include "js/StructuredClone.h"
12 #include "js/RootingAPI.h"
13 #include "js/Value.h"
14 #include "nsJSPrincipals.h"
15 #include "nsContentUtils.h"
16 #include "nsDebug.h"
17 #include "MainThreadUtils.h"
18 #include "mozilla/Assertions.h"
19 #include "nsGlobalWindowInner.h"
20 #include "mozilla/DOMEventTargetHelper.h"
21 #include "mozilla/ErrorResult.h"
22 #include "nsIGlobalObject.h"
23 #include "nsCOMPtr.h"
24 #include "js/GlobalObject.h"
25 #include "xpcpublic.h"
26 #include "mozilla/dom/MessagePortBinding.h"
27 #include "mozilla/dom/MessagePort.h"
28 #include "mozilla/OwningNonNull.h"
29 #include "mozilla/RefPtr.h"
30 #include "mozilla/dom/Event.h"
31 #include "mozilla/dom/WorkerCommon.h"
33 namespace mozilla::dom {
34 EventWithOptionsRunnable::EventWithOptionsRunnable(Worker& aWorker,
35 const char* aName)
36 : WorkerDebuggeeRunnable(aName),
37 StructuredCloneHolder(CloningSupported, TransferringSupported,
38 StructuredCloneScope::SameProcess) {}
40 EventWithOptionsRunnable::~EventWithOptionsRunnable() = default;
42 void EventWithOptionsRunnable::InitOptions(
43 JSContext* aCx, JS::Handle<JS::Value> aOptions,
44 const Sequence<JSObject*>& aTransferable, ErrorResult& aRv) {
45 JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
47 aRv = nsContentUtils::CreateJSValueFromSequenceOfObject(aCx, aTransferable,
48 &transferable);
49 if (NS_WARN_IF(aRv.Failed())) {
50 return;
53 JS::CloneDataPolicy clonePolicy;
54 // DedicatedWorkers are always part of the same agent cluster.
55 clonePolicy.allowIntraClusterClonableSharedObjects();
57 MOZ_ASSERT(NS_IsMainThread());
58 nsGlobalWindowInner* win = nsContentUtils::IncumbentInnerWindow();
59 if (win && win->IsSharedMemoryAllowed()) {
60 clonePolicy.allowSharedMemoryObjects();
63 Write(aCx, aOptions, transferable, clonePolicy, aRv);
66 // Cargo-culted from MesssageEventRunnable.
67 bool EventWithOptionsRunnable::BuildAndFireEvent(
68 JSContext* aCx, WorkerPrivate* aWorkerPrivate,
69 DOMEventTargetHelper* aTarget) {
70 IgnoredErrorResult rv;
71 nsCOMPtr<nsIGlobalObject> parent = aTarget->GetParentObject();
73 // For some workers without window, parent is null and we try to find it
74 // from the JS Context.
75 if (!parent) {
76 JS::Rooted<JSObject*> globalObject(aCx, JS::CurrentGlobalOrNull(aCx));
77 if (NS_WARN_IF(!globalObject)) {
78 rv.ThrowDataCloneError("failed to get global object");
79 OptionsDeserializeFailed(rv);
80 return false;
83 parent = xpc::NativeGlobal(globalObject);
84 if (NS_WARN_IF(!parent)) {
85 rv.ThrowDataCloneError("failed to get parent");
86 OptionsDeserializeFailed(rv);
87 return false;
91 MOZ_ASSERT(parent);
93 JS::Rooted<JS::Value> options(aCx);
95 JS::CloneDataPolicy cloneDataPolicy;
96 if (parent->GetClientInfo().isSome() &&
97 parent->GetClientInfo()->AgentClusterId().isSome() &&
98 parent->GetClientInfo()->AgentClusterId()->Equals(
99 aWorkerPrivate->AgentClusterId())) {
100 cloneDataPolicy.allowIntraClusterClonableSharedObjects();
103 if (aWorkerPrivate->IsSharedMemoryAllowed()) {
104 cloneDataPolicy.allowSharedMemoryObjects();
107 Read(parent, aCx, &options, cloneDataPolicy, rv);
109 if (NS_WARN_IF(rv.Failed())) {
110 OptionsDeserializeFailed(rv);
111 return false;
114 Sequence<OwningNonNull<MessagePort>> ports;
115 if (NS_WARN_IF(!TakeTransferredPortsAsSequence(ports))) {
116 // TODO: Is this an appropriate type? What does this actually do?
117 rv.ThrowDataCloneError("TakeTransferredPortsAsSequence failed");
118 OptionsDeserializeFailed(rv);
119 return false;
122 RefPtr<dom::Event> event = BuildEvent(aCx, parent, aTarget, options);
124 if (NS_WARN_IF(!event)) {
125 return false;
128 aTarget->DispatchEvent(*event);
129 return true;
132 bool EventWithOptionsRunnable::WorkerRun(JSContext* aCx,
133 WorkerPrivate* aWorkerPrivate) {
134 MOZ_ASSERT(aWorkerPrivate == GetWorkerPrivateFromContext(aCx));
135 MOZ_ASSERT(aWorkerPrivate->GlobalScope());
137 // If the worker start shutting down, don't dispatch the event.
138 if (NS_FAILED(
139 aWorkerPrivate->GlobalScope()->CheckCurrentGlobalCorrectness())) {
140 return true;
143 return BuildAndFireEvent(aCx, aWorkerPrivate, aWorkerPrivate->GlobalScope());
146 } // namespace mozilla::dom