Bug 1350637 - Part 7: Convert asynchronous StorageDBParent initialization to be synchronous and fix low disk space checking; r=asuth
authorJan Varga <jan.varga@gmail.com>
Tue, 08 Aug 2017 23:01:56 +0200
changeset 373546 28506433e4f03f5c1d2f42fc59c4f86af6da3181
parent 373545 371e75eb2b60281508ef8f7535bdda3964975921
child 373547 ddbbf8aa33dca6011c81dde0ecf4002bbfb4eb4f
push id32304
push usercbook@mozilla.com
push dateWed, 09 Aug 2017 09:37:21 +0000
treeherdermozilla-central@4c5fbf493763 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1350637
milestone57.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 1350637 - Part 7: Convert asynchronous StorageDBParent initialization to be synchronous and fix low disk space checking; r=asuth
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);