From de3a1d59836496b786ce31e9f2ce77c0c9db545b Mon Sep 17 00:00:00 2001 From: MilhouseVH Date: Sun, 3 Apr 2022 11:31:07 +0200 Subject: [PATCH] handle SIGTERM 0. CApplication::Stop cant be trusted. (deadlocks crashes and boo) so, when shutdown/reboot is requested: 1. save an exit code (for CEC...) 2. call CPowerManager::{Reboot,PowerDown} 3. ... then systemd sends TERM and waits xx seconds before sending KILL 4. CApplication::Stop has xx seconds to save guisettings.xml and boo 5. CEC thread has xx seconds to switch off after it received OnQuit 6. addons / pvrmanager / cec / everything else.. are free to deadlock / crash now, we dont care 7. KILL --- xbmc/application/Application.cpp | 24 ++++++++++++++----- xbmc/application/Application.h | 2 ++ .../powermanagement/LogindUPowerSyscall.cpp | 2 -- 3 files changed, 20 insertions(+), 8 deletions(-) --- a/xbmc/application/Application.cpp +++ b/xbmc/application/Application.cpp @@ -1473,12 +1473,12 @@ void CApplication::OnApplicationMessage( switch (msg) { case TMSG_POWERDOWN: - if (Stop(EXITCODE_POWERDOWN)) + if (SetExitCode(EXITCODE_POWERDOWN)) CServiceBroker::GetPowerManager().Powerdown(); break; case TMSG_QUIT: - Stop(EXITCODE_QUIT); + SetExitCode(EXITCODE_QUIT); break; case TMSG_SHUTDOWN: @@ -1499,12 +1499,13 @@ void CApplication::OnApplicationMessage( case TMSG_RESTART: case TMSG_RESET: - if (Stop(EXITCODE_REBOOT)) + if (SetExitCode(EXITCODE_REBOOT)) CServiceBroker::GetPowerManager().Reboot(); break; case TMSG_RESTARTAPP: #if defined(TARGET_WINDOWS) || defined(TARGET_LINUX) + SetExitCode(EXITCODE_RESTARTAPP); Stop(EXITCODE_RESTARTAPP); #endif break; @@ -2100,7 +2101,7 @@ bool CApplication::Stop(int exitCode) m_frameMoveGuard.unlock(); CVariant vExitCode(CVariant::VariantTypeObject); - vExitCode["exitcode"] = exitCode; + vExitCode["exitcode"] = m_ExitCode; CServiceBroker::GetAnnouncementManager()->Announce(ANNOUNCEMENT::System, "OnQuit", vExitCode); // Abort any active screensaver @@ -2132,7 +2133,6 @@ bool CApplication::Stop(int exitCode) // Needs cleaning up CServiceBroker::GetAppMessenger()->Stop(); m_AppFocused = false; - m_ExitCode = exitCode; CLog::Log(LOGINFO, "Stopping all"); // cancel any jobs from the jobmanager @@ -2689,6 +2689,18 @@ void CApplication::StopPlaying() } } +bool CApplication::SetExitCode(int exitCode) +{ + if (!m_ExitCodeSet) + { + CLog::Log(LOGINFO, "Saving exitCode {}", exitCode); + // save it for CEC + m_ExitCode = exitCode; + m_ExitCodeSet = true; + } + return true; +} + bool CApplication::OnMessage(CGUIMessage& message) { switch (message.GetMessage()) @@ -3269,7 +3281,7 @@ void CApplication::ProcessSlow() if (CPlatformPosix::TestQuitFlag()) { CLog::Log(LOGINFO, "Quitting due to POSIX signal"); - CServiceBroker::GetAppMessenger()->PostMsg(TMSG_QUIT); + CServiceBroker::GetAppMessenger()->PostMsg(TMSG_RESTARTAPP); } #endif --- a/xbmc/application/Application.h +++ b/xbmc/application/Application.h @@ -113,6 +113,7 @@ public: bool CreateGUI(); bool InitWindow(RESOLUTION res = RES_INVALID); + bool SetExitCode(int exitCode); bool Stop(int exitCode); const std::string& CurrentFile(); CFileItem& CurrentFileItem(); @@ -251,6 +252,7 @@ private: unsigned int m_ProcessedExternalCalls = 0; /*!< counts calls which are processed during one "door open" cycle in FrameMove */ unsigned int m_ProcessedExternalDecay = 0; /*!< counts to close door after a few frames of no python activity */ int m_ExitCode{EXITCODE_QUIT}; + bool m_ExitCodeSet = false; std::shared_ptr m_itemCurrentFile; //!< Currently playing file CEvent m_playerEvent; }; --- a/xbmc/platform/linux/powermanagement/LogindUPowerSyscall.cpp +++ b/xbmc/platform/linux/powermanagement/LogindUPowerSyscall.cpp @@ -79,8 +79,6 @@ CLogindUPowerSyscall::~CLogindUPowerSysc bool CLogindUPowerSyscall::Powerdown() { - // delay shutdown so that the app can close properly - InhibitDelayLockShutdown(); return LogindSetPowerState("PowerOff"); }