Bug 1438945 - Part 2: PSharedWorker protocol. r=asuth
authorAndrea Marchesini <amarchesini@mozilla.com>
Mon, 19 Nov 2018 15:18:20 -0800
changeset 503564 d77e06240f3c05f592381bbbbed176eb78c4c7de
parent 503563 f816f239955c03172fc46f1caf8a46a898eca4e8
child 503565 062638f850a0bef1cfd94e62419ac2f00325c40b
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1438945
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1438945 - Part 2: PSharedWorker protocol. r=asuth
dom/workers/RuntimeService.cpp
dom/workers/RuntimeService.h
dom/workers/sharedworkers/PSharedWorker.ipdl
dom/workers/sharedworkers/SharedWorker.cpp
dom/workers/sharedworkers/SharedWorker.h
dom/workers/sharedworkers/SharedWorkerChild.cpp
dom/workers/sharedworkers/SharedWorkerChild.h
dom/workers/sharedworkers/SharedWorkerParent.cpp
dom/workers/sharedworkers/SharedWorkerParent.h
dom/workers/sharedworkers/SharedWorkerTypes.ipdlh
dom/workers/sharedworkers/moz.build
ipc/glue/BackgroundChildImpl.cpp
ipc/glue/BackgroundChildImpl.h
ipc/glue/BackgroundParentImpl.cpp
ipc/glue/BackgroundParentImpl.h
ipc/glue/PBackground.ipdl
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -1403,16 +1403,17 @@ RuntimeService::RegisterWorker(WorkerPri
     }
     else if (isServiceWorker) {
       domainInfo->mActiveServiceWorkers.AppendElement(aWorkerPrivate);
     }
     else {
       domainInfo->mActiveWorkers.AppendElement(aWorkerPrivate);
     }
 
+/* TODO
     if (isSharedWorker) {
 #ifdef DEBUG
       for (const UniquePtr<SharedWorkerInfo>& data : domainInfo->mSharedWorkerInfos) {
          if (data->mScriptSpec == sharedWorkerScriptSpec &&
              data->mName == aWorkerPrivate->WorkerName() &&
              // We want to be sure that the window's principal subsumes the
              // SharedWorker's principal and vice versa.
              data->mWorkerPrivate->GetPrincipal()->Subsumes(aWorkerPrivate->GetPrincipal()) &&
@@ -1422,16 +1423,17 @@ RuntimeService::RegisterWorker(WorkerPri
       }
 #endif
 
       UniquePtr<SharedWorkerInfo> sharedWorkerInfo(
         new SharedWorkerInfo(aWorkerPrivate, sharedWorkerScriptSpec,
                              aWorkerPrivate->WorkerName()));
       domainInfo->mSharedWorkerInfos.AppendElement(std::move(sharedWorkerInfo));
     }
+*/
   }
 
   // From here on out we must call UnregisterWorker if something fails!
   if (parent) {
     if (!parent->AddChildWorker(aWorkerPrivate)) {
       UnregisterWorker(aWorkerPrivate);
       return false;
     }
@@ -1480,24 +1482,26 @@ RuntimeService::RegisterWorker(WorkerPri
   }
   return true;
 }
 
 void
 RuntimeService::RemoveSharedWorker(WorkerDomainInfo* aDomainInfo,
                                    WorkerPrivate* aWorkerPrivate)
 {
+/* TODO
   for (uint32_t i = 0; i < aDomainInfo->mSharedWorkerInfos.Length(); ++i) {
     const UniquePtr<SharedWorkerInfo>& data =
       aDomainInfo->mSharedWorkerInfos[i];
     if (data->mWorkerPrivate == aWorkerPrivate) {
       aDomainInfo->mSharedWorkerInfos.RemoveElementAt(i);
       break;
     }
   }
+*/
 }
 
 void
 RuntimeService::UnregisterWorker(WorkerPrivate* aWorkerPrivate)
 {
   aWorkerPrivate->AssertIsOnParentThread();
 
   WorkerPrivate* parent = aWorkerPrivate->GetParent();
@@ -2287,71 +2291,23 @@ RuntimeService::PropagateFirstPartyStora
   GetWorkersForWindow(aWindow, workers);
 
   for (uint32_t index = 0; index < workers.Length(); index++) {
     workers[index]->PropagateFirstPartyStorageAccessGranted();
   }
 }
 
 nsresult
-RuntimeService::CreateSharedWorker(const GlobalObject& aGlobal,
-                                   const nsAString& aScriptURL,
-                                   const nsAString& aName,
-                                   SharedWorker** aSharedWorker)
-{
-  AssertIsOnMainThread();
-
-  nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
-  MOZ_ASSERT(window);
-
-  // If the window is blocked from accessing storage, do not allow it
-  // to connect to a SharedWorker.  This would potentially allow it
-  // to communicate with other windows that do have storage access.
-  // Allow private browsing, however, as we handle that isolation
-  // via the principal.
-  auto storageAllowed = nsContentUtils::StorageAllowedForWindow(window);
-  if (storageAllowed != nsContentUtils::StorageAccess::eAllow &&
-      storageAllowed != nsContentUtils::StorageAccess::ePrivateBrowsing) {
-    return NS_ERROR_DOM_SECURITY_ERR;
-  }
-
-  // Assert that the principal private browsing state matches the
-  // StorageAccess value.
-#ifdef  MOZ_DIAGNOSTIC_ASSERT_ENABLED
-  if (storageAllowed == nsContentUtils::StorageAccess::ePrivateBrowsing) {
-    nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
-    nsCOMPtr<nsIPrincipal> principal = doc ? doc->NodePrincipal() : nullptr;
-    uint32_t privateBrowsingId = 0;
-    if (principal) {
-      MOZ_ALWAYS_SUCCEEDS(principal->GetPrivateBrowsingId(&privateBrowsingId));
-    }
-    MOZ_DIAGNOSTIC_ASSERT(privateBrowsingId != 0);
-  }
-#endif // MOZ_DIAGNOSTIC_ASSERT_ENABLED
-
-  JSContext* cx = aGlobal.Context();
-
-  WorkerLoadInfo loadInfo;
-  nsresult rv = WorkerPrivate::GetLoadInfo(cx, window, nullptr, aScriptURL,
-                                           false,
-                                           WorkerPrivate::OverrideLoadGroup,
-                                           WorkerTypeShared, &loadInfo);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return CreateSharedWorkerFromLoadInfo(cx, &loadInfo, aScriptURL, aName,
-                                        aSharedWorker);
-}
-
-nsresult
 RuntimeService::CreateSharedWorkerFromLoadInfo(JSContext* aCx,
                                                WorkerLoadInfo* aLoadInfo,
                                                const nsAString& aScriptURL,
                                                const nsAString& aName,
                                                SharedWorker** aSharedWorker)
 {
+/* TODO
   AssertIsOnMainThread();
   MOZ_ASSERT(aLoadInfo);
   MOZ_ASSERT(aLoadInfo->mResolvedScriptURI);
 
   RefPtr<WorkerPrivate> workerPrivate;
   {
     MutexAutoLock lock(mMutex);
 
@@ -2454,16 +2410,17 @@ RuntimeService::CreateSharedWorkerFromLo
     }
 
     if (!windowArray->Contains(workerPrivate)) {
       windowArray->AppendElement(workerPrivate);
     }
   }
 
   sharedWorker.forget(aSharedWorker);
+*/
   return NS_OK;
 }
 
 void
 RuntimeService::ForgetSharedWorker(WorkerPrivate* aWorkerPrivate)
 {
   AssertIsOnMainThread();
   MOZ_ASSERT(aWorkerPrivate);
--- a/dom/workers/RuntimeService.h
+++ b/dom/workers/RuntimeService.h
@@ -150,22 +150,16 @@ public:
   SuspendWorkersForWindow(nsPIDOMWindowInner* aWindow);
 
   void
   ResumeWorkersForWindow(nsPIDOMWindowInner* aWindow);
 
   void
   PropagateFirstPartyStorageAccessGranted(nsPIDOMWindowInner* aWindow);
 
-  nsresult
-  CreateSharedWorker(const GlobalObject& aGlobal,
-                     const nsAString& aScriptURL,
-                     const nsAString& aName,
-                     SharedWorker** aSharedWorker);
-
   void
   ForgetSharedWorker(WorkerPrivate* aWorkerPrivate);
 
   const NavigatorProperties&
   GetNavigatorProperties() const
   {
     return mNavigatorProperties;
   }
new file mode 100644
--- /dev/null
+++ b/dom/workers/sharedworkers/PSharedWorker.ipdl
@@ -0,0 +1,20 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+include protocol PBackground;
+
+namespace mozilla {
+namespace dom {
+
+protocol PSharedWorker
+{
+  manager PBackground;
+
+child:
+  // TODO:
+  async __delete__();
+};
+
+} // namespace dom
+} // namespace mozilla
--- a/dom/workers/sharedworkers/SharedWorker.cpp
+++ b/dom/workers/sharedworkers/SharedWorker.cpp
@@ -1,52 +1,50 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SharedWorker.h"
 
-#include "nsPIDOMWindow.h"
-
 #include "mozilla/EventDispatcher.h"
-#include "mozilla/Preferences.h"
 #include "mozilla/dom/Event.h"
-#include "mozilla/dom/EventTarget.h"
+#include "mozilla/dom/MessageChannel.h"
 #include "mozilla/dom/MessagePort.h"
+#include "mozilla/dom/PMessagePort.h"
 #include "mozilla/dom/SharedWorkerBinding.h"
+#include "mozilla/dom/SharedWorkerChild.h"
 #include "mozilla/dom/WorkerBinding.h"
-#include "mozilla/Telemetry.h"
+#include "mozilla/dom/WorkerLoadInfo.h"
+#include "mozilla/dom/WorkerPrivate.h"
+#include "mozilla/ipc/BackgroundChild.h"
+#include "mozilla/ipc/BackgroundUtils.h"
+#include "mozilla/ipc/PBackgroundChild.h"
 #include "nsContentUtils.h"
-#include "nsIClassInfoImpl.h"
-
-#include "mozilla/dom/workerinternals/RuntimeService.h"
-#include "mozilla/dom/WorkerPrivate.h"
+#include "nsPIDOMWindow.h"
 
 #ifdef XP_WIN
 #undef PostMessage
 #endif
 
-using mozilla::dom::Optional;
-using mozilla::dom::Sequence;
-using mozilla::dom::MessagePort;
 using namespace mozilla;
 using namespace mozilla::dom;
+using namespace mozilla::ipc;
 
 SharedWorker::SharedWorker(nsPIDOMWindowInner* aWindow,
-                           WorkerPrivate* aWorkerPrivate,
+                           SharedWorkerChild* aActor,
                            MessagePort* aMessagePort)
   : DOMEventTargetHelper(aWindow)
-  , mWorkerPrivate(aWorkerPrivate)
+  , mActor(aActor)
   , mMessagePort(aMessagePort)
   , mFrozen(false)
 {
   AssertIsOnMainThread();
-  MOZ_ASSERT(aWorkerPrivate);
+  MOZ_ASSERT(aActor);
   MOZ_ASSERT(aMessagePort);
 }
 
 SharedWorker::~SharedWorker()
 {
   AssertIsOnMainThread();
 }
 
@@ -54,39 +52,117 @@ SharedWorker::~SharedWorker()
 already_AddRefed<SharedWorker>
 SharedWorker::Constructor(const GlobalObject& aGlobal,
                           const nsAString& aScriptURL,
                           const StringOrWorkerOptions& aOptions,
                           ErrorResult& aRv)
 {
   AssertIsOnMainThread();
 
-  workerinternals::RuntimeService* rts =
-    workerinternals::RuntimeService::GetOrCreateService();
-  if (!rts) {
-    aRv = NS_ERROR_NOT_AVAILABLE;
+  nsCOMPtr<nsPIDOMWindowInner> window =
+    do_QueryInterface(aGlobal.GetAsSupports());
+  MOZ_ASSERT(window);
+
+  // If the window is blocked from accessing storage, do not allow it
+  // to connect to a SharedWorker.  This would potentially allow it
+  // to communicate with other windows that do have storage access.
+  // Allow private browsing, however, as we handle that isolation
+  // via the principal.
+  auto storageAllowed = nsContentUtils::StorageAllowedForWindow(window);
+  if (storageAllowed != nsContentUtils::StorageAccess::eAllow &&
+      storageAllowed != nsContentUtils::StorageAccess::ePrivateBrowsing) {
+    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return nullptr;
   }
 
+  // Assert that the principal private browsing state matches the
+  // StorageAccess value.
+#ifdef  MOZ_DIAGNOSTIC_ASSERT_ENABLED
+  if (storageAllowed == nsContentUtils::StorageAccess::ePrivateBrowsing) {
+    nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
+    nsCOMPtr<nsIPrincipal> principal = doc ? doc->NodePrincipal() : nullptr;
+    uint32_t privateBrowsingId = 0;
+    if (principal) {
+      MOZ_ALWAYS_SUCCEEDS(principal->GetPrivateBrowsingId(&privateBrowsingId));
+    }
+    MOZ_DIAGNOSTIC_ASSERT(privateBrowsingId != 0);
+  }
+#endif // MOZ_DIAGNOSTIC_ASSERT_ENABLED
+
   nsAutoString name;
   if (aOptions.IsString()) {
     name = aOptions.GetAsString();
   } else {
     MOZ_ASSERT(aOptions.IsWorkerOptions());
     name = aOptions.GetAsWorkerOptions().mName;
   }
 
-  RefPtr<SharedWorker> sharedWorker;
-  nsresult rv = rts->CreateSharedWorker(aGlobal, aScriptURL, name,
-                                        getter_AddRefs(sharedWorker));
-  if (NS_FAILED(rv)) {
-    aRv = rv;
+  JSContext* cx = aGlobal.Context();
+
+  WorkerLoadInfo loadInfo;
+  aRv = WorkerPrivate::GetLoadInfo(cx, window, nullptr, aScriptURL,
+                                   false, WorkerPrivate::OverrideLoadGroup,
+                                   WorkerTypeShared, &loadInfo);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return nullptr;
+  }
+
+  PrincipalInfo principalInfo;
+  aRv = PrincipalToPrincipalInfo(loadInfo.mPrincipal, &principalInfo);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return nullptr;
+  }
+
+  PrincipalInfo loadingPrincipalInfo;
+  aRv = PrincipalToPrincipalInfo(loadInfo.mLoadingPrincipal,
+                                 &loadingPrincipalInfo);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return nullptr;
+  }
+
+  // We don't actually care about this MessageChannel, but we use it to 'steal'
+  // its 2 connected ports.
+  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
+  RefPtr<MessageChannel> channel = MessageChannel::Constructor(global, aRv);
+  if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
+  MessagePortIdentifier portIdentifier;
+  channel->Port1()->CloneAndDisentangle(portIdentifier);
+
+  nsAutoCString resolvedScriptURL;
+  aRv = loadInfo.mResolvedScriptURI->GetSpec(resolvedScriptURL);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return nullptr;
+  }
+
+  nsAutoCString baseURL;
+  aRv = loadInfo.mBaseURI->GetSpec(baseURL);
+  if (NS_WARN_IF(aRv.Failed())) {
+    return nullptr;
+  }
+
+  // Register this component to PBackground.
+  PBackgroundChild* actorChild = BackgroundChild::GetOrCreateForCurrentThread();
+
+  SharedWorkerLoadInfo sharedWorkerLoadInfo(nsString(aScriptURL), baseURL,
+                                            resolvedScriptURL, name,
+                                            loadingPrincipalInfo, principalInfo,
+                                            loadInfo.mDomain, portIdentifier);
+
+  PSharedWorkerChild* pActor =
+    actorChild->SendPSharedWorkerConstructor(sharedWorkerLoadInfo);
+
+  RefPtr<SharedWorkerChild> actor = static_cast<SharedWorkerChild*>(pActor);
+  MOZ_ASSERT(actor);
+
+  RefPtr<SharedWorker> sharedWorker = new SharedWorker(window, actor,
+                                                       channel->Port2());
+
   return sharedWorker.forget();
 }
 
 MessagePort*
 SharedWorker::Port()
 {
   AssertIsOnMainThread();
   return mMessagePort;
@@ -148,17 +224,16 @@ SharedWorker::Close()
 }
 
 void
 SharedWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
                           const Sequence<JSObject*>& aTransferable,
                           ErrorResult& aRv)
 {
   AssertIsOnMainThread();
-  MOZ_ASSERT(mWorkerPrivate);
   MOZ_ASSERT(mMessagePort);
 
   mMessagePort->PostMessage(aCx, aMessage, aTransferable, aRv);
 }
 
 NS_IMPL_ADDREF_INHERITED(SharedWorker, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(SharedWorker, DOMEventTargetHelper)
 
--- a/dom/workers/sharedworkers/SharedWorker.h
+++ b/dom/workers/sharedworkers/SharedWorker.h
@@ -18,31 +18,32 @@
 class nsPIDOMWindowInner;
 
 namespace mozilla {
 class EventChainPreVisitor;
 
 namespace dom {
 class MessagePort;
 class StringOrWorkerOptions;
-class WorkerPrivate;
 class Event;
 
 namespace workerinternals {
 class RuntimeService;
 }
 
+class SharedWorkerChild;
+
 class SharedWorker final : public DOMEventTargetHelper
 {
   friend class workerinternals::RuntimeService;
 
   typedef mozilla::ErrorResult ErrorResult;
   typedef mozilla::dom::GlobalObject GlobalObject;
 
-  RefPtr<WorkerPrivate> mWorkerPrivate;
+  RefPtr<SharedWorkerChild> mActor;
   RefPtr<MessagePort> mMessagePort;
   nsTArray<RefPtr<Event>> mFrozenEvents;
   bool mFrozen;
 
 public:
   static already_AddRefed<SharedWorker>
   Constructor(const GlobalObject& aGlobal, const nsAString& aScriptURL,
               const StringOrWorkerOptions& aOptions, ErrorResult& aRv);
@@ -73,26 +74,20 @@ public:
 
   IMPL_EVENT_HANDLER(error)
 
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
 
-  WorkerPrivate*
-  GetWorkerPrivate() const
-  {
-    return mWorkerPrivate;
-  }
-
 private:
   // This class can only be created from the RuntimeService.
   SharedWorker(nsPIDOMWindowInner* aWindow,
-               WorkerPrivate* aWorkerPrivate,
+               SharedWorkerChild* aActor,
                MessagePort* aMessagePort);
 
   // This class is reference-counted and will be destroyed from Release().
   ~SharedWorker();
 
   // Only called by MessagePort.
   void
   PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
new file mode 100644
--- /dev/null
+++ b/dom/workers/sharedworkers/SharedWorkerChild.cpp
@@ -0,0 +1,19 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SharedWorkerChild.h"
+
+namespace mozilla {
+namespace dom {
+
+SharedWorkerChild::SharedWorkerChild()
+{
+}
+
+SharedWorkerChild::~SharedWorkerChild() = default;
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/workers/sharedworkers/SharedWorkerChild.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_dom_SharedWorkerChild_h
+#define mozilla_dom_dom_SharedWorkerChild_h
+
+#include "mozilla/dom/PSharedWorkerChild.h"
+#include "nsISupportsImpl.h"
+
+namespace mozilla {
+namespace dom {
+
+class SharedWorker;
+
+class SharedWorkerChild final : public mozilla::dom::PSharedWorkerChild
+{
+public:
+  NS_INLINE_DECL_REFCOUNTING(SharedWorkerChild)
+
+  SharedWorkerChild();
+
+private:
+  ~SharedWorkerChild();
+
+  void ActorDestroy(ActorDestroyReason aWhy) override;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_dom_SharedWorkerChild_h
new file mode 100644
--- /dev/null
+++ b/dom/workers/sharedworkers/SharedWorkerParent.cpp
@@ -0,0 +1,29 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SharedWorkerParent.h"
+
+namespace mozilla {
+
+using ipc::PrincipalInfo;
+
+namespace dom {
+
+SharedWorkerParent::SharedWorkerParent()
+{
+  // TODO
+}
+
+SharedWorkerParent::~SharedWorkerParent() = default;
+
+void
+SharedWorkerParent::ActorDestroy(IProtocol::ActorDestroyReason aReason)
+{
+  // TODO
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/workers/sharedworkers/SharedWorkerParent.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_dom_SharedWorkerParent_h
+#define mozilla_dom_dom_SharedWorkerParent_h
+
+#include "mozilla/dom/PSharedWorkerParent.h"
+#include "mozilla/ipc/BackgroundUtils.h"
+#include "nsISupportsImpl.h"
+
+namespace mozilla {
+namespace dom {
+
+class SharedWorkerParent final : public mozilla::dom::PSharedWorkerParent
+{
+public:
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedWorkerParent)
+
+  SharedWorkerParent();
+
+private:
+  ~SharedWorkerParent();
+
+  void
+  ActorDestroy(IProtocol::ActorDestroyReason aReason) override;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_dom_SharedWorkerParent_h
new file mode 100644
--- /dev/null
+++ b/dom/workers/sharedworkers/SharedWorkerTypes.ipdlh
@@ -0,0 +1,30 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+include DOMTypes;
+include PBackgroundSharedTypes;
+
+using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
+
+namespace mozilla {
+namespace dom {
+
+struct SharedWorkerLoadInfo
+{
+  nsString originalScriptURL;
+  nsCString baseScriptURL;
+  nsCString resolvedScriptURL;
+
+  nsString name;
+
+  PrincipalInfo loadingPrincipalInfo;
+  PrincipalInfo principalInfo;
+
+  nsCString domain;
+
+  MessagePortIdentifier portIdentifier;
+};
+
+} // namespace dom
+} // namespace mozilla
--- a/dom/workers/sharedworkers/moz.build
+++ b/dom/workers/sharedworkers/moz.build
@@ -1,17 +1,26 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS.mozilla.dom += [
     'SharedWorker.h',
+    'SharedWorkerChild.h',
+    'SharedWorkerParent.h',
 ]
 
 UNIFIED_SOURCES += [
     'SharedWorker.cpp',
+    'SharedWorkerChild.cpp',
+    'SharedWorkerParent.cpp',
+]
+
+IPDL_SOURCES += [
+    'PSharedWorker.ipdl',
+    'SharedWorkerTypes.ipdlh',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
--- a/ipc/glue/BackgroundChildImpl.cpp
+++ b/ipc/glue/BackgroundChildImpl.cpp
@@ -22,16 +22,17 @@
 #include "mozilla/dom/asmjscache/AsmJSCache.h"
 #include "mozilla/dom/cache/ActorUtils.h"
 #include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h"
 #include "mozilla/dom/indexedDB/PBackgroundIndexedDBUtilsChild.h"
 #include "mozilla/dom/ipc/IPCBlobInputStreamChild.h"
 #include "mozilla/dom/ipc/PendingIPCBlobChild.h"
 #include "mozilla/dom/ipc/TemporaryIPCBlobChild.h"
 #include "mozilla/dom/quota/PQuotaChild.h"
+#include "mozilla/dom/SharedWorkerChild.h"
 #include "mozilla/dom/StorageIPC.h"
 #include "mozilla/dom/GamepadEventChannelChild.h"
 #include "mozilla/dom/GamepadTestChannelChild.h"
 #include "mozilla/dom/LocalStorage.h"
 #include "mozilla/dom/MessagePortChild.h"
 #include "mozilla/dom/ServiceWorkerActors.h"
 #include "mozilla/dom/ServiceWorkerManagerChild.h"
 #include "mozilla/dom/TabChild.h"
@@ -283,16 +284,31 @@ BackgroundChildImpl::AllocPPendingIPCBlo
 
 bool
 BackgroundChildImpl::DeallocPPendingIPCBlobChild(PPendingIPCBlobChild* aActor)
 {
   delete aActor;
   return true;
 }
 
+dom::PSharedWorkerChild*
+BackgroundChildImpl::AllocPSharedWorkerChild(const dom::SharedWorkerLoadInfo& aInfo)
+{
+  RefPtr<dom::SharedWorkerChild> agent = new dom::SharedWorkerChild();
+  return agent.forget().take();
+}
+
+bool
+BackgroundChildImpl::DeallocPSharedWorkerChild(dom::PSharedWorkerChild* aActor)
+{
+  RefPtr<dom::SharedWorkerChild> actor =
+    dont_AddRef(static_cast<dom::SharedWorkerChild*>(aActor));
+  return true;
+}
+
 PTemporaryIPCBlobChild*
 BackgroundChildImpl::AllocPTemporaryIPCBlobChild()
 {
   MOZ_CRASH("This is not supposed to be called.");
   return nullptr;
 }
 
 bool
--- a/ipc/glue/BackgroundChildImpl.h
+++ b/ipc/glue/BackgroundChildImpl.h
@@ -109,16 +109,22 @@ protected:
   DeallocPIPCBlobInputStreamChild(PIPCBlobInputStreamChild* aActor) override;
 
   virtual PTemporaryIPCBlobChild*
   AllocPTemporaryIPCBlobChild() override;
 
   virtual bool
   DeallocPTemporaryIPCBlobChild(PTemporaryIPCBlobChild* aActor) override;
 
+  virtual mozilla::dom::PSharedWorkerChild*
+  AllocPSharedWorkerChild(const mozilla::dom::SharedWorkerLoadInfo& aInfo) override;
+
+  virtual bool
+  DeallocPSharedWorkerChild(mozilla::dom::PSharedWorkerChild* aActor) override;
+
   virtual PFileDescriptorSetChild*
   AllocPFileDescriptorSetChild(const FileDescriptor& aFileDescriptor)
                                override;
 
   virtual bool
   DeallocPFileDescriptorSetChild(PFileDescriptorSetChild* aActor) override;
 
   virtual PCamerasChild*
--- a/ipc/glue/BackgroundParentImpl.cpp
+++ b/ipc/glue/BackgroundParentImpl.cpp
@@ -30,16 +30,17 @@
 #include "mozilla/dom/asmjscache/AsmJSCache.h"
 #include "mozilla/dom/cache/ActorUtils.h"
 #include "mozilla/dom/indexedDB/ActorsParent.h"
 #include "mozilla/dom/ipc/IPCBlobInputStreamParent.h"
 #include "mozilla/dom/ipc/PendingIPCBlobParent.h"
 #include "mozilla/dom/ipc/TemporaryIPCBlobParent.h"
 #include "mozilla/dom/quota/ActorsParent.h"
 #include "mozilla/dom/simpledb/ActorsParent.h"
+#include "mozilla/dom/SharedWorkerParent.h"
 #include "mozilla/dom/StorageIPC.h"
 #include "mozilla/dom/MIDIManagerParent.h"
 #include "mozilla/dom/MIDIPortParent.h"
 #include "mozilla/dom/MIDIPlatformService.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/ipc/IPCStreamAlloc.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
@@ -381,16 +382,32 @@ BackgroundParentImpl::DeallocPPendingIPC
   AssertIsInMainProcess();
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aActor);
 
   delete aActor;
   return true;
 }
 
+mozilla::dom::PSharedWorkerParent*
+BackgroundParentImpl::AllocPSharedWorkerParent(const mozilla::dom::SharedWorkerLoadInfo& aInfo)
+{
+  RefPtr<dom::SharedWorkerParent> agent =
+    new mozilla::dom::SharedWorkerParent();
+  return agent.forget().take();
+}
+
+bool
+BackgroundParentImpl::DeallocPSharedWorkerParent(mozilla::dom::PSharedWorkerParent* aActor)
+{
+  RefPtr<mozilla::dom::SharedWorkerParent> actor =
+    dont_AddRef(static_cast<mozilla::dom::SharedWorkerParent*>(aActor));
+  return true;
+}
+
 PTemporaryIPCBlobParent*
 BackgroundParentImpl::AllocPTemporaryIPCBlobParent()
 {
   return new mozilla::dom::TemporaryIPCBlobParent();
 }
 
 mozilla::ipc::IPCResult
 BackgroundParentImpl::RecvPTemporaryIPCBlobConstructor(PTemporaryIPCBlobParent* aActor)
--- a/ipc/glue/BackgroundParentImpl.h
+++ b/ipc/glue/BackgroundParentImpl.h
@@ -128,16 +128,22 @@ protected:
   AllocPTemporaryIPCBlobParent() override;
 
   virtual mozilla::ipc::IPCResult
   RecvPTemporaryIPCBlobConstructor(PTemporaryIPCBlobParent* actor) override;
 
   virtual bool
   DeallocPTemporaryIPCBlobParent(PTemporaryIPCBlobParent* aActor) override;
 
+  virtual mozilla::dom::PSharedWorkerParent*
+  AllocPSharedWorkerParent(const mozilla::dom::SharedWorkerLoadInfo& aInfo) override;
+
+  virtual bool
+  DeallocPSharedWorkerParent(PSharedWorkerParent* aActor) override;
+
   virtual PFileDescriptorSetParent*
   AllocPFileDescriptorSetParent(const FileDescriptor& aFileDescriptor)
                                 override;
 
   virtual bool
   DeallocPFileDescriptorSetParent(PFileDescriptorSetParent* aActor)
                                   override;
 
--- a/ipc/glue/PBackground.ipdl
+++ b/ipc/glue/PBackground.ipdl
@@ -16,16 +16,17 @@ include protocol PCacheStreamControl;
 include protocol PClientManager;
 include protocol PFileDescriptorSet;
 include protocol PFileSystemRequest;
 include protocol PGamepadEventChannel;
 include protocol PGamepadTestChannel;
 include protocol PHttpBackgroundChannel;
 include protocol PIPCBlobInputStream;
 include protocol PPendingIPCBlob;
+include protocol PSharedWorker;
 include protocol PTemporaryIPCBlob;
 include protocol PMessagePort;
 include protocol PCameras;
 include protocol PMIDIManager;
 include protocol PMIDIPort;
 include protocol PQuota;
 include protocol PChildToParentStream;
 include protocol PParentToChildStream;
@@ -40,16 +41,17 @@ include protocol PVsync;
 include DOMTypes;
 include IPCBlob;
 include IPCServiceWorkerDescriptor;
 include IPCServiceWorkerRegistrationDescriptor;
 include PBackgroundSharedTypes;
 include PBackgroundIDBSharedTypes;
 include PFileSystemParams;
 include ProtocolTypes;
+include SharedWorkerTypes;
 include MIDITypes;
 
 include "mozilla/dom/cache/IPCUtils.h";
 include "mozilla/layers/LayersMessageUtils.h";
 
 using mozilla::dom::cache::Namespace
   from "mozilla/dom/cache/Types.h";
 
@@ -78,16 +80,17 @@ sync protocol PBackground
   manages PClientManager;
   manages PFileDescriptorSet;
   manages PFileSystemRequest;
   manages PGamepadEventChannel;
   manages PGamepadTestChannel;
   manages PHttpBackgroundChannel;
   manages PIPCBlobInputStream;
   manages PPendingIPCBlob;
+  manages PSharedWorker;
   manages PTemporaryIPCBlob;
   manages PMessagePort;
   manages PCameras;
   manages PMIDIManager;
   manages PMIDIPort;
   manages PQuota;
   manages PChildToParentStream;
   manages PParentToChildStream;
@@ -148,16 +151,18 @@ parent:
   async PGamepadEventChannel();
 
   async PGamepadTestChannel();
 
   async PHttpBackgroundChannel(uint64_t channelId);
 
   async PWebAuthnTransaction();
 
+  async PSharedWorker(SharedWorkerLoadInfo loadInfo);
+
   async PTemporaryIPCBlob();
 
   async PClientManager();
 
   async PMIDIManager();
   async PMIDIPort(MIDIPortInfo portInfo, bool sysexEnabled);
 
   // This method is used to propagate storage activities from the child actor