summaryrefslogtreecommitdiffstats
path: root/dom/cache
diff options
context:
space:
mode:
Diffstat (limited to 'dom/cache')
-rw-r--r--dom/cache/CacheChild.cpp2
-rw-r--r--dom/cache/CacheStorageChild.cpp2
-rw-r--r--dom/cache/CacheStreamControlParent.cpp4
-rw-r--r--dom/cache/CacheStreamControlParent.h5
-rw-r--r--dom/cache/Connection.cpp3
-rw-r--r--dom/cache/StreamList.cpp10
-rw-r--r--dom/cache/test/marionette/test_caches_delete_cleanup_after_shutdown.py116
7 files changed, 77 insertions, 65 deletions
diff --git a/dom/cache/CacheChild.cpp b/dom/cache/CacheChild.cpp
index c822653fea..05f25ec838 100644
--- a/dom/cache/CacheChild.cpp
+++ b/dom/cache/CacheChild.cpp
@@ -112,7 +112,7 @@ void CacheChild::NoteDeletedActor() {
// CacheOpChilds when StartDestroy was called from WorkerRef notification. If
// the last CacheOpChild is getting destructed; it's the time for us to
// SendTearDown to the other side.
- if (NumChildActors() == 1 && mDelayedDestroy && !mLocked) DestroyInternal();
+ if (NumChildActors() == 0 && mDelayedDestroy && !mLocked) DestroyInternal();
}
already_AddRefed<PCacheOpChild> CacheChild::AllocPCacheOpChild(
diff --git a/dom/cache/CacheStorageChild.cpp b/dom/cache/CacheStorageChild.cpp
index e7918bbf88..e344e2c272 100644
--- a/dom/cache/CacheStorageChild.cpp
+++ b/dom/cache/CacheStorageChild.cpp
@@ -88,7 +88,7 @@ void CacheStorageChild::NoteDeletedActor() {
// when StartDestroy was called from WorkerRef notification. If the last
// CacheOpChild is getting destructed; it's the time for us to SendTearDown to
// the other side.
- if (NumChildActors() == 1 && mDelayedDestroy) DestroyInternal();
+ if (NumChildActors() == 0 && mDelayedDestroy) DestroyInternal();
}
void CacheStorageChild::ActorDestroy(ActorDestroyReason aReason) {
diff --git a/dom/cache/CacheStreamControlParent.cpp b/dom/cache/CacheStreamControlParent.cpp
index aaab59f944..8441d5cee4 100644
--- a/dom/cache/CacheStreamControlParent.cpp
+++ b/dom/cache/CacheStreamControlParent.cpp
@@ -149,9 +149,11 @@ void CacheStreamControlParent::SetStreamList(
void CacheStreamControlParent::CloseAll() {
NS_ASSERT_OWNINGTHREAD(CacheStreamControlParent);
- NotifyCloseAll();
QM_WARNONLY_TRY(OkIf(SendCloseAll()));
+
+ // Attention: NotifyCloseAll potentially destroys our this synchronously!
+ NotifyCloseAll();
}
void CacheStreamControlParent::Shutdown() {
diff --git a/dom/cache/CacheStreamControlParent.h b/dom/cache/CacheStreamControlParent.h
index 46fe834309..332c08487b 100644
--- a/dom/cache/CacheStreamControlParent.h
+++ b/dom/cache/CacheStreamControlParent.h
@@ -25,7 +25,12 @@ class CacheStreamControlParent final : public PCacheStreamControlParent,
CacheStreamControlParent();
void SetStreamList(SafeRefPtr<StreamList> aStreamList);
+
+ // Will close all streams. May synchronously free our this, see
+ // inherited StreamControl::CloseAllReadStreams.
void CloseAll();
+
+ // Implicitly called when the last stream goes away.
void Shutdown();
// StreamControl methods
diff --git a/dom/cache/Connection.cpp b/dom/cache/Connection.cpp
index e9c9becebc..f7afca0d7a 100644
--- a/dom/cache/Connection.cpp
+++ b/dom/cache/Connection.cpp
@@ -288,7 +288,8 @@ uint32_t Connection::DecreaseTransactionNestingLevel(
NS_IMETHODIMP
Connection::BackupToFileAsync(nsIFile* aDestinationFile,
- mozIStorageCompletionCallback* aCallback) {
+ mozIStorageCompletionCallback* aCallback,
+ uint32_t aPagesPerStep, uint32_t aStepDelayMs) {
// async methods are not supported
return NS_ERROR_NOT_IMPLEMENTED;
}
diff --git a/dom/cache/StreamList.cpp b/dom/cache/StreamList.cpp
index cbce695b60..00dd3b585f 100644
--- a/dom/cache/StreamList.cpp
+++ b/dom/cache/StreamList.cpp
@@ -136,13 +136,9 @@ void StreamList::CloseAll() {
NS_ASSERT_OWNINGTHREAD(StreamList);
if (mStreamControl && mStreamControl->CanSend()) {
- auto* streamControl = std::exchange(mStreamControl, nullptr);
-
- streamControl->CloseAll();
-
- mStreamControl = std::exchange(streamControl, nullptr);
-
- mStreamControl->Shutdown();
+ // CloseAll will kick off everything needed for shutdown.
+ // mStreamControl may go away immediately or async.
+ mStreamControl->CloseAll();
} else {
// We cannot interact with the child, let's just clear our lists of
// streams to unblock shutdown.
diff --git a/dom/cache/test/marionette/test_caches_delete_cleanup_after_shutdown.py b/dom/cache/test/marionette/test_caches_delete_cleanup_after_shutdown.py
index 4db7606b08..2923deeffe 100644
--- a/dom/cache/test/marionette/test_caches_delete_cleanup_after_shutdown.py
+++ b/dom/cache/test/marionette/test_caches_delete_cleanup_after_shutdown.py
@@ -2,6 +2,8 @@
# 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/.
+import os
+
from marionette_driver import Wait
from marionette_harness import MarionetteTestCase
@@ -13,6 +15,8 @@ from marionette_harness import MarionetteTestCase
fail if we fail to delete all of the 5,000 1k files we create on disk
as part of the test.
"""
+QM_TESTING_PREF = "dom.quotaManager.testing"
+
EXPECTED_CACHEDIR_SIZE_AFTER_CLEANUP = 128 * 1024 # 128KB
CACHE_ID = "data"
@@ -31,10 +35,12 @@ class CachesDeleteCleanupAtShutdownTestCase(MarionetteTestCase):
def setUp(self):
super(CachesDeleteCleanupAtShutdownTestCase, self).setUp()
self.marionette.restart(in_app=False, clean=True)
+ self.marionette.set_pref(QM_TESTING_PREF, True)
def tearDown(self):
self.marionette.restart(in_app=False, clean=True)
super(CachesDeleteCleanupAtShutdownTestCase, self).tearDown()
+ self.marionette.set_pref(QM_TESTING_PREF, False)
def getUsage(self):
return self.marionette.execute_script(
@@ -71,56 +77,45 @@ class CachesDeleteCleanupAtShutdownTestCase(MarionetteTestCase):
script_args=(CACHE_ID,),
)
+ def countBodies(self):
+ profile = self.marionette.instance.profile.profile
+ originDir = (
+ self.marionette.absolute_url("")[:-1].replace(":", "+").replace("/", "+")
+ )
+ morgueDir = f"{profile}/storage/default/{originDir}/cache/morgue"
+ print("morgueDir path = ", morgueDir)
+
+ bodyCount = -1
+ if os.path.exists(morgueDir):
+ bodyCount = 0
+ for elem in os.listdir(morgueDir):
+ absPathElem = os.path.join(morgueDir, elem)
+ if os.path.isdir(absPathElem):
+ bodyCount += sum(
+ 1
+ for e in os.listdir(absPathElem)
+ if os.path.isfile(os.path.join(absPathElem, e))
+ )
+ return bodyCount
+
def ensureCleanDirectory(self):
+ orphanedBodiesCount = self.countBodies()
+ return orphanedBodiesCount <= 0
+
+ def isStorageInitialized(self, temporary=False):
with self.marionette.using_context("chrome"):
- return self.marionette.execute_script(
+ return self.marionette.execute_async_script(
+ """
+ const [resolve] = arguments;
+ const req = %s;
+ req.callback = () => {
+ resolve(req.resultCode == Cr.NS_OK && req.result)
+ };
"""
- let originDir = arguments[0];
- const pathDelimiter = "/";
-
- function getRelativeFile(relativePath) {
- let file = Services.dirsvc
- .get("ProfD", Ci.nsIFile)
- .clone();
-
- relativePath.split(pathDelimiter).forEach(function(component) {
- if (component == "..") {
- file = file.parent;
- } else {
- file.append(component);
- }
- });
-
- return file;
- }
-
- function getCacheDir() {
-
- const storageDirName = "storage";
- const defaultPersistenceDirName = "default";
-
- return getRelativeFile(
- `${storageDirName}/${defaultPersistenceDirName}/${originDir}/cache`
- );
- }
-
- const cacheDir = getCacheDir();
- let morgueDir = cacheDir.clone();
-
- // morgue directory should be empty
- // or atleast directories under morgue should be empty
- morgueDir.append("morgue");
- for (let dir of morgueDir.directoryEntries) {
- for (let file of dir.directoryEntries) {
- return false;
- }
- }
- return true;
- """,
- script_args=(
- self.marionette.absolute_url("")[:-1]
- .replace(":", "+")
- .replace("/", "+"),
+ % (
+ "Services.qms.temporaryStorageInitialized()"
+ if temporary
+ else "Services.qms.storageInitialized()"
),
new_sandbox=False,
)
@@ -128,6 +123,7 @@ class CachesDeleteCleanupAtShutdownTestCase(MarionetteTestCase):
def create_and_cleanup_cache(self, ensureCleanCallback, in_app):
# create 640 cache entries
self.doCacheWork(640)
+ print("usage after doCacheWork = ", self.getUsage())
self.marionette.restart(in_app=in_app)
print("restart successful")
@@ -137,6 +133,14 @@ class CachesDeleteCleanupAtShutdownTestCase(MarionetteTestCase):
)
return ensureCleanCallback()
+ def afterCleanupClosure(self, usage):
+ print(
+ f"Storage initialized = {self.isStorageInitialized()}, temporary storage initialized = {self.isStorageInitialized(True)}"
+ )
+
+ print(f"Usage = {usage} and number of orphaned bodies = {self.countBodies()}")
+ return usage < EXPECTED_CACHEDIR_SIZE_AFTER_CLEANUP
+
def test_ensure_cache_cleanup_after_clean_restart(self):
self.marionette.navigate(
self.marionette.absolute_url("dom/cache/cacheUsage.html")
@@ -144,9 +148,8 @@ class CachesDeleteCleanupAtShutdownTestCase(MarionetteTestCase):
beforeUsage = self.getUsage()
def ensureCleanCallback():
- Wait(self.marionette, timeout=60).until(
- lambda x: (self.getUsage() - beforeUsage)
- < EXPECTED_CACHEDIR_SIZE_AFTER_CLEANUP,
+ Wait(self.marionette, interval=1, timeout=60).until(
+ lambda _: self.afterCleanupClosure(self.getUsage() - beforeUsage),
message="Cache directory is not cleaned up properly",
)
@@ -164,14 +167,19 @@ class CachesDeleteCleanupAtShutdownTestCase(MarionetteTestCase):
self.marionette.navigate(
self.marionette.absolute_url("dom/cache/cacheUsage.html")
)
+
+ print(f"profile path = {self.marionette.instance.profile.profile}")
+
beforeUsage = self.getUsage()
def ensureCleanCallback():
- self.openCache()
+ print(
+ f"ensureCleanCallback, profile path = {self.marionette.instance.profile.profile}"
+ )
- Wait(self.marionette, timeout=60).until(
- lambda x: (self.getUsage() - beforeUsage)
- < EXPECTED_CACHEDIR_SIZE_AFTER_CLEANUP,
+ self.openCache()
+ Wait(self.marionette, interval=1, timeout=60).until(
+ lambda _: self.afterCleanupClosure(self.getUsage() - beforeUsage),
message="Cache directory is not cleaned up properly",
)