summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAsen Kirov <akirov@luxoft.com>2015-11-30 13:54:57 +0200
committerAsen Kirov <akirov@luxoft.com>2015-11-30 13:54:57 +0200
commitf030dd2959e0a27a04aa3150bb98172b72b89a7f (patch)
tree76144a3ab5cb7fe4b972276f23d8d16ea0b721ea
parentd6120b98447ff89c1cfab05545709c9e70829347 (diff)
downloadsmartdevicelink-f030dd2959e0a27a04aa3150bb98172b72b89a7f.tar.gz
Fix deadlocks in AM when stopping SDL and log socket endless blocking
When we stop AM we unregister apps and call StopSavePersistentDataTimer(). If the timer callback by chance is active at this moment we can have a deadlock between AM and ResumeController. To prevent it limit the lifetime of ApplicationListAccessor and allow ResumeController to finish his job. Another option is to move resume_controller().OnSuspend() call before unregitering apps. Another deadlock problem arises when while destroying AM an app tries to register (3 seconds before that actually). Then AM tries to destroy ResumeController, but RC is in ApplicationResumptiOnTimer() callback and tries to get AM instance, and blocks on AM singleton's lock. The fix is to StopRestoreHmiLevelTimer() before destroyng AM. A third reason for SDL not stopping normally is when a logger is writing on a socket, but the client on the other side is not reading (and is not closing the socket neither). Then write() blocks and logger, and therefore SDL, cannot be stopped. The fix is to put timeout option to the socket.
-rw-r--r--src/3rd_party/apache-log4cxx-0.10.0/src/main/cpp/serversocket.cpp7
-rw-r--r--src/components/application_manager/include/application_manager/resume_ctrl.h5
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc6
-rw-r--r--src/components/application_manager/src/resume_ctrl.cpp9
4 files changed, 26 insertions, 1 deletions
diff --git a/src/3rd_party/apache-log4cxx-0.10.0/src/main/cpp/serversocket.cpp b/src/3rd_party/apache-log4cxx-0.10.0/src/main/cpp/serversocket.cpp
index 095fffc54..f2b5de61c 100644
--- a/src/3rd_party/apache-log4cxx-0.10.0/src/main/cpp/serversocket.cpp
+++ b/src/3rd_party/apache-log4cxx-0.10.0/src/main/cpp/serversocket.cpp
@@ -128,6 +128,13 @@ SocketPtr ServerSocket::accept() {
throw SocketException(status);
}
+ // Added 5 seconds timeout to fix endless blocking on write() when the client is not reading
+ status = apr_socket_timeout_set(newSocket, 5000000);
+ if (status != APR_SUCCESS) {
+ apr_pool_destroy(newPool);
+ throw SocketException(status);
+ }
+
return new Socket(newSocket, newPool);
}
diff --git a/src/components/application_manager/include/application_manager/resume_ctrl.h b/src/components/application_manager/include/application_manager/resume_ctrl.h
index 99d694570..4d9031636 100644
--- a/src/components/application_manager/include/application_manager/resume_ctrl.h
+++ b/src/components/application_manager/include/application_manager/resume_ctrl.h
@@ -154,6 +154,11 @@ class ResumeCtrl: public event_engine::EventObserver {
*/
void StopSavePersistentDataTimer();
+ /**
+ * @brief Method stops restore_hmi_level_timer_ "RsmCtrlRstore" in Suspend()
+ */
+ void StopRestoreHmiLevelTimer();
+
/**
* @brief Start timer for resumption applications
* Restore D1-D5 data
diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc
index 0c686c79a..baa45bc0b 100644
--- a/src/components/application_manager/src/application_manager_impl.cc
+++ b/src/components/application_manager/src/application_manager_impl.cc
@@ -2213,6 +2213,8 @@ void ApplicationManagerImpl::UnregisterAllApplications() {
bool is_unexpected_disconnect =
Compare<eType, NEQ, ALL>(unregister_reason_,
IGNITION_OFF, MASTER_RESET, FACTORY_DEFAULTS);
+
+ { // A local scope to limit accessor's lifetime and release app list lock.
ApplicationListAccessor accessor;
ApplictionSetConstIt it = accessor.begin();
while (it != accessor.end()) {
@@ -2234,7 +2236,9 @@ void ApplicationManagerImpl::UnregisterAllApplications() {
connection_handler::kCommon);
it = accessor.begin();
}
- if (is_ignition_off) {
+ }
+
+ if (is_ignition_off) { // Move this block before unregistering apps?
resume_controller().Suspend();
}
request_ctrl_.terminateAllHMIRequests();
diff --git a/src/components/application_manager/src/resume_ctrl.cpp b/src/components/application_manager/src/resume_ctrl.cpp
index 19cad8013..983699e02 100644
--- a/src/components/application_manager/src/resume_ctrl.cpp
+++ b/src/components/application_manager/src/resume_ctrl.cpp
@@ -376,6 +376,7 @@ bool ResumeCtrl::RemoveApplicationFromSaved(const std::string& mobile_app_id) {
void ResumeCtrl::Suspend() {
LOG4CXX_AUTO_TRACE(logger_);
+ StopRestoreHmiLevelTimer();
StopSavePersistentDataTimer();
SaveAllApplications();
Json::Value to_save;
@@ -443,6 +444,14 @@ void ResumeCtrl::StopSavePersistentDataTimer() {
}
+void ResumeCtrl::StopRestoreHmiLevelTimer() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (restore_hmi_level_timer_.isRunning()) {
+ restore_hmi_level_timer_.stop();
+ }
+}
+
+
bool ResumeCtrl::StartResumption(ApplicationSharedPtr application,
const std::string& hash) {
LOG4CXX_AUTO_TRACE(logger_);