summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjacobkeeler <jacob.keeler@livioradio.com>2018-05-14 13:55:32 -0400
committerjacobkeeler <jacob.keeler@livioradio.com>2018-05-14 15:57:41 -0400
commit028ca237522c1c1693ca54049cf462a5122598e4 (patch)
tree2c97b81379e45e9bbe4a251e213d07f813305895
parentb33bffd77d428d59612c9fc3267767d21542579d (diff)
downloadsdl_core-fix/event_dispatcher_crash.tar.gz
Prevent `INVALID_ID`responses from terminating valid requestsfix/event_dispatcher_crash
-rw-r--r--src/components/application_manager/include/application_manager/request_controller.h7
-rw-r--r--src/components/application_manager/src/request_controller.cc25
2 files changed, 32 insertions, 0 deletions
diff --git a/src/components/application_manager/include/application_manager/request_controller.h b/src/components/application_manager/include/application_manager/request_controller.h
index d3a5a0b821..c0bae1aac8 100644
--- a/src/components/application_manager/include/application_manager/request_controller.h
+++ b/src/components/application_manager/include/application_manager/request_controller.h
@@ -289,6 +289,13 @@ class RequestController {
*/
std::list<RequestPtr> notification_list_;
+ /**
+ * @brief Map keeping track of how many duplicate messages were sent for a
+ * given correlation id, to prevent early termination of a request
+ */
+ std::map<uint32_t, uint32_t> duplicate_message_count_;
+ sync_primitives::Lock duplicate_message_count_lock_;
+
/*
* timer for checking requests timeout
*/
diff --git a/src/components/application_manager/src/request_controller.cc b/src/components/application_manager/src/request_controller.cc
index a6d78f24de..f341967842 100644
--- a/src/components/application_manager/src/request_controller.cc
+++ b/src/components/application_manager/src/request_controller.cc
@@ -50,6 +50,7 @@ RequestController::RequestController(const RequestControlerSettings& settings)
: pool_state_(UNDEFINED)
, pool_size_(settings.thread_pool_size())
, request_tracker_(settings)
+ , duplicate_message_count_()
, timer_("AM RequestCtrlTimer",
new timer::TimerTaskImpl<RequestController>(
this, &RequestController::TimeoutThread))
@@ -230,6 +231,21 @@ void RequestController::TerminateRequest(const uint32_t correlation_id,
<< correlation_id << " connection_key = " << connection_key
<< " function_id = " << function_id
<< " force_terminate = " << force_terminate);
+ {
+ AutoLock auto_lock(duplicate_message_count_lock_);
+ auto dup_it = duplicate_message_count_.find(correlation_id);
+ if (duplicate_message_count_.end() != dup_it) {
+ duplicate_message_count_[correlation_id]--;
+ if (0 == duplicate_message_count_[correlation_id]) {
+ duplicate_message_count_.erase(dup_it);
+ }
+ LOG4CXX_DEBUG(logger_,
+ "Ignoring termination request due to duplicate correlation "
+ "ID being sent");
+ return;
+ }
+ }
+
RequestInfoPtr request =
waiting_for_response_.Find(connection_key, correlation_id);
if (!request) {
@@ -478,6 +494,15 @@ void RequestController::Worker::threadMain() {
commands::CommandRequestImpl* cmd_request =
dynamic_cast<commands::CommandRequestImpl*>(request_ptr.get());
if (cmd_request != NULL) {
+ uint32_t corr_id = cmd_request->correlation_id();
+ request_controller_->duplicate_message_count_lock_.Acquire();
+ auto dup_it =
+ request_controller_->duplicate_message_count_.find(corr_id);
+ if (request_controller_->duplicate_message_count_.end() == dup_it) {
+ request_controller_->duplicate_message_count_[corr_id] = 0;
+ }
+ request_controller_->duplicate_message_count_[corr_id]++;
+ request_controller_->duplicate_message_count_lock_.Release();
cmd_request->SendResponse(
false, mobile_apis::Result::INVALID_ID, "Duplicate correlation_id");
}