summaryrefslogtreecommitdiff
path: root/indra/newview/llappviewer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llappviewer.cpp')
-rw-r--r--indra/newview/llappviewer.cpp383
1 files changed, 283 insertions, 100 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index c770b7c917..677f34456e 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -298,6 +298,7 @@ bool gUseQuickTime = true;
eLastExecEvent gLastExecEvent = LAST_EXEC_NORMAL;
S32 gLastExecDuration = -1; // (<0 indicates unknown)
+LLUUID gLastAgentSessionId;
#if LL_WINDOWS
# define LL_PLATFORM_KEY "win"
@@ -348,10 +349,6 @@ std::string gLastVersionChannel;
LLVector3 gWindVec(3.0, 3.0, 0.0);
LLVector3 gRelativeWindVec(0.0, 0.0, 0.0);
-U32 gPacketsIn = 0;
-
-bool gPrintMessagesThisFrame = false;
-
bool gRandomizeFramerate = false;
bool gPeriodicSlowFrame = false;
@@ -360,6 +357,7 @@ bool gLLErrorActivated = false;
bool gLogoutInProgress = false;
bool gSimulateMemLeak = false;
+bool gDoDisconnect = false;
// We don't want anyone, especially threads working on the graphics pipeline,
// to have to block due to this WorkQueue being full.
@@ -372,9 +370,7 @@ const int MAX_MARKER_LENGTH = 1024;
const std::string MARKER_FILE_NAME("SecondLife.exec_marker");
const std::string START_MARKER_FILE_NAME("SecondLife.start_marker");
const std::string ERROR_MARKER_FILE_NAME("SecondLife.error_marker");
-const std::string LLERROR_MARKER_FILE_NAME("SecondLife.llerror_marker");
const std::string LOGOUT_MARKER_FILE_NAME("SecondLife.logout_marker");
-static bool gDoDisconnect = false;
static std::string gLaunchFileOnQuit;
// Used on Win32 for other apps to identify our window (eg, win_setup)
@@ -449,8 +445,8 @@ void idle_afk_check()
{
// check idle timers
F32 current_idle = gAwayTriggerTimer.getElapsedTimeF32();
- F32 afk_timeout = (F32)gSavedSettings.getS32("AFKTimeout");
- if (afk_timeout && (current_idle > afk_timeout) && ! gAgent.getAFK())
+ static LLCachedControl<S32> afk_timeout(gSavedSettings, "AFKTimeout", 300);
+ if (afk_timeout() && (current_idle > (F32)afk_timeout()) && !gAgent.getAFK())
{
LL_INFOS("IdleAway") << "Idle more than " << afk_timeout << " seconds: automatically changing to Away status" << LL_ENDL;
gAgent.setAFK();
@@ -479,7 +475,7 @@ static void deferred_ui_audio_callback(const LLUUID& uuid)
bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
{
- if(!match || !base || base->getPlainText())
+ if (!match || match->getSkipProfileIcon() || !base || base->getPlainText())
return false;
LLUUID match_id = match->getID();
@@ -1495,9 +1491,9 @@ bool LLAppViewer::doFrame()
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df pauseMainloopTimeout");
- pingMainloopTimeout("Main:Sleep");
+ pingMainloopTimeout("Main:Sleep");
- pauseMainloopTimeout();
+ pauseMainloopTimeout();
}
// Sleep and run background threads
@@ -2219,6 +2215,7 @@ bool LLAppViewer::initThreads()
return true;
}
+// Callback for all LL_ERROR calls
void errorCallback(LLError::ELevel level, const std::string &error_string)
{
if (level == LLError::LEVEL_ERROR)
@@ -2234,15 +2231,38 @@ void errorCallback(LLError::ELevel level, const std::string &error_string)
// haven't actually trashed anything yet, we can afford to write the whole
// static info file.
LLAppViewer::instance()->writeDebugInfo();
+
+ std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
+ if (!LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
+ {
+ // If marker doesn't exist, create a marker with llerror code for next launch
+ // otherwise don't override existing file
+ LLAppViewer::instance()->createErrorMarker(LAST_EXEC_LLERROR_CRASH);
+ }
}
}
-void errorMSG(const std::string& title_string, const std::string& message_string)
+// Callback for LLError::LLUserWarningMsg
+void errorHandler(const std::string& title_string, const std::string& message_string, S32 code)
{
if (!message_string.empty())
{
OSMessageBox(message_string, title_string.empty() ? LLTrans::getString("MBFatalError") : title_string, OSMB_OK);
}
+ switch (code)
+ {
+ case LLError::LLUserWarningMsg::ERROR_OTHER:
+ LLAppViewer::instance()->createErrorMarker(LAST_EXEC_OTHER_CRASH);
+ break;
+ case LLError::LLUserWarningMsg::ERROR_BAD_ALLOC:
+ LLAppViewer::instance()->createErrorMarker(LAST_EXEC_BAD_ALLOC);
+ break;
+ case LLError::LLUserWarningMsg::ERROR_MISSING_FILES:
+ LLAppViewer::instance()->createErrorMarker(LAST_EXEC_MISSING_FILES);
+ break;
+ default:
+ break;
+ }
}
void LLAppViewer::initLoggingAndGetLastDuration()
@@ -2256,7 +2276,7 @@ void LLAppViewer::initLoggingAndGetLastDuration()
LLError::addGenericRecorder(&errorCallback);
//LLError::setTimeFunction(getRuntime);
- LLError::LLUserWarningMsg::setHandler(errorMSG);
+ LLError::LLUserWarningMsg::setHandler(errorHandler);
if (mSecondInstance)
@@ -2330,6 +2350,14 @@ void LLAppViewer::initLoggingAndGetLastDuration()
{
LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL;
}
+
+ std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef.log");
+ if (gDirUtilp->fileExists(user_data_path_cef_log))
+ {
+ std::string user_data_path_cef_old = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef.old");
+ LLFile::remove(user_data_path_cef_old, ENOENT);
+ LLFile::rename(user_data_path_cef_log, user_data_path_cef_old);
+ }
}
}
@@ -2540,6 +2568,7 @@ bool LLAppViewer::initConfiguration()
OSMessageBox(
"Unable to load default settings file. The installation may be corrupted.",
LLStringUtil::null,OSMB_OK);
+ LLAppViewer::instance()->createErrorMarker(LAST_EXEC_MISSING_FILES);
return false;
}
@@ -2956,9 +2985,10 @@ void LLAppViewer::initStrings()
std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file);
if (strings_path_full.empty() || !LLFile::isfile(strings_path_full))
{
+ std::string crash_reason;
if (strings_path_full.empty())
{
- LL_WARNS() << "The file '" << strings_file << "' is not found" << LL_ENDL;
+ crash_reason = "The file '" + strings_file + "' is not found";
}
else
{
@@ -2966,24 +2996,23 @@ void LLAppViewer::initStrings()
int rc = LLFile::stat(strings_path_full, &st);
if (rc != 0)
{
- LL_WARNS() << "The file '" << strings_path_full << "' failed to get status. Error code: " << rc << LL_ENDL;
+ crash_reason = "The file '" + strings_path_full + "' failed to get status. Error code: " + std::to_string(rc);
}
else if (S_ISDIR(st.st_mode))
{
- LL_WARNS() << "The filename '" << strings_path_full << "' is a directory name" << LL_ENDL;
+ crash_reason = "The filename '" + strings_path_full + "' is a directory name";
}
else
{
- LL_WARNS() << "The filename '" << strings_path_full << "' doesn't seem to be a regular file name" << LL_ENDL;
+ crash_reason = "The filename '" + strings_path_full + "' doesn't seem to be a regular file name";
}
}
// initial check to make sure files are there failed
gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);
LLError::LLUserWarningMsg::showMissingFiles();
- LL_ERRS() << "Viewer failed to find localization and UI files."
- << " Please reinstall viewer from https://secondlife.com/support/downloads"
- << " and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
+ LL_ERRS() << "Viewer failed to open some of localization and UI files."
+ << " " << crash_reason << "." << LL_ENDL;
}
LLTransUtil::parseStrings(strings_file, default_trans_args);
LLTransUtil::parseLanguageStrings("language_settings.xml");
@@ -3702,16 +3731,21 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const
bool sameVersion = false;
std::string my_version(LLVersionInfo::instance().getChannelAndVersion());
- char marker_version[MAX_MARKER_LENGTH];
+ char marker_data[MAX_MARKER_LENGTH];
S32 marker_version_length;
LLAPRFile marker_file;
marker_file.open(marker_name, LL_APR_RB);
if (marker_file.getFileHandle())
{
- marker_version_length = marker_file.read(marker_version, sizeof(marker_version));
- std::string marker_string(marker_version, marker_version_length);
- if ( 0 == my_version.compare( 0, my_version.length(), marker_version, 0, marker_version_length ) )
+ marker_version_length = marker_file.read(marker_data, sizeof(marker_data));
+ std::string marker_string(marker_data, marker_version_length);
+ size_t pos = marker_string.find('\n');
+ if (pos != std::string::npos)
+ {
+ marker_string = marker_string.substr(0, pos);
+ }
+ if ( 0 == my_version.compare( 0, my_version.length(), marker_string, 0, marker_string.length()) )
{
sameVersion = true;
}
@@ -3725,6 +3759,88 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const
return sameVersion;
}
+void LLAppViewer::recordSessionToMarker()
+{
+ std::string marker_version(LLVersionInfo::instance().getChannelAndVersion());
+ std::string uuid_str = "\n" + gAgentSessionID.asString();
+ if (marker_version.length() + uuid_str.length() > MAX_MARKER_LENGTH)
+ {
+ LL_WARNS_ONCE("MarkerFile") << "Version length (" << marker_version.length() << ")"
+ << " greater than maximum (" << MAX_MARKER_LENGTH << ")"
+ << ": marker matching may be incorrect"
+ << LL_ENDL;
+ }
+
+ mMarkerFile.seek(APR_SET, (S32)marker_version.length());
+ mMarkerFile.write(uuid_str.data(), (S32)uuid_str.length());
+}
+
+LLUUID LLAppViewer::getMarkerSessionId(const std::string& marker_name) const
+{
+ std::string data;
+ if (getMarkerData(marker_name, data))
+ {
+ return LLUUID(data);
+ }
+ return LLUUID();
+}
+
+S32 LLAppViewer::getMarkerErrorCode(const std::string& marker_name) const
+{
+ std::string data;
+ if (getMarkerData(marker_name, data))
+ {
+ if (data.empty())
+ {
+ return 0;
+ }
+ else
+ {
+ return std::stoi(data);
+ }
+ }
+ return -1;
+}
+
+bool LLAppViewer::getMarkerData(const std::string& marker_name, std::string& data) const
+{
+ bool sameVersion = false;
+
+ std::string my_version(LLVersionInfo::instance().getChannelAndVersion());
+ char marker_data[MAX_MARKER_LENGTH];
+ S32 marker_version_length;
+
+ LLAPRFile marker_file;
+ marker_file.open(marker_name, LL_APR_RB);
+ if (marker_file.getFileHandle())
+ {
+ marker_version_length = marker_file.read(marker_data, sizeof(marker_data));
+ marker_file.close();
+ std::string marker_string(marker_data, marker_version_length);
+ size_t pos = marker_string.find('\n');
+ if (pos != std::string::npos)
+ {
+ data = marker_string.substr(pos + 1, marker_version_length - pos - 1);
+ marker_string = marker_string.substr(0, pos);
+ }
+ if (0 == my_version.compare(0, my_version.length(), marker_string, 0, marker_string.length()))
+ {
+ sameVersion = true;
+ }
+ else
+ {
+ return false;
+ }
+ LL_DEBUGS("MarkerFile") << "Compare markers for '" << marker_name << "': "
+ << "\n mine '" << my_version << "'"
+ << "\n marker '" << marker_string << "'"
+ << "\n " << (sameVersion ? "same" : "different") << " version"
+ << LL_ENDL;
+ return true;
+ }
+ return false;
+}
+
void LLAppViewer::processMarkerFiles()
{
//We've got 4 things to test for here
@@ -3743,6 +3859,10 @@ void LLAppViewer::processMarkerFiles()
// File exists...
// first, read it to see if it was created by the same version (we need this later)
marker_is_same_version = markerIsSameVersion(mMarkerFileName);
+ if (marker_is_same_version)
+ {
+ gLastAgentSessionId = getMarkerSessionId(mMarkerFileName);
+ }
// now test to see if this file is locked by a running process (try to open for write)
marker_log_stream << "Checking exec marker file for lock...";
@@ -3832,44 +3952,27 @@ void LLAppViewer::processMarkerFiles()
}
LLAPRFile::remove(logout_marker_file);
}
- // further refine based on whether or not a marker created during an llerr crash is found
- std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);
- if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))
- {
- if (markerIsSameVersion(llerror_marker_file))
- {
- if ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE )
- {
- gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
- LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
- }
- else
- {
- gLastExecEvent = LAST_EXEC_LLERROR_CRASH;
- LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LLERROR_CRASH" << LL_ENDL;
- }
- }
- else
- {
- LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL;
- }
- LLAPRFile::remove(llerror_marker_file);
- }
// and last refine based on whether or not a marker created during a non-llerr crash is found
std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
{
- if (markerIsSameVersion(error_marker_file))
+ S32 marker_code = getMarkerErrorCode(error_marker_file);
+ if (marker_code >= 0)
{
if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE)
{
gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
}
+ else if (marker_code > 0 && marker_code < (S32)LAST_EXEC_COUNT)
+ {
+ gLastExecEvent = (eLastExecEvent)marker_code;
+ LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ }
else
{
gLastExecEvent = LAST_EXEC_OTHER_CRASH;
- LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ LL_INFOS("MarkerFile") << "Error marker '" << error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
}
}
else
@@ -4145,7 +4248,7 @@ U32 LLAppViewer::getTextureCacheVersion()
U32 LLAppViewer::getDiskCacheVersion()
{
// Viewer disk cache version intorduced in Simple Cache Viewer, change if the cache format changes.
- const U32 DISK_CACHE_VERSION = 1;
+ const U32 DISK_CACHE_VERSION = 3;
return DISK_CACHE_VERSION ;
}
@@ -4437,6 +4540,7 @@ void LLAppViewer::saveFinalSnapshot()
false,
gSavedSettings.getBOOL("RenderHUDInSnapshot"),
true,
+ false,
LLSnapshotModel::SNAPSHOT_TYPE_COLOR,
LLSnapshotModel::SNAPSHOT_FORMAT_PNG);
mSavedFinalSnapshot = true;
@@ -4464,11 +4568,32 @@ void LLAppViewer::saveFinalSnapshot()
}
}
+static const char PRODUCTION_CACHE_FORMAT_STRING[] = "%s.%s";
+static const char GRID_CACHE_FORMAT_STRING[] = "%s.%s.%s";
+std::string get_name_cache_filename(const std::string &base_file, const std::string& extention)
+{
+ std::string filename;
+ std::string path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, base_file));
+ if (LLGridManager::getInstance()->isInProductionGrid())
+ {
+ filename = llformat(PRODUCTION_CACHE_FORMAT_STRING, path.c_str(), extention.c_str());
+ }
+ else
+ {
+ // NOTE: The inventory cache filenames now include the grid name.
+ // Add controls against directory traversal or problematic pathname lengths
+ // if your viewer uses grid names from an untrusted source.
+ const std::string& grid_id_str = LLGridManager::getInstance()->getGridId();
+ const std::string& grid_id_lower = utf8str_tolower(grid_id_str);
+ filename = llformat(GRID_CACHE_FORMAT_STRING, path.c_str(), grid_id_lower.c_str(), extention.c_str());
+ }
+ return filename;
+}
+
void LLAppViewer::loadNameCache()
{
// display names cache
- std::string filename =
- gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml");
+ std::string filename = get_name_cache_filename("avatar_name_cache", "xml");
LL_INFOS("AvNameCache") << filename << LL_ENDL;
llifstream name_cache_stream(filename.c_str());
if(name_cache_stream.is_open())
@@ -4483,8 +4608,8 @@ void LLAppViewer::loadNameCache()
if (!gCacheName) return;
- std::string name_cache;
- name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache");
+ // is there a reason for the "cache" extention?
+ std::string name_cache = get_name_cache_filename("name", "cache");
llifstream cache_file(name_cache.c_str());
if(cache_file.is_open())
{
@@ -4495,8 +4620,7 @@ void LLAppViewer::loadNameCache()
void LLAppViewer::saveNameCache()
{
// display names cache
- std::string filename =
- gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml");
+ std::string filename = get_name_cache_filename("avatar_name_cache", "xml");
llofstream name_cache_stream(filename.c_str());
if(name_cache_stream.is_open())
{
@@ -4506,8 +4630,7 @@ void LLAppViewer::saveNameCache()
// real names cache
if (gCacheName)
{
- std::string name_cache;
- name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache");
+ std::string name_cache = get_name_cache_filename("name", "cache");
llofstream cache_file(name_cache.c_str());
if(cache_file.is_open())
{
@@ -4785,6 +4908,20 @@ void LLAppViewer::idle()
if (gTeleportDisplay)
{
+ if (gAgent.getTeleportState() == LLAgent::TELEPORT_ARRIVING)
+ {
+ // Teleported, but waiting for things to load, start processing surface data
+ {
+ LL_RECORD_BLOCK_TIME(FTM_NETWORK);
+ gVLManager.unpackData();
+ }
+ {
+ LL_RECORD_BLOCK_TIME(FTM_REGION_UPDATE);
+ const F32 max_region_update_time = .001f; // 1ms
+ LLWorld::getInstance()->updateRegions(max_region_update_time);
+ }
+ }
+
return;
}
@@ -5080,15 +5217,28 @@ void LLAppViewer::sendLogoutRequest()
gLogoutInProgress = true;
if (!mSecondInstance)
{
- mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
-
- mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB);
- if (mLogoutMarkerFile.getFileHandle())
+ mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME);
+ try
{
- LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL;
- recordMarkerVersion(mLogoutMarkerFile);
+ if (!mLogoutMarkerFile.getFileHandle())
+ {
+ mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB);
+ if (mLogoutMarkerFile.getFileHandle())
+ {
+ LL_INFOS("MarkerFile") << "Created logout marker file '" << mLogoutMarkerFileName << "' " << LL_ENDL;
+ recordMarkerVersion(mLogoutMarkerFile);
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "Atempted to reopen file '" << mLogoutMarkerFileName << "' " << LL_ENDL;
+ }
}
- else
+ catch (...)
{
LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL;
}
@@ -5105,6 +5255,8 @@ void LLAppViewer::sendLogoutRequest()
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
gAgent.sendReliableMessage();
+ LL_INFOS("Agent") << "Logging out as agent: " << gAgent.getID() << " Session: " << gAgent.getSessionID() << LL_ENDL;
+
gLogoutTimer.reset();
gLogoutMaxTime = LOGOUT_REQUEST_TIME;
mLogoutRequestSent = true;
@@ -5159,6 +5311,24 @@ void LLAppViewer::postToMainCoro(const LL::WorkQueue::Work& work)
gMainloopWork.post(work);
}
+void LLAppViewer::createErrorMarker(eLastExecEvent error_code) const
+{
+ if (!mSecondInstance)
+ {
+ std::string error_marker = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
+
+ LLAPRFile file;
+ file.open(error_marker, LL_APR_WB);
+ if (file.getFileHandle())
+ {
+ recordMarkerVersion(file);
+ std::string data = "\n" + std::to_string((S32)error_code);
+ file.write(data.data(), static_cast<S32>(data.length()));
+ file.close();
+ }
+ }
+}
+
void LLAppViewer::outOfMemorySoftQuit()
{
if (!mQuitRequested)
@@ -5203,12 +5373,9 @@ void LLAppViewer::idleNameCache()
// Handle messages, and all message related stuff
//
-#define TIME_THROTTLE_MESSAGES
-#ifdef TIME_THROTTLE_MESSAGES
-#define CHECK_MESSAGES_DEFAULT_MAX_TIME .020f // 50 ms = 50 fps (just for messages!)
+constexpr F32 CHECK_MESSAGES_DEFAULT_MAX_TIME = 0.020f; // 50 ms = 50 fps (just for messages!)
static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
-#endif
static LLTrace::BlockTimerStatHandle FTM_IDLE_NETWORK("Idle Network");
static LLTrace::BlockTimerStatHandle FTM_MESSAGE_ACKS("Message Acks");
@@ -5225,7 +5392,8 @@ void LLAppViewer::idleNetwork()
gObjectList.mNumNewObjects = 0;
S32 total_decoded = 0;
- if (!gSavedSettings.getBOOL("SpeedTest"))
+ static LLCachedControl<bool> speed_test(gSavedSettings, "SpeedTest", false);
+ if (!speed_test())
{
LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("idle network"); //LL_RECORD_BLOCK_TIME(FTM_IDLE_NETWORK); // decode
@@ -5235,6 +5403,7 @@ void LLAppViewer::idleNetwork()
F32 total_time = 0.0f;
{
+ bool needs_drain = false;
LockMessageChecker lmc(gMessageSystem);
while (lmc.checkAllMessages(frame_count, gServicePump))
{
@@ -5247,53 +5416,45 @@ void LLAppViewer::idleNetwork()
}
total_decoded++;
- gPacketsIn++;
if (total_decoded > MESSAGE_MAX_PER_FRAME)
{
+ needs_drain = true;
break;
}
-#ifdef TIME_THROTTLE_MESSAGES
// Prevent slow packets from completely destroying the frame rate.
// This usually happens due to clumps of avatars taking huge amount
// of network processing time (which needs to be fixed, but this is
// a good limit anyway).
total_time = check_message_timer.getElapsedTimeF32();
if (total_time >= CheckMessagesMaxTime)
+ {
+ needs_drain = true;
break;
-#endif
+ }
+ }
+ if (needs_drain || gMessageSystem->mPacketRing.getNumBufferedPackets() > 0)
+ {
+ // Rather than allow packets to silently backup on the socket
+ // we drain them into our own buffer so we know how many exist.
+ S32 num_buffered_packets = gMessageSystem->drainUdpSocket();
+ if (num_buffered_packets > 0)
+ {
+ // Increase CheckMessagesMaxTime so that we will eventually catch up
+ CheckMessagesMaxTime *= 1.035f; // 3.5% ~= 2x in 20 frames, ~8x in 60 frames
+ }
+ }
+ else
+ {
+ // Reset CheckMessagesMaxTime to default value
+ CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
}
// Handle per-frame message system processing.
- lmc.processAcks(gSavedSettings.getF32("AckCollectTime"));
- }
-#ifdef TIME_THROTTLE_MESSAGES
- if (total_time >= CheckMessagesMaxTime)
- {
- // Increase CheckMessagesMaxTime so that we will eventually catch up
- CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames
- }
- else
- {
- // Reset CheckMessagesMaxTime to default value
- CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
- }
-#endif
-
- // Decode enqueued messages...
- S32 remaining_possible_decodes = MESSAGE_MAX_PER_FRAME - total_decoded;
-
- if( remaining_possible_decodes <= 0 )
- {
- LL_INFOS() << "Maxed out number of messages per frame at " << MESSAGE_MAX_PER_FRAME << LL_ENDL;
- }
-
- if (gPrintMessagesThisFrame)
- {
- LL_INFOS() << "Decoded " << total_decoded << " msgs this frame!" << LL_ENDL;
- gPrintMessagesThisFrame = false;
+ static LLCachedControl<F32> ack_collection_time(gSavedSettings, "AckCollectTime", 0.1f);
+ lmc.processAcks(ack_collection_time());
}
}
add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects);
@@ -5301,6 +5462,7 @@ void LLAppViewer::idleNetwork()
// Retransmit unacknowledged packets.
gXferManager->retransmitUnackedPackets();
gAssetStorage->checkForTimeouts();
+ gViewerThrottle.setBufferLoadRate(gMessageSystem->getBufferLoadRate());
gViewerThrottle.updateDynamicThrottle();
// Check that the circuit between the viewer and the agent's current
@@ -5475,6 +5637,27 @@ void LLAppViewer::forceErrorCoroutineCrash()
LLCoros::instance().launch("LLAppViewer::crashyCoro", [] {throw LLException("A deliberate crash from LLCoros"); });
}
+void LLAppViewer::forceErrorCoroprocedureCrash()
+{
+ LL_WARNS() << "Forcing a crash in LLCoprocedureManager" << LL_ENDL;
+ LLCoprocedureManager::instance().enqueueCoprocedure("Upload", "DeliberateCrash",
+ [](LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t&, const LLUUID&)
+ {
+ LL_WARNS() << "Forcing a deliberate bad memory access from LLCoprocedureManager" << LL_ENDL;
+ S32* crash = NULL;
+ *crash = 0xDEADBEEF;
+ });
+}
+
+void LLAppViewer::forceErrorWorkQueueCrash()
+{
+ LL::WorkQueue::ptr_t workqueue = LL::WorkQueue::getInstance("General");
+ if (workqueue)
+ {
+ workqueue->post([]() { throw LLException("This is a deliberate crash from General Queue"); });
+ }
+}
+
void LLAppViewer::forceErrorThreadCrash()
{
class LLCrashTestThread : public LLThread