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 28506433e4f0
parent 373545 371e75eb2b60
child 373547 ddbbf8aa33dc
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);