dom/workers/SharedWorker.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "SharedWorker.h"
michael@0 7
michael@0 8 #include "nsPIDOMWindow.h"
michael@0 9
michael@0 10 #include "mozilla/EventDispatcher.h"
michael@0 11 #include "mozilla/Preferences.h"
michael@0 12 #include "mozilla/dom/SharedWorkerBinding.h"
michael@0 13 #include "nsContentUtils.h"
michael@0 14 #include "nsIClassInfoImpl.h"
michael@0 15 #include "nsIDOMEvent.h"
michael@0 16
michael@0 17 #include "MessagePort.h"
michael@0 18 #include "RuntimeService.h"
michael@0 19 #include "WorkerPrivate.h"
michael@0 20
michael@0 21 using mozilla::dom::Optional;
michael@0 22 using mozilla::dom::Sequence;
michael@0 23 using namespace mozilla;
michael@0 24
michael@0 25 USING_WORKERS_NAMESPACE
michael@0 26
michael@0 27 SharedWorker::SharedWorker(nsPIDOMWindow* aWindow,
michael@0 28 WorkerPrivate* aWorkerPrivate)
michael@0 29 : DOMEventTargetHelper(aWindow), mWorkerPrivate(aWorkerPrivate),
michael@0 30 mSuspended(false)
michael@0 31 {
michael@0 32 AssertIsOnMainThread();
michael@0 33 MOZ_ASSERT(aWorkerPrivate);
michael@0 34
michael@0 35 mSerial = aWorkerPrivate->NextMessagePortSerial();
michael@0 36
michael@0 37 mMessagePort = new MessagePort(aWindow, this, mSerial);
michael@0 38 }
michael@0 39
michael@0 40 SharedWorker::~SharedWorker()
michael@0 41 {
michael@0 42 AssertIsOnMainThread();
michael@0 43 Close();
michael@0 44 MOZ_ASSERT(!mWorkerPrivate);
michael@0 45 }
michael@0 46
michael@0 47 // static
michael@0 48 already_AddRefed<SharedWorker>
michael@0 49 SharedWorker::Constructor(const GlobalObject& aGlobal, JSContext* aCx,
michael@0 50 const nsAString& aScriptURL,
michael@0 51 const mozilla::dom::Optional<nsAString>& aName,
michael@0 52 ErrorResult& aRv)
michael@0 53 {
michael@0 54 AssertIsOnMainThread();
michael@0 55
michael@0 56 RuntimeService* rts = RuntimeService::GetOrCreateService();
michael@0 57 if (!rts) {
michael@0 58 aRv = NS_ERROR_NOT_AVAILABLE;
michael@0 59 return nullptr;
michael@0 60 }
michael@0 61
michael@0 62 nsCString name;
michael@0 63 if (aName.WasPassed()) {
michael@0 64 name = NS_ConvertUTF16toUTF8(aName.Value());
michael@0 65 }
michael@0 66
michael@0 67 nsRefPtr<SharedWorker> sharedWorker;
michael@0 68 nsresult rv = rts->CreateSharedWorker(aGlobal, aScriptURL, name,
michael@0 69 getter_AddRefs(sharedWorker));
michael@0 70 if (NS_FAILED(rv)) {
michael@0 71 aRv = rv;
michael@0 72 return nullptr;
michael@0 73 }
michael@0 74
michael@0 75 return sharedWorker.forget();
michael@0 76 }
michael@0 77
michael@0 78 already_AddRefed<MessagePort>
michael@0 79 SharedWorker::Port()
michael@0 80 {
michael@0 81 AssertIsOnMainThread();
michael@0 82
michael@0 83 nsRefPtr<MessagePort> messagePort = mMessagePort;
michael@0 84 return messagePort.forget();
michael@0 85 }
michael@0 86
michael@0 87 void
michael@0 88 SharedWorker::Suspend()
michael@0 89 {
michael@0 90 AssertIsOnMainThread();
michael@0 91 MOZ_ASSERT(!IsSuspended());
michael@0 92
michael@0 93 mSuspended = true;
michael@0 94 }
michael@0 95
michael@0 96 void
michael@0 97 SharedWorker::Resume()
michael@0 98 {
michael@0 99 AssertIsOnMainThread();
michael@0 100 MOZ_ASSERT(IsSuspended());
michael@0 101
michael@0 102 mSuspended = false;
michael@0 103
michael@0 104 if (!mSuspendedEvents.IsEmpty()) {
michael@0 105 nsTArray<nsCOMPtr<nsIDOMEvent>> events;
michael@0 106 mSuspendedEvents.SwapElements(events);
michael@0 107
michael@0 108 for (uint32_t index = 0; index < events.Length(); index++) {
michael@0 109 nsCOMPtr<nsIDOMEvent>& event = events[index];
michael@0 110 MOZ_ASSERT(event);
michael@0 111
michael@0 112 nsCOMPtr<nsIDOMEventTarget> target;
michael@0 113 if (NS_SUCCEEDED(event->GetTarget(getter_AddRefs(target)))) {
michael@0 114 bool ignored;
michael@0 115 if (NS_FAILED(target->DispatchEvent(event, &ignored))) {
michael@0 116 NS_WARNING("Failed to dispatch event!");
michael@0 117 }
michael@0 118 } else {
michael@0 119 NS_WARNING("Failed to get target!");
michael@0 120 }
michael@0 121 }
michael@0 122 }
michael@0 123 }
michael@0 124
michael@0 125 void
michael@0 126 SharedWorker::QueueEvent(nsIDOMEvent* aEvent)
michael@0 127 {
michael@0 128 AssertIsOnMainThread();
michael@0 129 MOZ_ASSERT(aEvent);
michael@0 130 MOZ_ASSERT(IsSuspended());
michael@0 131
michael@0 132 mSuspendedEvents.AppendElement(aEvent);
michael@0 133 }
michael@0 134
michael@0 135 void
michael@0 136 SharedWorker::Close()
michael@0 137 {
michael@0 138 AssertIsOnMainThread();
michael@0 139
michael@0 140 if (mMessagePort) {
michael@0 141 mMessagePort->Close();
michael@0 142 }
michael@0 143
michael@0 144 if (mWorkerPrivate) {
michael@0 145 AutoSafeJSContext cx;
michael@0 146 NoteDeadWorker(cx);
michael@0 147 }
michael@0 148 }
michael@0 149
michael@0 150 void
michael@0 151 SharedWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
michael@0 152 const Optional<Sequence<JS::Value>>& aTransferable,
michael@0 153 ErrorResult& aRv)
michael@0 154 {
michael@0 155 AssertIsOnMainThread();
michael@0 156 MOZ_ASSERT(mWorkerPrivate);
michael@0 157 MOZ_ASSERT(mMessagePort);
michael@0 158
michael@0 159 mWorkerPrivate->PostMessageToMessagePort(aCx, mMessagePort->Serial(),
michael@0 160 aMessage, aTransferable, aRv);
michael@0 161 }
michael@0 162
michael@0 163 void
michael@0 164 SharedWorker::NoteDeadWorker(JSContext* aCx)
michael@0 165 {
michael@0 166 AssertIsOnMainThread();
michael@0 167 MOZ_ASSERT(mWorkerPrivate);
michael@0 168
michael@0 169 mWorkerPrivate->UnregisterSharedWorker(aCx, this);
michael@0 170 mWorkerPrivate = nullptr;
michael@0 171 }
michael@0 172
michael@0 173 NS_IMPL_ADDREF_INHERITED(SharedWorker, DOMEventTargetHelper)
michael@0 174 NS_IMPL_RELEASE_INHERITED(SharedWorker, DOMEventTargetHelper)
michael@0 175
michael@0 176 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(SharedWorker)
michael@0 177 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
michael@0 178
michael@0 179 NS_IMPL_CYCLE_COLLECTION_CLASS(SharedWorker)
michael@0 180
michael@0 181 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SharedWorker,
michael@0 182 DOMEventTargetHelper)
michael@0 183 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessagePort)
michael@0 184 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSuspendedEvents)
michael@0 185 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
michael@0 186
michael@0 187 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SharedWorker,
michael@0 188 DOMEventTargetHelper)
michael@0 189 tmp->Close();
michael@0 190 NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessagePort)
michael@0 191 NS_IMPL_CYCLE_COLLECTION_UNLINK(mSuspendedEvents)
michael@0 192 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
michael@0 193
michael@0 194 JSObject*
michael@0 195 SharedWorker::WrapObject(JSContext* aCx)
michael@0 196 {
michael@0 197 AssertIsOnMainThread();
michael@0 198
michael@0 199 return SharedWorkerBinding::Wrap(aCx, this);
michael@0 200 }
michael@0 201
michael@0 202 nsresult
michael@0 203 SharedWorker::PreHandleEvent(EventChainPreVisitor& aVisitor)
michael@0 204 {
michael@0 205 AssertIsOnMainThread();
michael@0 206
michael@0 207 nsIDOMEvent*& event = aVisitor.mDOMEvent;
michael@0 208
michael@0 209 if (IsSuspended() && event) {
michael@0 210 QueueEvent(event);
michael@0 211
michael@0 212 aVisitor.mCanHandle = false;
michael@0 213 aVisitor.mParentTarget = nullptr;
michael@0 214 return NS_OK;
michael@0 215 }
michael@0 216
michael@0 217 return DOMEventTargetHelper::PreHandleEvent(aVisitor);
michael@0 218 }

mercurial