From e129eac3401f6af629ef96e91f4db62b3528cbc9 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Wed, 29 Apr 2026 01:20:11 +0300 Subject: #5719 Partial detection of shutdown from task manager We can't be absolutely certain about the source in this case, but at least try to distinguish termination caused by task manager from 'unknowns'. --- indra/llwindow/llwindowcallbacks.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/llwindow/llwindowcallbacks.cpp') diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index 7331f50ba0..6267433751 100644 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -68,6 +68,10 @@ void LLWindowCallbacks::handleMouseLeave(LLWindow *window) return; } +void LLWindowCallbacks::handlePreCloseRequest() +{ +} + bool LLWindowCallbacks::handleCloseRequest(LLWindow *window, bool from_user) { //allow the window to close -- cgit v1.3 From edf982b7a4efbee1ba75349c460e7040e8d04428 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Fri, 29 May 2026 03:03:31 +0300 Subject: #5719 Detect hybernation #2 --- indra/llwindow/llwindowcallbacks.cpp | 8 ++++++++ indra/llwindow/llwindowcallbacks.h | 2 ++ indra/llwindow/llwindowwin32.cpp | 15 ++++++++------- indra/newview/llappviewer.cpp | 29 ++++++++++++++++++----------- indra/newview/llappviewer.h | 2 ++ indra/newview/llviewerwindow.cpp | 18 ++++++++++++++++++ indra/newview/llviewerwindow.h | 2 ++ 7 files changed, 58 insertions(+), 18 deletions(-) (limited to 'indra/llwindow/llwindowcallbacks.cpp') diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index 6267433751..8d1eebe33d 100644 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -72,6 +72,14 @@ void LLWindowCallbacks::handlePreCloseRequest() { } +void LLWindowCallbacks::handleCloseRequestCanceled() +{ +} + +void LLWindowCallbacks::handleSuspendRequest() +{ +} + bool LLWindowCallbacks::handleCloseRequest(LLWindow *window, bool from_user) { //allow the window to close diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h index 457087448f..390e3ff93a 100644 --- a/indra/llwindow/llwindowcallbacks.h +++ b/indra/llwindow/llwindowcallbacks.h @@ -43,6 +43,8 @@ public: virtual void handleMouseLeave(LLWindow *window); // Called before close request is processed (ex: to create marker file in case OS is about to kill app). virtual void handlePreCloseRequest(); + virtual void handleCloseRequestCanceled(); + virtual void handleSuspendRequest(); // return true to allow window to close, which will then cause handleQuit to be called virtual bool handleCloseRequest(LLWindow *window, bool from_user); virtual bool handleSessionExit(LLWindow* window); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 52e0cdd5d5..79cdf8b67a 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -2657,21 +2657,22 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ // Viewer can't function in hibernation, try to shut down. // The system allows approximately two seconds for an // application to handle this notification. + + // Mark app as potentially closing, to minimize issues if OS does not recover. + window_imp->mCallbacks->handlePreCloseRequest(); window_imp->post([=]() { - LL_INFOS("Window") << "Shutting down due to system suspending (sleep/hibernate)" << LL_ENDL; - if (window_imp->mCallbacks->handleSessionExit(window_imp)) - { - // Get the app to initiate cleanup. - window_imp->mCallbacks->handleQuit(window_imp); - } + window_imp->mCallbacks->handleSuspendRequest(); }); + // Window thread normally doesn't block main thread, but OS can suspend + // immediately if we don't wait. + // Keep OS from suspending to give a chance to send stats. ms_sleep(1000); return TRUE; case PBT_APMRESUMESUSPEND: LL_INFOS("Window") << "System is resuming from suspend" << LL_ENDL; - // Shouldn't be up, but log just in case. + window_imp->mCallbacks->handleCloseRequestCanceled(); return TRUE; case PBT_APMPOWERSTATUSCHANGE: diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 7f06f991b0..6b5c0ea6b0 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4055,8 +4055,10 @@ void LLAppViewer::processMarkerFiles() // - Other Crash (SecondLife.error_marker present) // - Watchdog freeze (SecondLife.watchdog_marker present) // - Failed to initialize (SecondLife.inited_marker not present) - // - Potentially killed by task manager (SecondLife.close_marker present) - // These checks should also remove these files for the last 2 cases if they currently exist + // - Potentially killed by task manager or computer + // didn't recover from hibernation (SecondLife.close_marker present) + // These checks should also remove these files for the last 2 cases + // if they currently exist std::ostringstream marker_log_stream; bool marker_is_same_version = true; @@ -4227,21 +4229,21 @@ void LLAppViewer::processMarkerFiles() } } // If 'close' marker is found, viewer either started shutdown but - // failed, or viewer got killed by task manager. + // failed, OS did not recover from hibernation or viewer got + // killed by task manager. // Marker does not indicate that viewer was closed or is closing, // just that 'close' was requested before viewer died. else if (LLAPRFile::isExist(close_marker_file, NULL, LL_APR_RB)) { - // For now treat as 'other' cause. - // Unfortunately we can't for certain distinguish task - // manager's case from other shutdown problems, so we - // have to report both. - // Todo: if this bears noticeable fruits, make a new state later. - // New categories need server/web side support. + // Unfortunately we can't reliably distinguish + // task manager's case from genuine shutdown, so we + // have to report all of them as the same thing. + // Todo: but we can distinguish hibernation, might want + // to simply not report it as an issue. if (markerIsSameVersion(close_marker_file)) { - gLastExecEvent = LAST_EXEC_UNKNOWN == gLastExecEvent ? LAST_EXEC_OTHER_CRASH : LAST_EXEC_LOGOUT_CRASH; - LL_INFOS("MarkerFile") << "'Close' marker '" << close_marker_file << "' found, setting LastExecEvent to CRASH" + gLastExecEvent = LAST_EXEC_OS_EVENT; + LL_INFOS("MarkerFile") << "'Close' marker '" << close_marker_file << "' found, setting LastExecEvent to OS_EVENT" << LL_ENDL; } } @@ -4472,6 +4474,11 @@ void LLAppViewer::abortQuit() mClosingFloaters = false; } +void LLAppViewer::sendViewerStatistics() +{ + send_viewer_stats(false); +} + void LLAppViewer::migrateCacheDirectory() { #if LL_WINDOWS || LL_DARWIN diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index b404ec2c03..cde58b0850 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -79,6 +79,7 @@ typedef enum LAST_EXEC_INIT, LAST_EXEC_UNKNOWN, LAST_EXEC_LOGOUT_UNKNOWN, + LAST_EXEC_OS_EVENT, LAST_EXEC_COUNT } eLastExecEvent; @@ -113,6 +114,7 @@ public: const LLSD& substitutions = LLSD()); // Display an error dialog and forcibly quit. void earlyExitNoNotify(); // Do not display error dialog then forcibly quit. void abortQuit(); // Called to abort a quit request. + void sendViewerStatistics(); bool quitRequested() { return mQuitRequested; } bool logoutRequestSent() { return mLogoutRequestSent; } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index dbf9fe6bf2..abd7096f50 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1474,7 +1474,25 @@ void LLViewerWindow::handlePreCloseRequest() { LLAppViewer::instance()->createCloseRequestMarker(); } +} +void LLViewerWindow::handleCloseRequestCanceled() +{ + // WINDOW THREAD! since we need this to act fast. + if (!LLApp::isExiting() && !LLApp::isStopped()) + { + LLAppViewer::instance()->removeCloseRequestMarker(); + } +} + +void LLViewerWindow::handleSuspendRequest() +{ + LLAppViewer::instance()->sendViewerStatistics(); + // Todo: this should send a disconnect request as viewer + // can't keep heartbeat up while suspended and will get + // disconnected within a minute. + // Add a disconnect here once 'prevent OS from sleeping' + // feature is ready. } bool LLViewerWindow::handleCloseRequest(LLWindow *window, bool from_user) diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index ff5da371ec..b68956d853 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -203,6 +203,8 @@ public: /*virtual*/ bool handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); /*virtual*/ bool handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); /*virtual*/ void handlePreCloseRequest(); + /*virtual*/ void handleCloseRequestCanceled(); + /*virtual*/ void handleSuspendRequest(); /*virtual*/ bool handleCloseRequest(LLWindow *window, bool from_user); /*virtual*/ bool handleSessionExit(LLWindow* window); /*virtual*/ void handleQuit(LLWindow *window); -- cgit v1.3