dom/workers/SharedWorker.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial