Skip to content
Permalink
Browse files

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
  • Loading branch information...
stefansaraev committed Dec 15, 2014
1 parent 4786290 commit b24d9e0672495a2582541bcca0593d04c8131ff9
Showing with 30 additions and 5 deletions.
  1. +12 −5 xbmc/Application.cpp
  2. +1 −0 xbmc/Application.h
  3. +1 −0 xbmc/XBApplicationEx.cpp
  4. +1 −0 xbmc/XBApplicationEx.h
  5. +15 −0 xbmc/main/main.cpp
@@ -2493,12 +2493,12 @@ void CApplication::OnApplicationMessage(ThreadMessage* pMsg)
switch (pMsg->dwMessage)
{
case TMSG_POWERDOWN:
Stop(EXITCODE_POWERDOWN);
SetExitCode(EXITCODE_POWERDOWN);
g_powerManager.Powerdown();
break;

case TMSG_QUIT:
Stop(EXITCODE_QUIT);
SetExitCode(EXITCODE_QUIT);
break;

case TMSG_SHUTDOWN:
@@ -2544,12 +2544,13 @@ void CApplication::OnApplicationMessage(ThreadMessage* pMsg)

case TMSG_RESTART:
case TMSG_RESET:
Stop(EXITCODE_REBOOT);
SetExitCode(EXITCODE_REBOOT);
g_powerManager.Reboot();
break;

case TMSG_RESTARTAPP:
#if defined(TARGET_WINDOWS) || defined(TARGET_LINUX)
SetExitCode(EXITCODE_RESTARTAPP);
Stop(EXITCODE_RESTARTAPP);
#endif
break;
@@ -2900,12 +2901,19 @@ bool CApplication::Cleanup()
}
}

void CApplication::SetExitCode(int exitCode)
{
// save it for CEC
m_ExitCode = exitCode;
m_ExitCodeSet = true;
}

void CApplication::Stop(int exitCode)
{
try
{
CVariant vExitCode(CVariant::VariantTypeObject);
vExitCode["exitcode"] = exitCode;
vExitCode["exitcode"] = m_ExitCode;
CAnnouncementManager::Get().Announce(System, "xbmc", "OnQuit", vExitCode);

// Abort any active screensaver
@@ -2932,7 +2940,6 @@ void CApplication::Stop(int exitCode)

m_bStop = true;
m_AppFocused = false;
m_ExitCode = exitCode;
CLog::Log(LOGNOTICE, "stop all");

// cancel any jobs from the jobmanager
@@ -159,6 +159,7 @@ class CApplication : public CXBApplicationEx, public IPlayerCallback, public IMs
bool StartPVRManager();
void StopPVRManager();
bool IsCurrentThread() const;
void SetExitCode(int exitCode);
void Stop(int exitCode);
void RestartApp();
void UnloadSkin(bool forReload = false);
@@ -40,6 +40,7 @@ CXBApplicationEx::CXBApplicationEx()
m_bStop = false;
m_AppFocused = true;
m_ExitCode = EXITCODE_QUIT;
m_ExitCodeSet = false;
m_renderGUI = false;
}

@@ -40,6 +40,7 @@ class CXBApplicationEx : public IWindowManagerCallback
// Variables for timing
bool m_bStop;
int m_ExitCode;
bool m_ExitCodeSet;
bool m_AppFocused;
bool m_renderGUI;

@@ -41,12 +41,27 @@
#include "input/linux/LIRC.h"
#endif
#include "XbmcContext.h"
#include "Application.h"

void xbmc_term_handler(int signum)
{
CLog::Log(LOGINFO, "Received SIGTERM...");
if (!g_application.m_ExitCodeSet)
g_application.SetExitCode(EXITCODE_RESTARTAPP);
g_application.Stop(EXITCODE_RESTARTAPP);
}

#ifdef __cplusplus
extern "C"
#endif
int main(int argc, char* argv[])
{
// SIGTERM handler
struct sigaction action;
memset(&action, 0, sizeof(struct sigaction));
action.sa_handler = xbmc_term_handler;
sigaction(SIGTERM, &action, NULL);

// set up some xbmc specific relationships
XBMC::Context context;

0 comments on commit b24d9e0

Please sign in to comment.
You can’t perform that action at this time.