Fix memory leak
authorHwankyu Jhun <h.jhun@samsung.com>
Thu, 3 Aug 2023 00:25:19 +0000 (09:25 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 8 Aug 2023 23:02:58 +0000 (08:02 +0900)
If the callee application does not use tizen main loop function,
the ResultCb instance is not released.
To release the allocated memory properly, this patch adds a new method to
the ClientChannel. When calling the OnTimedOut, amd releases the ResultCb.

Change-Id: Ia29e7ba632296c56ae95d9fd5febc14ecfcd9e22
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/lib/api/amd_api_app_request_broker.cc

index b51932d35d55fab62d79c20bc160f7e2355df80f..f1b3e53609e666cfa58589ca1bb3709d0b311f8b 100644 (file)
@@ -23,6 +23,7 @@
 #include <gio/gio.h>
 #include <glib.h>
 
+#include <list>
 #include <memory>
 #include <queue>
 #include <string>
@@ -41,8 +42,15 @@ constexpr const char PATH_AUL_APPS[] = "/run/aul/apps";
 
 class ResultCb {
  public:
-  ResultCb(amd_app_request_broker_result_cb cb, void* user_data)
-      :  cb_(cb), user_data_(user_data) {
+  class IEvent {
+   public:
+    virtual ~IEvent() = default;
+    virtual void OnTimedOut(ResultCb* cb) = 0;
+  };
+
+  ResultCb(IEvent* listener, amd_app_request_broker_result_cb cb,
+      void* user_data)
+      : listener_(listener), cb_(cb), user_data_(user_data) {
     timer_ = g_timeout_add(5000, OnTimedOut, this);
   }
 
@@ -61,18 +69,25 @@ class ResultCb {
  private:
   static gboolean OnTimedOut(gpointer user_data) {
     auto* cb = static_cast<ResultCb*>(user_data);
-    cb->Invoke(-ETIMEDOUT);
     cb->timer_ = 0;
+
+    auto* listener = cb->listener_;
+    if (listener != nullptr)
+      listener->OnTimedOut(cb);
+
     return G_SOURCE_REMOVE;
   }
 
  private:
+  IEvent* listener_;
   amd_app_request_broker_result_cb cb_;
   void* user_data_;
   guint timer_ = 0;
 };
 
-class ClientChannel : public amd::ClientSocket {
+class ClientChannel : public amd::ClientSocket,
+                      public ResultCb::IEvent,
+                      public std::enable_shared_from_this<ClientChannel> {
  public:
   ClientChannel(pid_t pid, uid_t uid)
       : ClientSocket(), pid_(pid), uid_(uid) {
@@ -125,6 +140,14 @@ class ClientChannel : public amd::ClientSocket {
     return uid_;
   }
 
+  std::shared_ptr<ClientChannel> GetSharedPtr() {
+    return shared_from_this();
+  }
+
+  void AddResultCb(amd_app_request_broker_result_cb cb, void* user_data) {
+    Push(std::make_shared<ResultCb>(this, cb, user_data));
+  }
+
   void Push(std::shared_ptr<ResultCb> result_cb) {
     queue_.push(std::move(result_cb));
   }
@@ -140,6 +163,11 @@ class ClientChannel : public amd::ClientSocket {
   }
 
  private:
+  void OnTimedOut(ResultCb* cb) override {
+    cb->Invoke(-ETIMEDOUT);
+    queue_.pop();
+  }
+
   static gboolean OnDataReceived(GIOChannel* channel, GIOCondition cond,
       gpointer user_data);
   static gboolean OnSocketDisconnected(GIOChannel* channel, GIOCondition cond,
@@ -306,10 +334,11 @@ extern "C" EXPORT_API int amd_app_request_broker_send(
 
     _E("Client channel will be removed. pid(%d)", channel->GetPid());
     broker.RemoveClientChannel(channel->GetPid());
+
     return ret;
   }
 
-  channel->Push(std::make_shared<ResultCb>(callback, user_data));
+  channel->AddResultCb(callback, user_data);
   return 0;
 }