diff options
| author | Mike <contact@mikelittman.me> | 2026-10-14 00:04:11 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-10-14 13:04:11 +0800 |
| commit | 4d3ec2142c2fcafec17425284a59134f62c3f8b7 (patch) | |
| tree | 1a167e4b946da44f1ed3888850898b48a0db45fc | |
| parent | 9cc783022a202a1d00b5dc8eaf01ffddbc9fa39f (diff) | |
Log out before exiting on the first terminate signal (#35)
SIGTERM was marking the app quitting immediately, so the Mac frame
pump stopped before LogoutRequest and the simulator kept the agent
in the region. The first signal now runs the normal logout. A second
signal still forces the process to exit.
| -rw-r--r-- | indra/llcommon/llapp.cpp | 30 | ||||
| -rw-r--r-- | indra/llcommon/llapp.h | 3 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 8 |
3 files changed, 35 insertions, 6 deletions
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 02d6da989a..278a8f7c2f 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -28,6 +28,7 @@ #include "llapp.h" +#include <csignal> #include <cstdlib> #ifdef LL_DARWIN @@ -397,6 +398,22 @@ void LLApp::writeMiniDump() { } +namespace +{ + volatile sig_atomic_t sTermCount = 0; +} + +// static +bool LLApp::consumeSignalQuit() +{ + if (sTermCount == 0) + { + return false; + } + sTermCount = 0; + return true; +} + // static void LLApp::setQuitting() { @@ -623,18 +640,19 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *) { LL_WARNS() << "Signal handler - Got SIGINT, or TERM, exiting gracefully" << LL_ENDL; } - // Graceful exit - // Just set our state to quitting, not error - if (LLApp::isQuitting() || LLApp::isError()) + // The first signal asks the main loop to log out. setQuitting() here + // makes the Mac frame pump return immediately, so LogoutRequest is + // never sent and the simulator keeps the agent in the region. + if (sTermCount > 0 || LLApp::isQuitting() || LLApp::isError()) { - // We're already trying to die, just ignore this signal if (LLApp::sLogInSignal) { - LL_INFOS() << "Signal handler - Already trying to quit, ignoring signal!" << LL_ENDL; + LL_INFOS() << "Signal handler - Already trying to quit, forcing exit" << LL_ENDL; } + LLApp::setQuitting(); return; } - LLApp::setQuitting(); + sTermCount = 1; return; case SIGALRM: case SIGPIPE: diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index 3a855bc480..590991bbd7 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -195,6 +195,9 @@ public: // Application status // static void setQuitting(); // Set status to QUITTING, the app is now shutting down + // True once after SIGTERM or SIGINT. The main loop should log out + // before setQuitting(), so the simulator releases the agent. + static bool consumeSignalQuit(); static void setStopped(); // Set status to STOPPED, the app is done running and should exit static void setError(); // Set status to ERROR, the error handler should run static bool isStopped(); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index d48ccdb9ea..f8c687b0fc 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1360,6 +1360,14 @@ bool LLAppViewer::frame() bool LLAppViewer::doFrame() { + // SIGTERM asks for a normal logout. Quitting immediately skips + // LogoutRequest and leaves the agent in the region. + if (LLApp::consumeSignalQuit() && !mQuitRequested && !isQuitting()) + { + LL_INFOS() << "Terminate signal, logging out before exit" << LL_ENDL; + requestQuit(); + } + resumeMainloopTimeout("Main:doFrameStart"); U32 fpsLimitMaxFps = (U32)gSavedSettings.getU32("MaxFPS"); |
