Add app status startup timer 79/299179/8
authorChanggyu Choi <changyu.choi@samsung.com>
Thu, 21 Sep 2023 06:37:48 +0000 (15:37 +0900)
committerChanggyu Choi <changyu.choi@samsung.com>
Thu, 21 Sep 2023 08:19:12 +0000 (17:19 +0900)
Occasionally, if amd does not receive the app dead signal from launchpad due to a delay in dbus
initialization, amd may have a problem of not recognizing the termination status of an app.
To prevent this situation, this patch registers a timer for the startup signal and recognizes that
the app is dead if the signal is not received within 30 seconds.

Change-Id: I3cd0080dcb7148ac4d904639a1bf60d940448a79
Signed-off-by: Changgyu Choi <changyu.choi@samsung.com>
src/lib/amd_launch.cc
src/lib/app_status/app_status.cc
src/lib/app_status/app_status.hh
src/lib/app_status/app_status_manager.cc
src/lib/app_status/app_status_manager.hh

index 6d4787a..b32e390 100644 (file)
@@ -897,6 +897,7 @@ static int DispatchAppStartupSignal(request_h request) {
     return -1;
 
   app_status->SetStarting(true);
+  app_status->UnsetStartupTimer();
   if (app_status->GetAppType() == AT_UI_APP &&
       app_status->GetStatus() != STATUS_VISIBLE)
     amd::ForegroundManager::GetInst().Add(pid);
index dbe4e44..109b6dd 100644 (file)
@@ -36,6 +36,7 @@ namespace amd {
 namespace {
 
 constexpr int DYING_TIMEOUT = 5;
+constexpr int STARTUP_TIMEOUT = 30;
 
 typedef enum {
   AT_SERVICE_APP,
@@ -170,6 +171,9 @@ AppStatus::AppStatus(unsigned int request_id, std::string appid,
 AppStatus::~AppStatus() {
   if (dying_timer_ != 0)
     g_source_remove(dying_timer_);
+
+  if (startup_timer_ != 0)
+    g_source_remove(startup_timer_);
 }
 
 gboolean AppStatus::DyingTimeoutHandler(gpointer data) {
@@ -198,6 +202,32 @@ void AppStatus::SetDyingEvent() {
   }
 }
 
+void AppStatus::SetStartupTimer() {
+  if (startup_timer_ != 0)
+    return;
+
+  startup_timer_ = g_timeout_add_seconds(STARTUP_TIMEOUT,
+      +[](gpointer data) -> gboolean {
+    auto* app_status = static_cast<AppStatus*>(data);
+    app_status->startup_timer_ = 0;
+    app_status->event_listener_->OnStartupTimeout(app_status);
+    return G_SOURCE_REMOVE;
+  }, this);
+
+  if (startup_timer_ == 0) {
+    _E("Failed to set timeout callback");
+    return;
+  }
+}
+
+void AppStatus::UnsetStartupTimer() {
+  if (startup_timer_ == 0)
+    return;
+
+  g_source_remove(startup_timer_);
+  startup_timer_ = 0;
+}
+
 const AppInfo* AppStatus::GetAppInfo() const {
   return app_info_.get();
 }
index 7c61dda..735fe5f 100644 (file)
@@ -42,6 +42,7 @@ class AppStatus : public std::enable_shared_from_this<AppStatus> {
   class IEvent {
    public:
     virtual void OnDyingTimeout(AppStatus* data) = 0;
+    virtual void OnStartupTimeout(AppStatus* data) = 0;
     virtual ~IEvent() = default;
   };
 
@@ -128,6 +129,9 @@ class AppStatus : public std::enable_shared_from_this<AppStatus> {
 
   void SetDyingEvent();
 
+  void SetStartupTimer();
+  void UnsetStartupTimer();
+
   unsigned int GetRequestID() const;
   void SetPID(pid_t pid);
 
@@ -153,6 +157,7 @@ class AppStatus : public std::enable_shared_from_this<AppStatus> {
   int timestamp_ = 0;
   int fg_count_ = 0;
   guint dying_timer_ = 0;
+  guint startup_timer_ = 0;
   bool socket_exists_ = false;
   bool starting_ = false;
   bool exiting_ = false;
index 2e59286..e0c3798 100644 (file)
@@ -170,6 +170,21 @@ void AppStatusManager::OnDyingTimeout(AppStatus* app_status) {
   }
 }
 
+void AppStatusManager::OnStartupTimeout(AppStatus* app_status) {
+  if (app_status == nullptr)
+    return;
+
+  _E("App startup signal has not been received. pid(%d)", app_status->GetPID());
+  /*
+    Note: When OnStartupTimeout() is called, it may be after the app has
+    already been terminated. In this case, if sigkill is called, there is a
+    possibility that another process executed with the same pid will be
+    killed.
+  */
+  amd::AppStatusManager::GetInst().Update(app_status->shared_from_this(),
+      STATUS_DYING, false, true);
+}
+
 AppStatusManager& AppStatusManager::GetInst() {
   static AppStatusManager inst;
   return inst;
@@ -786,6 +801,9 @@ AppStatusPtr AppStatusManager::AddAppInfo(AppStatusPtr app_status) {
   if (app_status == nullptr)
     return nullptr;
 
+  if (!app_status->IsStarting())
+    app_status->SetStartupTimer();
+
   _noti_send(AMD_NOTI_MSG_APP_STATUS_ADD, 0, 0, app_status.get(), nullptr);
   app_status_dao_->UpdateAppStatus(app_status);
   Insert(app_status);
index ef98a93..1d55754 100644 (file)
@@ -90,6 +90,7 @@ class AppStatusManager : public AppStatus::IEvent {
   int Finish();
 
   void OnDyingTimeout(AppStatus* app) override;
+  void OnStartupTimeout(AppStatus* app) override;
 
  private:
   AppStatusManager() = default;