Bug 1534208 - LSNG: DOM File thread and PBackground child for it must be created as soon as possible; r=asuth
authorJan Varga <jan.varga@gmail.com>
Mon, 11 Mar 2019 15:35:04 +0100
changeset 521360 52b03bc3489944b2f695b79754615edf7d38bd27
parent 521359 3a116fa47aff225e3760e3ec4fd6cf12e9721fdb
child 521361 0dd9653849e21017c8d8a81879d41ec8a8b6a655
child 521439 e2b7138d7c24c2be4985e8d0acbeab2ecf387b18
push id10866
push usernerli@mozilla.com
push dateTue, 12 Mar 2019 18:59:09 +0000
treeherdermozilla-beta@445c24a51727 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1534208
milestone67.0a1
first release with
nightly linux32
52b03bc34899 / 67.0a1 / 20190311215435 / files
nightly linux64
52b03bc34899 / 67.0a1 / 20190311215435 / files
nightly mac
52b03bc34899 / 67.0a1 / 20190311215435 / files
nightly win32
52b03bc34899 / 67.0a1 / 20190311215435 / files
nightly win64
52b03bc34899 / 67.0a1 / 20190311215435 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1534208 - LSNG: DOM File thread and PBackground child for it must be created as soon as possible; r=asuth Differential Revision: https://phabricator.services.mozilla.com/D22976
dom/file/ipc/IPCBlobInputStreamThread.cpp
dom/file/ipc/IPCBlobInputStreamThread.h
dom/ipc/ContentChild.cpp
dom/localstorage/LSObject.cpp
dom/localstorage/LSObject.h
--- a/dom/file/ipc/IPCBlobInputStreamThread.cpp
+++ b/dom/file/ipc/IPCBlobInputStreamThread.cpp
@@ -82,16 +82,27 @@ bool IPCBlobInputStreamThread::IsOnFileE
     nsIEventTarget* aEventTarget) {
   MOZ_ASSERT(aEventTarget);
 
   mozilla::StaticMutexAutoLock lock(gIPCBlobThreadMutex);
   return gIPCBlobThread && aEventTarget == gIPCBlobThread->mThread;
 }
 
 /* static */
+IPCBlobInputStreamThread* IPCBlobInputStreamThread::Get() {
+  mozilla::StaticMutexAutoLock lock(gIPCBlobThreadMutex);
+
+  if (gShutdownHasStarted) {
+    return nullptr;
+  }
+
+  return gIPCBlobThread;
+}
+
+/* static */
 IPCBlobInputStreamThread* IPCBlobInputStreamThread::GetOrCreate() {
   mozilla::StaticMutexAutoLock lock(gIPCBlobThreadMutex);
 
   if (gShutdownHasStarted) {
     return nullptr;
   }
 
   if (!gIPCBlobThread) {
--- a/dom/file/ipc/IPCBlobInputStreamThread.h
+++ b/dom/file/ipc/IPCBlobInputStreamThread.h
@@ -22,16 +22,18 @@ class IPCBlobInputStreamThread final : p
                                        public nsIEventTarget {
  public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIOBSERVER
   NS_DECL_NSIEVENTTARGET
 
   static bool IsOnFileEventTarget(nsIEventTarget* aEventTarget);
 
+  static IPCBlobInputStreamThread* Get();
+
   static IPCBlobInputStreamThread* GetOrCreate();
 
   void MigrateActor(IPCBlobInputStreamChild* aActor);
 
   bool Initialize();
 
   void InitializeOnMainThread();
 
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1183,16 +1183,18 @@ void ContentChild::InitXPCOM(
   BackgroundChild::Startup();
 
   PBackgroundChild* actorChild = BackgroundChild::GetOrCreateForCurrentThread();
   if (NS_WARN_IF(!actorChild)) {
     MOZ_ASSERT_UNREACHABLE("PBackground init can't fail at this point");
     return;
   }
 
+  LSObject::Initialize();
+
   ClientManager::Startup();
 
   RemoteWorkerService::Initialize();
 
   nsCOMPtr<nsIConsoleService> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
   if (!svc) {
     NS_WARNING("Couldn't acquire console service");
     return;
--- a/dom/localstorage/LSObject.cpp
+++ b/dom/localstorage/LSObject.cpp
@@ -191,16 +191,44 @@ LSObject::LSObject(nsPIDOMWindowInner* a
 
 LSObject::~LSObject() {
   AssertIsOnOwningThread();
 
   DropObserver();
 }
 
 // static
+void LSObject::Initialize() {
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsCOMPtr<nsIEventTarget> domFileThread =
+      IPCBlobInputStreamThread::GetOrCreate();
+  if (NS_WARN_IF(!domFileThread)) {
+    return;
+  }
+
+  RefPtr<Runnable> runnable =
+      NS_NewRunnableFunction("LSObject::Initialize", []() {
+        AssertIsOnDOMFileThread();
+
+        PBackgroundChild* backgroundActor =
+            BackgroundChild::GetOrCreateForCurrentThread();
+
+        if (NS_WARN_IF(!backgroundActor)) {
+          return;
+        }
+      });
+
+  if (NS_WARN_IF(NS_FAILED(domFileThread->Dispatch(runnable,
+                                                   NS_DISPATCH_NORMAL)))) {
+    return;
+  }
+}
+
+// static
 nsresult LSObject::CreateForWindow(nsPIDOMWindowInner* aWindow,
                                    Storage** aStorage) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aWindow);
   MOZ_ASSERT(aStorage);
   MOZ_ASSERT(NextGenLocalStorageEnabled());
   MOZ_ASSERT(nsContentUtils::StorageAllowedForWindow(aWindow) >
              nsContentUtils::StorageAccess::eDeny);
@@ -386,18 +414,19 @@ void LSObject::OnSyncMessageHandled() {
   gPendingSyncMessage = false;
 }
 
 LSRequestChild* LSObject::StartRequest(nsIEventTarget* aMainEventTarget,
                                        const LSRequestParams& aParams,
                                        LSRequestChildCallback* aCallback) {
   AssertIsOnDOMFileThread();
 
-  PBackgroundChild* backgroundActor =
-      BackgroundChild::GetOrCreateForCurrentThread(aMainEventTarget);
+  PBackgroundChild* backgroundActor = XRE_IsParentProcess() ?
+      BackgroundChild::GetOrCreateForCurrentThread(aMainEventTarget) :
+      BackgroundChild::GetForCurrentThread();
   if (NS_WARN_IF(!backgroundActor)) {
     return nullptr;
   }
 
   LSRequestChild* actor = new LSRequestChild(aCallback);
 
   backgroundActor->SendPBackgroundLSRequestConstructor(actor, aParams);
 
@@ -1013,18 +1042,19 @@ nsresult RequestHelper::StartAndReturnRe
 
     const nsLocalExecutionGuard localExecution(thread->EnterLocalExecution());
     mNestedEventTarget = localExecution.GetEventTarget();
     MOZ_ASSERT(mNestedEventTarget);
 
     mNestedEventTargetWrapper =
         new NestedEventTargetWrapper(mNestedEventTarget);
 
-    nsCOMPtr<nsIEventTarget> domFileThread =
-        IPCBlobInputStreamThread::GetOrCreate();
+    nsCOMPtr<nsIEventTarget> domFileThread = XRE_IsParentProcess() ?
+        IPCBlobInputStreamThread::GetOrCreate() :
+        IPCBlobInputStreamThread::Get();
     if (NS_WARN_IF(!domFileThread)) {
       return NS_ERROR_FAILURE;
     }
 
     nsresult rv;
 
     {
       {
--- a/dom/localstorage/LSObject.h
+++ b/dom/localstorage/LSObject.h
@@ -69,16 +69,18 @@ class LSObject final : public Storage {
   Maybe<nsID> mClientId;
   nsCString mOrigin;
   nsCString mOriginKey;
   nsString mDocumentURI;
 
   bool mInExplicitSnapshot;
 
  public:
+  static void Initialize();
+
   /**
    * The normal creation path invoked by nsGlobalWindowInner.
    */
   static nsresult CreateForWindow(nsPIDOMWindowInner* aWindow,
                                   Storage** aStorage);
 
   /**
    * nsIDOMStorageManager creation path for use in testing logic.  Supports the