Bug 1788986 - Part 4: Add a counter for nsIFile r=xpcom-reviewers,nika,barret,janv

This adds `count` out parameter for recursive file remove calls to report the number of the removed entries.

  Having a lot of files removed by `::Remove(recursive=true)` has been a problem, as a slow disk can cause a hang with such call. A counter feature will help us knowing the situation better via telemetry.

  The use of out parameter here is to mark it optional and prevent unwanted changes in existing callers (because a return value can't be optional).

Differential Revision: https://phabricator.services.mozilla.com/D156940
This commit is contained in:
Kagami Sascha Rosylight 2023-02-06 11:32:48 +00:00
Родитель bfa807408a
Коммит 0b2130674e
7 изменённых файлов: 39 добавлений и 15 удалений

Просмотреть файл

@ -5976,8 +5976,7 @@ Result<Ok, nsresult> DeleteFileManagerDirectory(
aOriginMetadata, Idempotency::Yes)));
}));
QM_TRY_RETURN(
MOZ_TO_RESULT_INVOKE_MEMBER(aFileManagerDirectory, Remove, false));
QM_TRY_RETURN(MOZ_TO_RESULT(aFileManagerDirectory.Remove(false)));
}
// Idempotently delete all the parts of an IndexedDB database including its

Просмотреть файл

@ -194,7 +194,7 @@ def paramlistAsNative(m, empty="void", return_param=True):
while (
paramIter >= 0
and m.params[paramIter].optional
and m.params[paramIter].paramtype == "out"
and "out" in m.params[paramIter].paramtype
):
t = m.params[paramIter].type
# Strings can't be optional, so this shouldn't happen, but let's make sure:

Просмотреть файл

@ -274,7 +274,9 @@ FileDescriptorFile::RenameToNative(nsIFile* aNewParentDir,
}
NS_IMETHODIMP
FileDescriptorFile::Remove(bool aRecursive) { return NS_ERROR_NOT_IMPLEMENTED; }
FileDescriptorFile::Remove(bool aRecursive, uint32_t* aRemoveCount) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
FileDescriptorFile::GetPermissions(uint32_t* aPermissions) {

Просмотреть файл

@ -232,9 +232,13 @@ interface nsIFile : nsISupports
* This will try to delete this file. The 'recursive' flag
* must be PR_TRUE to delete directories which are not empty.
*
* If passed, 'removeCount' will be incremented by the total number of files
* and/or directories removed. Will be 1 unless the 'recursive' flag is
* set. The parameter must be initialized beforehand.
*
* This will not resolve any symlinks.
*/
void remove(in boolean recursive);
void remove(in boolean recursive, [optional] inout uint32_t removeCount);
/**
* Attributes of nsIFile.

Просмотреть файл

@ -1101,7 +1101,7 @@ nsLocalFile::MoveToFollowingLinksNative(nsIFile* aNewParent,
}
NS_IMETHODIMP
nsLocalFile::Remove(bool aRecursive) {
nsLocalFile::Remove(bool aRecursive, uint32_t* aRemoveCount) {
CHECK_mPath();
ENSURE_STAT_CACHE();
@ -1113,7 +1113,11 @@ nsLocalFile::Remove(bool aRecursive) {
}
if (isSymLink || !S_ISDIR(mCachedStat.st_mode)) {
return NSRESULT_FOR_RETURN(unlink(mPath.get()));
rv = NSRESULT_FOR_RETURN(unlink(mPath.get()));
if (NS_SUCCEEDED(rv) && aRemoveCount) {
*aRemoveCount += 1;
}
return rv;
}
if (aRecursive) {
@ -1138,7 +1142,9 @@ nsLocalFile::Remove(bool aRecursive) {
if (NS_FAILED(rv)) {
return NS_ERROR_FAILURE;
}
rv = file->Remove(aRecursive);
// XXX: We care the result of the removal here while
// nsLocalFileWin does not. We should align the behavior. (bug 1779696)
rv = file->Remove(aRecursive, aRemoveCount);
#ifdef ANDROID
// See bug 580434 - Bionic gives us just deleted files
@ -1152,7 +1158,11 @@ nsLocalFile::Remove(bool aRecursive) {
}
}
return NSRESULT_FOR_RETURN(rmdir(mPath.get()));
rv = NSRESULT_FOR_RETURN(rmdir(mPath.get()));
if (NS_SUCCEEDED(rv) && aRemoveCount) {
*aRemoveCount += 1;
}
return rv;
}
nsresult nsLocalFile::GetTimeImpl(PRTime* aTime,

Просмотреть файл

@ -2287,7 +2287,7 @@ nsLocalFile::Load(PRLibrary** aResult) {
}
NS_IMETHODIMP
nsLocalFile::Remove(bool aRecursive) {
nsLocalFile::Remove(bool aRecursive, uint32_t* aRemoveCount) {
// NOTE:
//
// if the working path points to a shortcut, then we will only
@ -2340,9 +2340,11 @@ nsLocalFile::Remove(bool aRecursive) {
return rv;
}
// XXX: We are ignoring the result of the removal here while
// nsLocalFileUnix does not. We should align the behavior. (bug 1779696)
nsCOMPtr<nsIFile> file;
while (NS_SUCCEEDED(dirEnum->GetNextFile(getter_AddRefs(file))) && file) {
file->Remove(aRecursive);
file->Remove(aRecursive, aRemoveCount);
}
}
if (RemoveDirectoryW(mWorkingPath.get()) == 0) {
@ -2354,6 +2356,10 @@ nsLocalFile::Remove(bool aRecursive) {
}
}
if (aRemoveCount) {
*aRemoveCount += 1;
}
MakeDirty();
return rv;
}

Просмотреть файл

@ -201,7 +201,8 @@ static bool TestDeleteOnClose(nsIFile* aBase, const char* aName, int32_t aFlags,
}
// Test nsIFile::Remove, verifying that the file does not exist and did before
static bool TestRemove(nsIFile* aBase, const char* aName, bool aRecursive) {
static bool TestRemove(nsIFile* aBase, const char* aName, bool aRecursive,
uint32_t aExpectedRemoveCount = 1) {
nsCOMPtr<nsIFile> file = NewFile(aBase);
if (!file) return false;
@ -217,8 +218,10 @@ static bool TestRemove(nsIFile* aBase, const char* aName, bool aRecursive) {
return false;
}
rv = file->Remove(aRecursive);
uint32_t removeCount = 0;
rv = file->Remove(aRecursive, &removeCount);
if (!VerifyResult(rv, "Remove")) return false;
EXPECT_EQ(removeCount, aExpectedRemoveCount) << "Removal count was wrong";
rv = file->Exists(&exists);
if (!VerifyResult(rv, "Exists (after)")) return false;
@ -489,7 +492,7 @@ static void SetupAndTestFunctions(const nsAString& aDirName,
// Test moving across directories and renaming at the same time
ASSERT_TRUE(TestMove(subdir, base, "file2.txt", "file4.txt"));
// Test copying across directoreis
// Test copying across directories
ASSERT_TRUE(TestCopy(base, subdir, "file4.txt", "file5.txt"));
if (aTestNormalize) {
@ -498,7 +501,7 @@ static void SetupAndTestFunctions(const nsAString& aDirName,
}
// Test recursive directory removal
ASSERT_TRUE(TestRemove(base, "subdir", true));
ASSERT_TRUE(TestRemove(base, "subdir", true, 2));
if (aTestCreateUnique) {
ASSERT_TRUE(TestCreateUnique(base, "foo", nsIFile::NORMAL_FILE_TYPE, 0600));