Loading security/manager/ssl/DataStorage.cpp +32 −9 Original line number Diff line number Diff line Loading @@ -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"), Loading Loading @@ -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)) { Loading Loading @@ -589,6 +583,7 @@ nsresult DataStorage::PutInternal(const nsCString& aKey, Entry& aEntry, if (aType == DataStorage_Persistent) { mPendingWrite = true; ArmTimer(aProofOfLock); } return NS_OK; Loading @@ -603,6 +598,7 @@ void DataStorage::Remove(const nsCString& aKey, DataStorageType aType) { if (aType == DataStorage_Persistent) { mPendingWrite = true; ArmTimer(lock); } } Loading Loading @@ -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; } Loading @@ -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); } Loading @@ -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) { Loading security/manager/ssl/DataStorage.h +4 −1 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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 Loading Loading
security/manager/ssl/DataStorage.cpp +32 −9 Original line number Diff line number Diff line Loading @@ -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"), Loading Loading @@ -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)) { Loading Loading @@ -589,6 +583,7 @@ nsresult DataStorage::PutInternal(const nsCString& aKey, Entry& aEntry, if (aType == DataStorage_Persistent) { mPendingWrite = true; ArmTimer(aProofOfLock); } return NS_OK; Loading @@ -603,6 +598,7 @@ void DataStorage::Remove(const nsCString& aKey, DataStorageType aType) { if (aType == DataStorage_Persistent) { mPendingWrite = true; ArmTimer(lock); } } Loading Loading @@ -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; } Loading @@ -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); } Loading @@ -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) { Loading
security/manager/ssl/DataStorage.h +4 −1 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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 Loading