summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-05-29 03:03:31 +0300
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-05-30 01:35:25 +0300
commitedf982b7a4efbee1ba75349c460e7040e8d04428 (patch)
tree3f9b195794f5c8be59c550c1219c42ec63e45a04
parent34540cce4f2d504740ea997016b4b06b80ae7adf (diff)
#5719 Detect hybernation #2
-rw-r--r--indra/llwindow/llwindowcallbacks.cpp8
-rw-r--r--indra/llwindow/llwindowcallbacks.h2
-rw-r--r--indra/llwindow/llwindowwin32.cpp15
-rw-r--r--indra/newview/llappviewer.cpp29
-rw-r--r--indra/newview/llappviewer.h2
-rw-r--r--indra/newview/llviewerwindow.cpp18
-rw-r--r--indra/newview/llviewerwindow.h2
7 files changed, 58 insertions, 18 deletions
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);