Commit f3d631ab authored by Jan Varga's avatar Jan Varga
Browse files

Bug 1182987 - Part 1: Remove unreferenced files immediately; r=baku

parent 2c1e594f
Loading
Loading
Loading
Loading
+91 −1
Original line number Diff line number Diff line
@@ -10678,7 +10678,7 @@ UpdateRefcountFunction::DidCommit()
                 js::ProfileEntry::Category::STORAGE);
  for (auto iter = mFileInfoEntries.ConstIter(); !iter.Done(); iter.Next()) {
    auto value = iter.Data();
    FileInfoEntry* value = iter.Data();
    MOZ_ASSERT(value);
@@ -10760,9 +10760,94 @@ UpdateRefcountFunction::Reset()
  MOZ_ASSERT(!mSavepointEntriesIndex.Count());
  MOZ_ASSERT(!mInSavepoint);
  class MOZ_STACK_CLASS CustomCleanupCallback final
    : public FileInfo::CustomCleanupCallback
  {
    nsCOMPtr<nsIFile> mDirectory;
    nsCOMPtr<nsIFile> mJournalDirectory;
  public:
    virtual nsresult
    Cleanup(FileManager* aFileManager, int64_t aId)
    {
      if (!mDirectory) {
        MOZ_ASSERT(!mJournalDirectory);
        mDirectory = aFileManager->GetDirectory();
        if (NS_WARN_IF(!mDirectory)) {
          return NS_ERROR_FAILURE;
        }
        mJournalDirectory = aFileManager->GetJournalDirectory();
        if (NS_WARN_IF(!mJournalDirectory)) {
          return NS_ERROR_FAILURE;
        }
      }
      nsCOMPtr<nsIFile> file = aFileManager->GetFileForId(mDirectory, aId);
      if (NS_WARN_IF(!file)) {
        return NS_ERROR_FAILURE;
      }
      nsresult rv;
      int64_t fileSize;
      if (aFileManager->EnforcingQuota()) {
        rv = file->GetFileSize(&fileSize);
        if (NS_WARN_IF(!file)) {
          return NS_ERROR_FAILURE;
        }
      }
      rv = file->Remove(false);
      if (NS_WARN_IF(NS_FAILED(rv))) {
        return rv;
      }
      if (aFileManager->EnforcingQuota()) {
        QuotaManager* quotaManager = QuotaManager::Get();
        MOZ_ASSERT(quotaManager);
        quotaManager->DecreaseUsageForOrigin(aFileManager->Type(),
                                             aFileManager->Group(),
                                             aFileManager->Origin(),
                                             fileSize);
      }
      file = aFileManager->GetFileForId(mJournalDirectory, aId);
      if (NS_WARN_IF(!file)) {
        return NS_ERROR_FAILURE;
      }
      rv = file->Remove(false);
      if (NS_WARN_IF(NS_FAILED(rv))) {
        return rv;
      }
      return NS_OK;
    }
  };
  mJournalsToCreateBeforeCommit.Clear();
  mJournalsToRemoveAfterCommit.Clear();
  mJournalsToRemoveAfterAbort.Clear();
  // FileInfo implementation automatically removes unreferenced files, but it's
  // done asynchronously and with a delay. We want to remove them (and decrease
  // quota usage) before we fire the commit event.
  for (auto iter = mFileInfoEntries.ConstIter(); !iter.Done(); iter.Next()) {
    FileInfoEntry* value = iter.Data();
    MOZ_ASSERT(value);
    FileInfo* fileInfo = value->mFileInfo.forget().take();
    MOZ_ASSERT(fileInfo);
    CustomCleanupCallback customCleanupCallback;
    fileInfo->Release(&customCleanupCallback);
  }
  mFileInfoEntries.Clear();
}
@@ -24967,6 +25052,11 @@ ObjectStoreAddOrPutRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
              return rv;
            }
            rv2 = journalFile->Remove(false);
            if (NS_WARN_IF(NS_FAILED(rv2))) {
              return rv;
            }
            if (mFileManager->EnforcingQuota()) {
              QuotaManager* quotaManager = QuotaManager::Get();
              MOZ_ASSERT(quotaManager);
+10 −2
Original line number Diff line number Diff line
@@ -130,7 +130,8 @@ FileInfo::GetReferences(int32_t* aRefCnt,

void
FileInfo::UpdateReferences(ThreadSafeAutoRefCnt& aRefCount,
                           int32_t aDelta)
                           int32_t aDelta,
                           CustomCleanupCallback* aCustomCleanupCallback)
{
  // XXX This can go away once DOM objects no longer hold FileInfo objects...
  //     Looking at you, BlobImplBase...
@@ -169,8 +170,15 @@ FileInfo::UpdateReferences(ThreadSafeAutoRefCnt& aRefCount,
  }

  if (needsCleanup) {
    if (aCustomCleanupCallback) {
      nsresult rv = aCustomCleanupCallback->Cleanup(mFileManager, Id());
      if (NS_FAILED(rv)) {
        NS_WARNING("Custom cleanup failed!");
      }
    } else {
      Cleanup();
    }
  }

  delete this;
}
+17 −3
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ class FileInfo
  RefPtr<FileManager> mFileManager;

public:
  class CustomCleanupCallback;

  static
  FileInfo* Create(FileManager* aFileManager, int64_t aId);

@@ -39,9 +41,9 @@ public:
  }

  void
  Release()
  Release(CustomCleanupCallback* aCustomCleanupCallback = nullptr)
  {
    UpdateReferences(mRefCnt, -1);
    UpdateReferences(mRefCnt, -1, aCustomCleanupCallback);
  }

  void
@@ -74,7 +76,8 @@ protected:
private:
  void
  UpdateReferences(ThreadSafeAutoRefCnt& aRefCount,
                   int32_t aDelta);
                   int32_t aDelta,
                   CustomCleanupCallback* aCustomCleanupCallback = nullptr);

  bool
  LockedClearDBRefs();
@@ -83,6 +86,17 @@ private:
  Cleanup();
};

class NS_NO_VTABLE FileInfo::CustomCleanupCallback
{
public:
  virtual nsresult
  Cleanup(FileManager* aFileManager, int64_t aId) = 0;

protected:
  CustomCleanupCallback()
  { }
};

} // namespace indexedDB
} // namespace dom
} // namespace mozilla