Bug 1350637 - Part 7: Convert asynchronous StorageDBParent initialization to be synchronous and fix low disk space checking. r=asuth, a=lizzard
authorJan Varga <jan.varga@gmail.com>
Tue, 08 Aug 2017 23:01:56 +0200
changeset 421300 8267e1dbf9bc47c26b0f8bf382ab62f6e14b3790
parent 421299 e77772fae3c20104120b483890df521c6a3e51ce
child 421301 e78fed3a2212b824729b86b0ae917b745be98c81
push id7647
push userryanvm@gmail.com
push dateMon, 21 Aug 2017 19:15:39 +0000
treeherdermozilla-beta@6a2167880016 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth, lizzard
bugs1350637
milestone56.0
Bug 1350637 - Part 7: Convert asynchronous StorageDBParent initialization to be synchronous and fix low disk space checking. r=asuth, a=lizzard
dom/storage/StorageIPC.cpp
--- a/dom/storage/StorageIPC.cpp
+++ b/dom/storage/StorageIPC.cpp
@@ -478,81 +478,80 @@ StorageDBParent::ReleaseIPDLReference()
 {
   MOZ_ASSERT(mIPCOpen, "Attempting to release non-existent IPDL reference");
   mIPCOpen = false;
   Release();
 }
 
 namespace {
 
-class SendInitialChildDataRunnable : public Runnable
+class CheckLowDiskSpaceRunnable
+  : public Runnable
 {
+  nsCOMPtr<nsIEventTarget> mOwningEventTarget;
+  RefPtr<StorageDBParent> mParent;
+  bool mLowDiskSpace;
+
 public:
-  explicit SendInitialChildDataRunnable(StorageDBParent* aParent)
-    : Runnable("dom::SendInitialChildDataRunnable")
+  explicit CheckLowDiskSpaceRunnable(StorageDBParent* aParent)
+    : Runnable("dom::CheckLowDiskSpaceRunnable")
+    , mOwningEventTarget(GetCurrentThreadEventTarget())
     , mParent(aParent)
-  {}
+    , mLowDiskSpace(false)
+  {
+    AssertIsOnBackgroundThread();
+    MOZ_ASSERT(aParent);
+  }
 
 private:
   NS_IMETHOD Run() override
   {
-    if (!mParent->IPCOpen()) {
+    if (IsOnBackgroundThread()) {
+      MOZ_ASSERT(mParent);
+
+      if (!mParent->IPCOpen()) {
+        return NS_OK;
+      }
+
+      if (mLowDiskSpace) {
+        mozilla::Unused << mParent->SendObserve(
+          nsDependentCString("low-disk-space"), EmptyString(), EmptyCString());
+      }
+
+      mParent = nullptr;
+
       return NS_OK;
     }
 
-    mParent->Init();
+    MOZ_ASSERT(NS_IsMainThread());
 
-    StorageDBThread* storageThread = StorageDBThread::Get();
-    if (storageThread) {
-      InfallibleTArray<nsCString> scopes;
-      storageThread->GetOriginsHavingData(&scopes);
-      mozilla::Unused << mParent->SendOriginsHavingData(scopes);
-    }
-
-    // XXX Fix me!
-#if 0
-    // We need to check if the device is in a low disk space situation, so
-    // we can forbid in that case any write in localStorage.
     nsCOMPtr<nsIDiskSpaceWatcher> diskSpaceWatcher =
       do_GetService("@mozilla.org/toolkit/disk-space-watcher;1");
     if (!diskSpaceWatcher) {
       return NS_OK;
     }
 
-    bool lowDiskSpace = false;
-    diskSpaceWatcher->GetIsDiskFull(&lowDiskSpace);
+    diskSpaceWatcher->GetIsDiskFull(&mLowDiskSpace);
 
-    if (lowDiskSpace) {
-      mozilla::Unused << mParent->SendObserve(
-        nsDependentCString("low-disk-space"), EmptyString(), EmptyCString());
-    }
-#endif
+    MOZ_ALWAYS_SUCCEEDS(mOwningEventTarget->Dispatch(this, NS_DISPATCH_NORMAL));
 
     return NS_OK;
   }
-
-  RefPtr<StorageDBParent> mParent;
 };
 
 } // namespace
 
 StorageDBParent::StorageDBParent(const nsString& aProfilePath)
   : mProfilePath(aProfilePath)
   , mIPCOpen(false)
 {
   AssertIsOnBackgroundThread();
 
   // We are always open by IPC only
   AddIPDLReference();
-
-  // Cannot send directly from here since the channel
-  // is not completely built at this moment.
-  RefPtr<SendInitialChildDataRunnable> r =
-    new SendInitialChildDataRunnable(this);
-  NS_DispatchToCurrentThread(r);
 }
 
 StorageDBParent::~StorageDBParent()
 {
   AssertIsOnBackgroundThread();
 
   if (mObserverSink) {
     mObserverSink->Stop();
@@ -567,16 +566,31 @@ StorageDBParent::Init()
 
   PBackgroundParent* actor = Manager();
   MOZ_ASSERT(actor);
 
   if (BackgroundParent::IsOtherProcessActor(actor)) {
     mObserverSink = new ObserverSink(this);
     mObserverSink->Start();
   }
+
+  StorageDBThread* storageThread = StorageDBThread::Get();
+  if (storageThread) {
+    InfallibleTArray<nsCString> scopes;
+    storageThread->GetOriginsHavingData(&scopes);
+    mozilla::Unused << SendOriginsHavingData(scopes);
+  }
+
+  // We need to check if the device is in a low disk space situation, so
+  // we can forbid in that case any write in localStorage.
+
+  RefPtr<CheckLowDiskSpaceRunnable> runnable =
+    new CheckLowDiskSpaceRunnable(this);
+
+  MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
 }
 
 StorageDBParent::CacheParentBridge*
 StorageDBParent::NewCache(const nsACString& aOriginSuffix,
                           const nsACString& aOriginNoSuffix)
 {
   return new CacheParentBridge(this, aOriginSuffix, aOriginNoSuffix);
 }
@@ -1222,16 +1236,18 @@ AllocPBackgroundStorageParent(const nsSt
 
 mozilla::ipc::IPCResult
 RecvPBackgroundStorageConstructor(PBackgroundStorageParent* aActor,
                                   const nsString& aProfilePath)
 {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aActor);
 
+  auto* actor = static_cast<StorageDBParent*>(aActor);
+  actor->Init();
   return IPC_OK();
 }
 
 bool
 DeallocPBackgroundStorageParent(PBackgroundStorageParent* aActor)
 {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aActor);