From: Changgyu Choi Date: Thu, 21 Sep 2023 06:37:48 +0000 (+0900) Subject: Add app status startup timer X-Git-Tag: accepted/tizen/unified/20230923.084318~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d21812aa619b64c8f22d19cc94efa53509a50f3d;p=platform%2Fcore%2Fappfw%2Famd.git Add app status startup timer 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 --- diff --git a/src/lib/amd_launch.cc b/src/lib/amd_launch.cc index 6d4787a7..b32e390c 100644 --- a/src/lib/amd_launch.cc +++ b/src/lib/amd_launch.cc @@ -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); diff --git a/src/lib/app_status/app_status.cc b/src/lib/app_status/app_status.cc index dbe4e44f..109b6ddf 100644 --- a/src/lib/app_status/app_status.cc +++ b/src/lib/app_status/app_status.cc @@ -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(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(); } diff --git a/src/lib/app_status/app_status.hh b/src/lib/app_status/app_status.hh index 7c61ddad..735fe5f8 100644 --- a/src/lib/app_status/app_status.hh +++ b/src/lib/app_status/app_status.hh @@ -42,6 +42,7 @@ class AppStatus : public std::enable_shared_from_this { 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 { 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 { 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; diff --git a/src/lib/app_status/app_status_manager.cc b/src/lib/app_status/app_status_manager.cc index 2e59286f..e0c3798c 100644 --- a/src/lib/app_status/app_status_manager.cc +++ b/src/lib/app_status/app_status_manager.cc @@ -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); diff --git a/src/lib/app_status/app_status_manager.hh b/src/lib/app_status/app_status_manager.hh index ef98a930..1d55754b 100644 --- a/src/lib/app_status/app_status_manager.hh +++ b/src/lib/app_status/app_status_manager.hh @@ -90,6 +90,7 @@ class AppStatusManager : public AppStatus::IEvent { int Finish(); void OnDyingTimeout(AppStatus* app) override; + void OnStartupTimeout(AppStatus* app) override; private: AppStatusManager() = default;