Fix app com deletion 68/272068/2
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 7 Mar 2022 23:38:23 +0000 (08:38 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 8 Mar 2022 00:04:52 +0000 (09:04 +0900)
To avoid crash issue, this patch uses idler to remove the app_com_connection_h.
While calling the app_com_leave() function, the connection is set the disabled flag
to 'true'. If the disabled flag of the connection is 'true', the Invoke() method
doesn't call the callback function.
This patch is to fix the following crash issue:
+------------------------------------------------------------------------------+
| #0  0x43a88614 in std::_List_iterator<std::unique_ptr<(anonymous namespace)::|
|     AppComConnection, std::default_delete<(anonymous namespace)::AppComConnec|
|     tion> > >::operator++ (this=<synthetic pointer>)                         |
|     at /usr/lib/gcc/armv7l-tizen-linux-gnueabi/9.2.0/include/c++/mutex:109   |
| #1  (anonymous namespace)::Context::Receive (this=<optimized out>,           |
|     b=0x967c8af0) at /usr/src/debug/aul-0.43.10/src/app_com.cc:107           |
| #2  app_com_recv (b=0x967c8af0)                                              |
|     at /usr/src/debug/aul-0.43.10/src/app_com.cc:172                         |
+------------------------------------------------------------------------------+

Change-Id: I81a5d27fc49ba632c01c3171d4541e3eb3cd4605
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/app_com.cc

index a22be5b..e1e2645 100644 (file)
@@ -44,12 +44,21 @@ class AppComConnection {
     return endpoint_;
   }
 
+  void Disable() {
+    disabled_ = true;
+  }
+
+  bool IsDisabled() const {
+    return disabled_;
+  }
+
   void Invoke(aul_app_com_result_e result, bundle* envelope) {
-    if (cb_)
+    if (!disabled_ && cb_)
       cb_(endpoint_.c_str(), result, envelope, user_data_);
   }
 
  private:
+  bool disabled_ = false;
   std::string endpoint_;
   app_com_cb cb_;
   void* user_data_;
@@ -139,7 +148,7 @@ class Context {
   bool ExistConnection(const std::string& endpoint) {
     std::lock_guard<std::recursive_mutex> lock(mutex_);
     for (auto& conn : conns_) {
-      if (conn->GetEndpoint() == endpoint)
+      if (conn->GetEndpoint() == endpoint && !conn->IsDisabled())
         return true;
     }
 
@@ -148,6 +157,9 @@ class Context {
 
   bool ExistConnection(AppComConnection* conn) {
     std::lock_guard<std::recursive_mutex> lock(mutex_);
+    if (conn->IsDisabled())
+      return false;
+
     for (auto& i : conns_) {
       if (i.get() == conn)
         return true;
@@ -156,6 +168,10 @@ class Context {
     return false;
   }
 
+  std::recursive_mutex& GetMutex() const {
+    return mutex_;
+  }
+
  private:
   std::list<std::unique_ptr<AppComConnection>> conns_;
   mutable std::recursive_mutex mutex_;
@@ -313,8 +329,14 @@ extern "C" API int aul_app_com_leave(aul_app_com_connection_h connection) {
     return AUL_R_EINVAL;
   }
 
+  std::lock_guard<std::recursive_mutex> lock(context.GetMutex());
+  conn->Disable();
   std::string endpoint = conn->GetEndpoint();
-  context.RemoveConnection(conn);
+  g_idle_add_full(G_PRIORITY_HIGH, [](gpointer user_data) -> gboolean {
+        auto* conn = static_cast<AppComConnection*>(user_data);
+        context.RemoveConnection(conn);
+        return G_SOURCE_REMOVE;
+      }, connection, nullptr);
 
   if (context.ExistConnection(endpoint))
     return AUL_R_OK;