[application] Fixing memory management for app_control_send_launch_request_async 49/228649/3
authorPiotr Kosko <p.kosko@samsung.com>
Tue, 24 Mar 2020 09:48:55 +0000 (10:48 +0100)
committerPiotr Kosko <p.kosko@samsung.com>
Tue, 24 Mar 2020 11:00:18 +0000 (12:00 +0100)
[Bug] Order of reply and result callbacks is not defined (because both
signals come from different processes). This causes that we cannot just
release the memory in well defined way. Thus we added delay for removing
a data passed to callbacks to prevent crash.

[Verification] application tct passrate 100%
deprecate tct passrate 100%
Verified manually with application from PLM issue P200214-04877

Change-Id: Id50e80f7aecbaa9a01d46258f4f2a8eabe322409

src/application/application_manager.cc

index 864639c..af0f9cb 100644 (file)
@@ -19,6 +19,7 @@
 #include <glib.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <thread>
 #include <type_traits>
 
 #include <app_control_internal.h>
@@ -498,7 +499,9 @@ void ApplicationManager::LaunchAppControl(const picojson::value& args) {
       }
 
       Instance::PostMessage(callback_data->instance, return_value.serialize().c_str());
-      delete callback_data;
+      // Calling order of reply_callback and result_callback cannot be determined,
+      // thus callback_data is not released here - it is always
+      // released in result_callback with delay to prevent using a released memory.
     };
   }
 
@@ -519,9 +522,15 @@ void ApplicationManager::LaunchAppControl(const picojson::value& args) {
 
     Instance::PostMessage(callback_data->instance, callback_data->response->serialize().c_str());
 
-    if (result.IsError() || (callback_data->reply_callback_id).empty()) {
+    // Calling order of reply_callback and result_callback cannot be determined,
+    // thus callback_data is released here with delay to prevent using a released
+    // memory in reply_callback function.
+    int timeout = 10;
+    std::thread([callback_data, timeout]() {
+      std::this_thread::sleep_for(std::chrono::seconds(timeout));
+      LoggerD("Deleting callback_data: %p", callback_data);
       delete callback_data;
-    }
+    }).detach();
   };
 
   /*
@@ -641,10 +650,10 @@ void ApplicationManager::Launch(const picojson::value& args) {
   };
 
   /*
-   * TODO: Observe how often app_control_send_launch_request_async tries to launch the application.
+   * TODO: Observe how often app_control_send_resume_request tries to launch the application.
    * Previous implementation, using synchronous app_control_send_launch_request,
    * tries to launch the application 3 times, before reporting an error.
-   * New implementation, using app_control_send_launch_request_async makes only one attempt.
+   * New implementation, using app_control_send_resume_request makes only one attempt.
    * If problems, such as failed application start occur, multiple attempts may solve the problem.
    */
   auto launch_result = TranslateLaunchError(static_cast<app_control_error_e>(