From 332f8f5c552f695d4e893512a642f9f9bbed6d9e Mon Sep 17 00:00:00 2001
From: MilhouseVH <milhouseVH.github@nmacleod.com>
Date: Tue, 19 Mar 2019 18:06:56 +0000
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.cpp                          | 23 ++++++++++++++-----
 xbmc/Application.h                            |  1 +
 xbmc/XBApplicationEx.cpp                      |  1 +
 xbmc/XBApplicationEx.h                        |  1 +
 .../powermanagement/LogindUPowerSyscall.cpp   |  2 --
 5 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
index bfa6083209..a7fbe8afd5 100644
--- a/xbmc/Application.cpp
+++ b/xbmc/Application.cpp
@@ -2029,12 +2029,12 @@ void CApplication::OnApplicationMessage(ThreadMessage* pMsg)
   switch (msg)
   {
   case TMSG_POWERDOWN:
-    Stop(EXITCODE_POWERDOWN);
+    SetExitCode(EXITCODE_POWERDOWN);
     CServiceBroker::GetPowerManager().Powerdown();
     break;
 
   case TMSG_QUIT:
-    Stop(EXITCODE_QUIT);
+    SetExitCode(EXITCODE_QUIT);
     break;
 
   case TMSG_SHUTDOWN:
@@ -2055,12 +2055,13 @@ void CApplication::OnApplicationMessage(ThreadMessage* pMsg)
 
   case TMSG_RESTART:
   case TMSG_RESET:
-    Stop(EXITCODE_REBOOT);
+    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;
@@ -2522,6 +2523,17 @@ bool CApplication::Cleanup()
   }
 }
 
+void CApplication::SetExitCode(int exitCode)
+{
+  if (!m_ExitCodeSet)
+  {
+    CLog::Log(LOGINFO, "Saving exitCode %d", exitCode);
+    // save it for CEC
+    m_ExitCode = exitCode;
+    m_ExitCodeSet = true;
+  }
+}
+
 void CApplication::Stop(int exitCode)
 {
   CLog::Log(LOGNOTICE, "Stopping player");
@@ -2548,7 +2560,7 @@ void CApplication::Stop(int exitCode)
     m_frameMoveGuard.unlock();
 
     CVariant vExitCode(CVariant::VariantTypeObject);
-    vExitCode["exitcode"] = exitCode;
+    vExitCode["exitcode"] = m_ExitCode;
     CServiceBroker::GetAnnouncementManager()->Announce(ANNOUNCEMENT::System, "xbmc", "OnQuit", vExitCode);
 
     // Abort any active screensaver
@@ -2580,7 +2592,6 @@ void CApplication::Stop(int exitCode)
     // Needs cleaning up
     CApplicationMessenger::GetInstance().Stop();
     m_AppFocused = false;
-    m_ExitCode = exitCode;
     CLog::Log(LOGNOTICE, "Stopping all");
 
     // cancel any jobs from the jobmanager
@@ -4111,7 +4122,7 @@ void CApplication::ProcessSlow()
   if (CPlatformPosix::TestQuitFlag())
   {
     CLog::Log(LOGNOTICE, "Quitting due to POSIX signal");
-    CApplicationMessenger::GetInstance().PostMsg(TMSG_QUIT);
+    CApplicationMessenger::GetInstance().PostMsg(TMSG_RESTARTAPP);
   }
 #endif
 
diff --git a/xbmc/Application.h b/xbmc/Application.h
index 57b006b60c..5b66d7f09f 100644
--- a/xbmc/Application.h
+++ b/xbmc/Application.h
@@ -156,6 +156,7 @@ public:
   bool StartServer(enum ESERVERS eServer, bool bStart, bool bWait = false);
 
   bool IsCurrentThread() const;
+  void SetExitCode(int exitCode);
   void Stop(int exitCode);
   void UnloadSkin(bool forReload = false);
   bool LoadCustomWindows();
diff --git a/xbmc/XBApplicationEx.cpp b/xbmc/XBApplicationEx.cpp
index fb0bd6c70d..4f829512f1 100644
--- a/xbmc/XBApplicationEx.cpp
+++ b/xbmc/XBApplicationEx.cpp
@@ -24,6 +24,7 @@ CXBApplicationEx::CXBApplicationEx()
   m_bStop = false;
   m_AppFocused = true;
   m_ExitCode = EXITCODE_QUIT;
+  m_ExitCodeSet = false;
   m_renderGUI = false;
 }
 
diff --git a/xbmc/XBApplicationEx.h b/xbmc/XBApplicationEx.h
index e7534b8c05..8f45f04ec8 100644
--- a/xbmc/XBApplicationEx.h
+++ b/xbmc/XBApplicationEx.h
@@ -29,6 +29,7 @@ public:
   // Variables for timing
   bool m_bStop;
   int  m_ExitCode;
+  bool m_ExitCodeSet;
   bool m_AppFocused;
   bool m_renderGUI;
 
diff --git a/xbmc/platform/linux/powermanagement/LogindUPowerSyscall.cpp b/xbmc/platform/linux/powermanagement/LogindUPowerSyscall.cpp
index 9e65e939fc..fec636a417 100644
--- a/xbmc/platform/linux/powermanagement/LogindUPowerSyscall.cpp
+++ b/xbmc/platform/linux/powermanagement/LogindUPowerSyscall.cpp
@@ -76,8 +76,6 @@ CLogindUPowerSyscall::~CLogindUPowerSyscall()
 
 bool CLogindUPowerSyscall::Powerdown()
 {
-  // delay shutdown so that the app can close properly
-  InhibitDelayLockShutdown();
   return LogindSetPowerState("PowerOff");
 }
 
-- 
2.19.1

