diff options
-rw-r--r-- | src/components/policy/policy_external/include/policy/cache_manager.h | 17 | ||||
-rw-r--r-- | src/components/policy/policy_external/src/cache_manager.cc | 23 |
2 files changed, 40 insertions, 0 deletions
diff --git a/src/components/policy/policy_external/include/policy/cache_manager.h b/src/components/policy/policy_external/include/policy/cache_manager.h index 1bac72e2c6..5e3cf3dde7 100644 --- a/src/components/policy/policy_external/include/policy/cache_manager.h +++ b/src/components/policy/policy_external/include/policy/cache_manager.h @@ -33,6 +33,7 @@ #ifndef SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_INCLUDE_POLICY_CACHE_MANAGER_H_ #define SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_INCLUDE_POLICY_CACHE_MANAGER_H_ +#include <atomic> #include <map> #include "boost/optional.hpp" @@ -1129,12 +1130,28 @@ class CacheManager : public CacheManagerInterface { ~BackgroundBackuper(); virtual void threadMain(); virtual void exitThreadMain(); + + /** + * @brief Notifies BackgroundBackuper thread that new data is available and + * new backup iteration should be scheduled + */ void DoBackup(); + /** + * @brief Waits for BackgroundBackuper thread finish its own backup + * iteration. If currently no backup iteration in progress - function just + * returns the control back + */ + void WaitForBackupIsDone(); + private: void InternalBackup(); CacheManager* cache_manager_; sync_primitives::ConditionalVariable backup_notifier_; + sync_primitives::ConditionalVariable backup_done_; + sync_primitives::Lock backup_done_lock_; + + std::atomic_bool backup_is_in_progress_; volatile bool stop_flag_; volatile bool new_data_available_; diff --git a/src/components/policy/policy_external/src/cache_manager.cc b/src/components/policy/policy_external/src/cache_manager.cc index e1015ea574..c9ed786509 100644 --- a/src/components/policy/policy_external/src/cache_manager.cc +++ b/src/components/policy/policy_external/src/cache_manager.cc @@ -2741,10 +2741,14 @@ bool CacheManager::LoadFromFile(const std::string& file_name, bool CacheManager::ResetPT(const std::string& file_name) { LOG4CXX_AUTO_TRACE(logger_); is_unpaired_.clear(); + + backuper_->WaitForBackupIsDone(); + if (!backup_->RefreshDB()) { LOG4CXX_ERROR(logger_, "Can't re-create policy database. Reset failed."); return false; } + sync_primitives::AutoLock lock(cache_lock_); pt_.reset(new policy_table::Table()); const bool result = LoadFromFile(file_name, *pt_); @@ -3156,6 +3160,7 @@ void CacheManager::OnDeviceSwitching(const std::string& device_id_from, CacheManager::BackgroundBackuper::BackgroundBackuper( CacheManager* cache_manager) : cache_manager_(cache_manager) + , backup_is_in_progress_(false) , stop_flag_(false) , new_data_available_(false) { LOG4CXX_AUTO_TRACE(logger_); @@ -3180,13 +3185,23 @@ void CacheManager::BackgroundBackuper::threadMain() { LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock lock(need_backup_lock_); while (!stop_flag_) { + backup_is_in_progress_.exchange(true); { sync_primitives::AutoUnlock need_backup_lock(need_backup_lock_); InternalBackup(); } + + { + LOG4CXX_DEBUG(logger_, "Backup is done"); + sync_primitives::AutoLock auto_lock(backup_done_lock_); + backup_is_in_progress_.exchange(false); + backup_done_.Broadcast(); + } + if (new_data_available_ || stop_flag_) { continue; } + LOG4CXX_DEBUG(logger_, "Wait for a next backup"); backup_notifier_.Wait(need_backup_lock_); } @@ -3206,6 +3221,14 @@ void CacheManager::BackgroundBackuper::DoBackup() { backup_notifier_.NotifyOne(); } +void CacheManager::BackgroundBackuper::WaitForBackupIsDone() { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock auto_lock(backup_done_lock_); + if (backup_is_in_progress_) { + backup_done_.Wait(auto_lock); + } +} + EncryptionRequired CacheManager::GetAppEncryptionRequiredFlag( const std::string& application) const { LOG4CXX_AUTO_TRACE(logger_); |