Commit 671f8253 authored by Florian Quèze's avatar Florian Quèze
Browse files

Bug 1817305 - Start the DataStorageTimer only when there is something to write, r=keeler.

parent 0277d1fb
Loading
Loading
Loading
Loading
+32 −9
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ mozilla::StaticAutoPtr<DataStorage::DataStorages> DataStorage::sDataStorages;
DataStorage::DataStorage(const nsString& aFilename)
    : mMutex("DataStorage::mMutex"),
      mPendingWrite(false),
      mTimerArmed(false),
      mShuttingDown(false),
      mInitCalled(false),
      mReadyMonitor("DataStorage::mReadyMonitor"),
@@ -174,15 +175,8 @@ nsresult DataStorage::Init() {
  mBackgroundTaskQueue = TaskQueue::Create(target.forget(), "PSM DataStorage");

  // For test purposes, we can set the write timer to be very fast.
  uint32_t timerDelayMS = Preferences::GetInt("test.datastorage.write_timer_ms",
  mTimerDelayMS = Preferences::GetInt("test.datastorage.write_timer_ms",
                                      sDataStorageDefaultTimerDelay);
  rv = NS_NewTimerWithFuncCallback(
      getter_AddRefs(mTimer), DataStorage::TimerCallback, this, timerDelayMS,
      nsITimer::TYPE_REPEATING_SLACK_LOW_PRIORITY, "DataStorageTimer",
      mBackgroundTaskQueue);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  rv = AsyncReadData(lock);
  if (NS_FAILED(rv)) {
@@ -589,6 +583,7 @@ nsresult DataStorage::PutInternal(const nsCString& aKey, Entry& aEntry,

  if (aType == DataStorage_Persistent) {
    mPendingWrite = true;
    ArmTimer(aProofOfLock);
  }

  return NS_OK;
@@ -603,6 +598,7 @@ void DataStorage::Remove(const nsCString& aKey, DataStorageType aType) {

  if (aType == DataStorage_Persistent) {
    mPendingWrite = true;
    ArmTimer(lock);
  }
}

@@ -707,6 +703,11 @@ nsresult DataStorage::AsyncWriteData(const MutexAutoLock& /*aProofOfLock*/) {
  nsCOMPtr<nsIRunnable> job(new Writer(output, this));
  nsresult rv = mBackgroundTaskQueue->Dispatch(job.forget());
  mPendingWrite = false;
  if (mTimerArmed) {
    rv = mTimer->Cancel();
    Unused << NS_WARN_IF(NS_FAILED(rv));
    mTimerArmed = false;
  }
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }
@@ -732,6 +733,7 @@ nsresult DataStorage::Clear() {
void DataStorage::TimerCallback(nsITimer* aTimer, void* aClosure) {
  RefPtr<DataStorage> aDataStorage = (DataStorage*)aClosure;
  MutexAutoLock lock(aDataStorage->mMutex);
  aDataStorage->mTimerArmed = false;
  Unused << aDataStorage->AsyncWriteData(lock);
}

@@ -749,6 +751,27 @@ void DataStorage::NotifyObservers(const char* aTopic) {
  }
}

void DataStorage::ArmTimer(const MutexAutoLock& /*aProofOfLock*/) {
  mMutex.AssertCurrentThreadOwns();
  if (mTimerArmed) {
    return;
  }

  if (!mTimer) {
    mTimer = NS_NewTimer(mBackgroundTaskQueue);
    if (NS_WARN_IF(!mTimer)) {
      return;
    }
  }

  nsresult rv = mTimer->InitWithNamedFuncCallback(
      DataStorage::TimerCallback, this, mTimerDelayMS, nsITimer::TYPE_ONE_SHOT,
      "DataStorageTimer");
  Unused << NS_WARN_IF(NS_FAILED(rv));

  mTimerArmed = true;
}

void DataStorage::ShutdownTimer() {
  MOZ_ASSERT(NS_IsMainThread());
  if (mTimer) {
+4 −1
Original line number Diff line number Diff line
@@ -136,6 +136,7 @@ class DataStorage : public nsIObserver {
  // Return true if this data storage is ready to be used.
  bool IsReady();

  void ArmTimer(const MutexAutoLock& aProofOfLock);
  void ShutdownTimer();

 private:
@@ -201,13 +202,15 @@ class DataStorage : public nsIObserver {
  nsCOMPtr<nsIFile> mBackingFile MOZ_GUARDED_BY(mMutex);
  bool mPendingWrite MOZ_GUARDED_BY(
      mMutex);  // true if a write is needed but hasn't been dispatched
  bool mTimerArmed MOZ_GUARDED_BY(mMutex);
  bool mShuttingDown MOZ_GUARDED_BY(mMutex);
  RefPtr<TaskQueue> mBackgroundTaskQueue MOZ_GUARDED_BY(mMutex);
  // (End list of members protected by mMutex)

  nsCOMPtr<nsITimer> mTimer;  // Must only be accessed on the main thread
  nsCOMPtr<nsITimer> mTimer;

  mozilla::Atomic<bool> mInitCalled;  // Indicates that Init() has been called.
  uint32_t mTimerDelayMS;

  Monitor mReadyMonitor;  // Do not acquire this at the same time as mMutex.
  bool mReady MOZ_GUARDED_BY(mReadyMonitor);  // Indicates that saved data has