Fix vehicle data params after master reset#2614
Fix vehicle data params after master reset#2614SNiukalov wants to merge 4 commits intosmartdevicelink:developfrom
Conversation
| policy_manager_lock_.Acquire(); | ||
| const std::vector<UserFriendlyMessage> result = | ||
| policy_manager_->GetUserFriendlyMessages(message_codes, language); | ||
| policy_manager_lock_.Release(); |
There was a problem hiding this comment.
@SNiukalov Why do you make Lock and Release twice?
There was a problem hiding this comment.
@AByzhynar there is ifdef -> else -> endif sections.
But as for me you can use next way:
std::vector<UserFriendlyMessage> result;
#ifdef EXTERNAL_PROPRIETARY_MODE
const std::string active_hmi_language =
application_manager::MessageHelper::CommonLanguageToString(
application_manager_.hmi_capabilities().active_ui_language());
{
sync_primitives::AutoLock lock(policy_manager_lock_);
result = policy_manager_->GetUserFriendlyMessages(message_codes, language, active_hmi_language);
}
#else
{
sync_primitives::AutoLock lock(policy_manager_lock_);
result = policy_manager_->GetUserFriendlyMessages(message_codes, language);
}
#endif // EXTERNAL_PROPRIETARY_MODE
There was a problem hiding this comment.
This code block is in the definition for EXTERNAL_PROPRIETARY_MODE.
In the code for EXTERNAL_PROPRIETARY_MODE,
before calling the PolicyManager method,
The methods of the ApplicationManager and HMICapabilities classes are called.
We don't use this object synchronize for them.
| policy_manager_->SetUserConsentForDevice(device_mac, is_allowed); | ||
| { | ||
| sync_primitives::AutoLock lock(policy_manager_lock_); | ||
| policy_manager_->SetUserConsentForDevice(device_mac, is_allowed); |
There was a problem hiding this comment.
@SNiukalov I see a lot of calls like policy_manager-> something + acquire/release lock
As we have C++11 support in open source, I propose you to declare a template like:
template <typename Func, typename... Args>
void CallPolicyManagerFunction(Func func, Args... args) {
sync_primitives::AutoLock lock(policy_manager_lock_);
((*policy_manager_).*func)(args...);
}
And simplify all these calls to a single line:
CallPolicyManagerFunction(&PolicyManager::SetUserConsentForDevice, device_mac, is_allowed);
Please analyze all such places and try this template instead
| POLICY_LIB_CHECK(0); | ||
| LOG4CXX_AUTO_TRACE(logger_); | ||
| sync_primitives::AutoLock lock(policy_manager_lock_); | ||
| return policy_manager_->NextRetryTimeout(); |
There was a problem hiding this comment.
@SNiukalov try to create similar template with the function return type
There was a problem hiding this comment.
@SNiukalov that's crazy, but something like that:
template <typename Func, typename... Args>
auto CallPolicyManagerFunction(Func func, Args... args) -> decltype((std::declval<PolicyManager>().*std::declval<Func>())(std::declval<Args>()...)) {
sync_primitives::AutoLock lock(policy_manager_lock_);
return ((*policy_manager_).*func)(args...);
}
It should work for both cases - when return type required and when not
There was a problem hiding this comment.
@SNiukalov or another way - try to create accessor to PolicyManager instance and make access to it only through accessor
| UpdateHMILevel(app, level); | ||
| } | ||
|
|
||
| template <typename Func, typename... Args> |
There was a problem hiding this comment.
@SNiukalov I think you could merge this template definition with declaration and keep whole in header file
| hmi_apis::FunctionID::BasicCommunication_OnReady); | ||
| std::string preloaded_file = get_settings().preloaded_pt_file(); | ||
| if (file_system::FileExists(preloaded_file)) { | ||
| sync_primitives::AutoLock lock(policy_manager_lock_); |
| POLICY_LIB_CHECK(false); | ||
| std::string preloaded_file = get_settings().preloaded_pt_file(); | ||
| if (file_system::FileExists(preloaded_file)) { | ||
| sync_primitives::AutoLock lock(policy_manager_lock_); |
| bool PolicyHandler::ClearUserConsent() { | ||
| LOG4CXX_AUTO_TRACE(logger_); | ||
| POLICY_LIB_CHECK(false); | ||
| sync_primitives::AutoLock lock(policy_manager_lock_); |
There was a problem hiding this comment.
@SNiukalov @SNiukalov CallPolicyManagerFunction?
| void PolicyHandler::OnPTExchangeNeeded() { | ||
| LOG4CXX_AUTO_TRACE(logger_); | ||
| POLICY_LIB_CHECK_VOID(); | ||
| sync_primitives::AutoLock lock(policy_manager_lock_); |
| usage_statistics::AppStopwatchId type, | ||
| int32_t timespan_seconds) { | ||
| POLICY_LIB_CHECK(); | ||
| sync_primitives::AutoLock lock(policy_manager_lock_); |
| bool PolicyHandler::CheckModule(const PTString& app_id, | ||
| const PTString& module) { | ||
| POLICY_LIB_CHECK(false); | ||
| sync_primitives::AutoLock lock(policy_manager_lock_); |
| void PolicyHandler::OnRemoteAppPermissionsChanged( | ||
| const std::string& device_id, const std::string& application_id) { | ||
| POLICY_LIB_CHECK_VOID(); | ||
| sync_primitives::AutoLock lock(policy_manager_lock_); |
| std::vector<std::string>* modules) const { | ||
| LOG4CXX_AUTO_TRACE(logger_); | ||
| POLICY_LIB_CHECK(false); | ||
| sync_primitives::AutoLock lock(policy_manager_lock_); |
| SmartObjectToInt()); | ||
| } | ||
|
|
||
| sync_primitives::AutoLock lock(policy_manager_lock_); |
There was a problem hiding this comment.
@AKalinich-Luxoft Sorry, there was a small misunderstanding.
Replaced everything, where there is no need for statics_cast for the overload functions
in: e60c21e
|
Rebuild Required |
| /** | ||
| * @brief Call PolicyManager function with sync_primitives::AutoLock | ||
| * @param func function PolicyManager to call | ||
| * @param args argmunets for call function |
| mobile_apis::HMILevel::eType default_mobile_hmi; | ||
| policy_manager_->GetDefaultHmi(app->policy_app_id(), &hmi_level); | ||
| { | ||
| sync_primitives::AutoLock lock(policy_manager_lock_); |
There was a problem hiding this comment.
@SNiukalov Add check for shared ptr validity before dereferencing
|
@SNiukalov Please add appropriate description with detailed fix information |
There was a problem hiding this comment.
@SNiukalov this fix may significantly reduce the performance of SDL (replacing RW lock with recursive) . Also it adds not obvious template function for calling Policy Manager, and there no way to prevent using of the policy_manager_ variable without lock.
This fix required additional description
I suppose that here could be better solution, but probably this fix is OK,.
Please describe it carefully. Add the root cause of the issue, and how your fix prevent it.
|
@SNiukalov see comments |
|
@SNiukalov actualize branch |
e60c21e to
a4f0569
Compare
|
@AByzhynar @LuxoftAKutsan |
|
@EKuliiev |
a4f0569 to
741b392
Compare
| void PolicyHandler::OnGetStatusUpdate(const uint32_t correlation_id) { | ||
| LOG4CXX_AUTO_TRACE(logger_); | ||
| POLICY_LIB_CHECK_VOID(); | ||
| std::string policy_table_status = |
|
|
||
| AppPermissions permissions = | ||
| policy_manager_->GetAppPermissionsChanges(policy_app_id); | ||
| AppPermissions permissions = CallPolicyManagerFunction( |
| POLICY_LIB_CHECK(false); | ||
|
|
||
| bool ret = policy_manager_->LoadPT(file, pt_string); | ||
| bool ret = CallPolicyManagerFunction(&PolicyManager::LoadPT, file, pt_string); |
| CallPolicyManagerFunction(&PolicyManager::GetUserConsentForDevice, | ||
| permissions.deviceInfo.device_mac_address); | ||
|
|
||
| permissions.isSDLAllowed = kDeviceAllowed == consent; |
| std::string update_status = policy_manager_->ForcePTExchangeAtUserRequest(); | ||
| LOG4CXX_DEBUG(logger_, "PT exchange at user request"); | ||
|
|
||
| std::string update_status = |
Fixes #2596
This PR is ready for review.
Risk
This PR makes no API changes.
Summary
There was a problem that in some cases parallel call of functions of
policy_manager_object could cause database inner structure corruption which causes undefined issues with policy permissions. In order to avoid such behavior, all calls ofpolicy_manager_was wrapped with universal function which provides thread safe access for this object.CLA