Fix DebugPort Implementation 37/280137/1
authorHwankyu Jhun <h.jhun@samsung.com>
Fri, 6 Aug 2021 01:43:14 +0000 (10:43 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Wed, 24 Aug 2022 08:32:54 +0000 (08:32 +0000)
If the instance is managed as a global variable, the process tries to
access to the destroyed DebugPort instance while calling the exit handlers.

Change-Id: Ia7cfa9d241266921221ecf28ce8b4b22dc4b95d6
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/debug-port-internal.cc
src/debug-port-internal.hh
src/proxy-internal.cc
src/rpc-port.cc
src/stub-internal.cc

index dc1b0ba..fd1bffc 100644 (file)
@@ -33,11 +33,32 @@ static const char RPC_PORT_SIGNAL_INTERFACE[] = "org.tizen.rpc.port.signal";
 static const char RPC_PORT_SIGNAL_DEBUG[] = "Debug";
 static const char RPC_PORT_SIGNAL_NEW[] = "New";
 
+std::atomic<DebugPort*> DebugPort::inst_;
+std::mutex DebugPort::mutex_;
+
 DebugPort::~DebugPort() {
   if (!disposed_)
     Dispose();
 }
 
+DebugPort* DebugPort::GetInst() {
+  DebugPort* inst = inst_.load(std::memory_order_acquire);
+  if (inst == nullptr) {
+    std::lock_guard<std::mutex> lock(mutex_);
+    inst = inst_.load(std::memory_order_relaxed);
+    if (inst == nullptr) {
+      inst = new DebugPort();
+      inst_.store(inst, std::memory_order_release);
+    }
+  }
+
+  std::lock_guard<std::recursive_mutex> rec_lock(inst->GetMutex());
+  if (inst->disposed_)
+    inst->Init();
+
+  return inst;
+}
+
 void DebugPort::Dispose() {
   Unwatch();
   Unsubscribe();
index 3fa25e7..89f2759 100644 (file)
@@ -74,14 +74,7 @@ class DebugPort {
     int delegate_port_;
   };
 
-  static DebugPort& GetInst() {
-    static DebugPort inst;
-
-    std::lock_guard<std::recursive_mutex> lock(inst.GetMutex());
-    if (inst.disposed_)
-      inst.Init();
-    return inst;
-  }
+  static DebugPort* GetInst();
 
   void Dispose();
   bool IsConnected();
@@ -94,8 +87,11 @@ class DebugPort {
       const void* buf, unsigned int size);
 
  private:
+  static std::atomic<DebugPort*> inst_;
+  static std::mutex mutex_;
+
   std::recursive_mutex& GetMutex() const {
-    return mutex_;
+    return rec_mutex_;
   }
 
   void Init();
@@ -134,7 +130,7 @@ class DebugPort {
   std::thread thread_;
   std::atomic<bool> is_running_;
   SharedQueue<std::shared_ptr<Parcel>> queue_;
-  mutable std::recursive_mutex mutex_;
+  mutable std::recursive_mutex rec_mutex_;
 };
 
 }  // namespace internal
index 3e0b7ed..9ede652 100644 (file)
@@ -64,7 +64,7 @@ gboolean Proxy::OnSocketDisconnected(GIOChannel *gio, GIOCondition cond,
     proxy->main_port_.reset();
     proxy->delegate_port_.reset();
   }
-  DebugPort::GetInst().RemoveSession(fd);
+  DebugPort::GetInst()->RemoveSession(fd);
 
   return FALSE;
 }
@@ -85,7 +85,7 @@ gboolean Proxy::OnDataReceived(GIOChannel *gio, GIOCondition cond,
         listener->OnDisconnected(proxy->target_appid_);
 
       if (proxy->main_port_.get() != nullptr) {
-        DebugPort::GetInst().RemoveSession(proxy->main_port_->GetFd());
+        DebugPort::GetInst()->RemoveSession(proxy->main_port_->GetFd());
         proxy->main_port_.reset();
       }
       proxy->delegate_port_.reset();
@@ -149,7 +149,7 @@ void Proxy::OnPortConnected() {
   main_port_.reset(new ProxyPort(this, fds_[0], target_appid_, false));
   delegate_port_.reset(new ProxyPort(this, fds_[1], target_appid_));
   listener_->OnConnected(target_appid_, main_port_.get());
-  DebugPort::GetInst().AddSession(port_name_, target_appid_, fds_[0], fds_[1]);
+  DebugPort::GetInst()->AddSession(port_name_, target_appid_, fds_[0], fds_[1]);
 }
 
 // LCOV_EXCL_START
@@ -170,7 +170,7 @@ void Proxy::OnPortDisconnected(bool cancel) {
   IEventListener* listener = listener_;
   listener_ = nullptr;
   listener->OnDisconnected(target_appid_);
-  DebugPort::GetInst().RemoveSession(fds_[0]);
+  DebugPort::GetInst()->RemoveSession(fds_[0]);
 }
 // LCOV_EXCL_STOP
 
@@ -241,14 +241,13 @@ int Proxy::ConnectSync(std::string appid, std::string port_name,
   main_port_.reset(new ProxyPort(this, fds_[0], target_appid_, false));
   delegate_port_.reset(new ProxyPort(this, fds_[1], target_appid_));
   listener_->OnConnected(target_appid_, main_port_.get());
-  DebugPort::GetInst().AddSession(port_name, target_appid_, fds_[0], fds_[1]);
-
+  DebugPort::GetInst()->AddSession(port_name, target_appid_, fds_[0], fds_[1]);
   return RPC_PORT_ERROR_NONE;
 }
 
 void Proxy::DisconnectPort() {
   if (main_port_.get() != nullptr) {
-    DebugPort::GetInst().RemoveSession(main_port_->GetFd());
+    DebugPort::GetInst()->RemoveSession(main_port_->GetFd());
     main_port_.reset();
   }
 }
index e6b1fd1..f0da658 100644 (file)
@@ -214,8 +214,8 @@ RPC_API int rpc_port_read(rpc_port_h h, void* buf, unsigned int size) {
   if (ret < 0)
     return ret;
 
-  auto& debug_port = DebugPort::GetInst();
-  debug_port.Send(port->GetFd(), true, seq, buf, size);
+  auto* debug_port = DebugPort::GetInst();
+  debug_port->Send(port->GetFd(), true, seq, buf, size);
   return RPC_PORT_ERROR_NONE;
 }
 
@@ -233,8 +233,8 @@ RPC_API int rpc_port_write(rpc_port_h h, const void* buf, unsigned int size) {
   if (ret < 0)
     return ret;
 
-  auto& debug_port = DebugPort::GetInst();
-  debug_port.Send(port->GetFd(), false, seq, buf, size);
+  auto* debug_port = DebugPort::GetInst();
+  debug_port->Send(port->GetFd(), false, seq, buf, size);
   return RPC_PORT_ERROR_NONE;
 }
 
index 35ecd09..989eb0f 100644 (file)
@@ -80,7 +80,7 @@ void Stub::RemoveAcceptedPorts(std::string instance) {
   while (iter != ports_.end()) {
     if ((*iter)->GetInstance().compare(instance) == 0) {
       LOGI("Close: fd(%d)", (*iter)->GetFd());
-      DebugPort::GetInst().RemoveSession((*iter)->GetFd());
+      DebugPort::GetInst()->RemoveSession((*iter)->GetFd());
       iter = ports_.erase(iter);
     } else {
       iter++;
@@ -159,7 +159,11 @@ void Stub::OnFdReceived(const std::string& sender, int fds[2]) {
       break;
     }
   }
-  DebugPort::GetInst().AddSession(port_name_, sender, fds[0], fds[1]);
+
+  _W("sender_appid(%s), instance(%s), main_fd(%d), delegate_fd(%d)",
+      sender.c_str(), main_port->GetInstance().c_str(), fds[0], fds[1]);
+  listener_->OnConnected(sender, main_port->GetInstance());
+  DebugPort::GetInst()->AddSession(port_name_, sender, fds[0], fds[1]);
 }
 
 Stub::AcceptedPort::AcceptedPort(Stub* parent, bool isDelegate, int fd,