summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorErik Kundiman <erik@megapahit.org>2026-01-11 16:35:26 +0800
committerErik Kundiman <erik@megapahit.org>2026-01-11 16:35:26 +0800
commit2f765440f8f7017e5af219c6124705c76af477c8 (patch)
treea5ac1cf749b0377ee3780737615bd75c1a5fe306 /indra/newview
parentbb0d3408d116174986765bcb2cd698a9d4a4f0d7 (diff)
parentb26f62eb0ce72b9cdd83296e87ba1954ee1b8b04 (diff)
Merge tag 'Second_Life_Release#b26f62eb-26.1' into 2026.01
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/app_settings/settings.xml2
-rw-r--r--indra/newview/llappviewer.cpp14
-rw-r--r--indra/newview/lllandmarklist.cpp49
-rw-r--r--indra/newview/lllandmarklist.h1
-rw-r--r--indra/newview/llpanelface.cpp32
-rw-r--r--indra/newview/llpanelface.h2
-rw-r--r--indra/newview/llviewerassetstorage.cpp71
-rw-r--r--indra/newview/llwatchdog.cpp295
-rw-r--r--indra/newview/llwatchdog.h107
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml2
-rwxr-xr-xindra/newview/viewer_manifest.py5
12 files changed, 147 insertions, 435 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 9a7e66fb97..e609416dc1 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -745,7 +745,6 @@ set(viewer_SOURCE_FILES
llvovolume.cpp
llvowater.cpp
llvowlsky.cpp
- llwatchdog.cpp
llwearableitemslist.cpp
llwearablelist.cpp
llweb.cpp
@@ -1433,7 +1432,6 @@ set(viewer_HEADER_FILES
llvovolume.h
llvowater.h
llvowlsky.h
- llwatchdog.h
llwearableitemslist.h
llwearablelist.h
llweb.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index cdb712df99..5361f58dbe 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -9124,7 +9124,7 @@
<key>Comment</key>
<string>Show reflection probes in the transparency debug view</string>
<key>Persist</key>
- <integer>1</integer>
+ <integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index d4e9736f61..93f0142994 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3243,7 +3243,19 @@ bool LLAppViewer::initWindow()
if (use_watchdog)
{
- LLWatchdog::getInstance()->init();
+ LLWatchdog::getInstance()->init([]()
+ {
+ LLAppViewer* app = LLAppViewer::instance();
+ if (app->logoutRequestSent())
+ {
+ app->createErrorMarker(LAST_EXEC_LOGOUT_FROZE);
+ }
+ else
+ {
+ app->createErrorMarker(LAST_EXEC_FROZE);
+ }
+ });
+ gViewerWindow->getWindow()->initWatchdog();
}
LLNotificationsUI::LLNotificationManager::getInstance();
diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index 3fa0ab99f3..b25a42a938 100644
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
@@ -147,29 +147,66 @@ void LLLandmarkList::processGetAssetReply(
else
{
// failed to parse, shouldn't happen
+ LL_WARNS("Landmarks") << "Failed to parse landmark " << uuid << LL_ENDL;
gLandmarkList.eraseCallbacks(uuid);
}
}
else
{
// got a good status, but no file, shouldn't happen
+ LL_WARNS("Landmarks") << "Empty buffer for landmark " << uuid << LL_ENDL;
gLandmarkList.eraseCallbacks(uuid);
}
+
+ // We got this asset, remove it from retry and bad lists.
+ gLandmarkList.mRetryList.erase(uuid);
+ gLandmarkList.mBadList.erase(uuid);
}
else
{
- // SJB: No use case for a notification here. Use LL_DEBUGS() instead
- if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status )
+ if (LL_ERR_NO_CAP == status)
+ {
+ // A problem with asset cap, always allow retrying.
+ // Todo: should this reschedule?
+ gLandmarkList.mRequestedList.erase(uuid);
+ gLandmarkList.eraseCallbacks(uuid);
+ // If there was a previous request, it likely failed due to an obsolete cap
+ // so clear the retry marker to allow multiple retries.
+ gLandmarkList.mRetryList.erase(uuid);
+ return;
+ }
+ if (gLandmarkList.mBadList.find(uuid) != gLandmarkList.mBadList.end())
+ {
+ // Already on the 'bad' list, ignore
+ gLandmarkList.mRequestedList.erase(uuid);
+ gLandmarkList.eraseCallbacks(uuid);
+ return;
+ }
+ if (LL_ERR_ASSET_REQUEST_FAILED == status
+ && gLandmarkList.mRetryList.find(uuid) == gLandmarkList.mRetryList.end())
+ {
+ // There is a number of reasons why an asset request can fail,
+ // like a cap being obsolete due to user teleporting.
+ // Let viewer rerequest at least once more.
+ // Todo: should this reshchedule?
+ gLandmarkList.mRetryList.emplace(uuid);
+ gLandmarkList.mRequestedList.erase(uuid);
+ gLandmarkList.eraseCallbacks(uuid);
+ return;
+ }
+
+ if (LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status)
{
- LL_WARNS("Landmarks") << "Missing Landmark" << LL_ENDL;
- //LLNotificationsUtil::add("LandmarkMissing");
+ LL_WARNS("Landmarks") << "Missing Landmark " << uuid << LL_ENDL;
}
else
{
- LL_WARNS("Landmarks") << "Unable to load Landmark" << LL_ENDL;
- //LLNotificationsUtil::add("UnableToLoadLandmark");
+ LL_WARNS("Landmarks") << "Unable to load Landmark " << uuid
+ << ". asset status: " << status
+ << ". Extended status: " << (S64)ext_status << LL_ENDL;
}
+ gLandmarkList.mRetryList.erase(uuid);
gLandmarkList.mBadList.insert(uuid);
gLandmarkList.mRequestedList.erase(uuid); //mBadList effectively blocks any load, so no point keeping id in requests
gLandmarkList.eraseCallbacks(uuid);
diff --git a/indra/newview/lllandmarklist.h b/indra/newview/lllandmarklist.h
index fb8b5a1960..76b5b97211 100644
--- a/indra/newview/lllandmarklist.h
+++ b/indra/newview/lllandmarklist.h
@@ -72,6 +72,7 @@ protected:
typedef std::set<LLUUID> landmark_uuid_list_t;
landmark_uuid_list_t mBadList;
+ landmark_uuid_list_t mRetryList;
typedef std::map<LLUUID,F32> landmark_requested_list_t;
landmark_requested_list_t mRequestedList;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 02efaa6090..6c0ff4a929 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -1201,7 +1201,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
// See if that's been overridden by a material setting for same...
//
- LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode, mIsAlpha);
+ LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode);
// it is invalid to have any alpha mode other than blend if transparency is greater than zero ...
// Want masking? Want emissive? Tough! You get BLEND!
@@ -1211,6 +1211,12 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
alpha_mode = mIsAlpha ? alpha_mode : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
mComboAlphaMode->getSelectionInterface()->selectNthItem(alpha_mode);
+ mComboAlphaMode->setTentative(!identical_alpha_mode);
+ if (!identical_alpha_mode)
+ {
+ std::string multiple = LLTrans::getString("multiple_textures");
+ mComboAlphaMode->setLabel(multiple);
+ }
updateAlphaControls();
mExcludeWater &= (LLMaterial::DIFFUSE_ALPHA_MODE_BLEND == alpha_mode);
@@ -5484,32 +5490,40 @@ void LLPanelFace::LLSelectedTEMaterial::getMaxNormalRepeats(F32& repeats, bool&
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_norm_repeats_func, repeats);
}
-void LLPanelFace::LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha)
+void LLPanelFace::LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical)
{
struct LLSelectedTEGetDiffuseAlphaMode : public LLSelectedTEGetFunctor<U8>
{
- LLSelectedTEGetDiffuseAlphaMode() : _isAlpha(false) {}
- LLSelectedTEGetDiffuseAlphaMode(bool diffuse_texture_has_alpha) : _isAlpha(diffuse_texture_has_alpha) {}
+ LLSelectedTEGetDiffuseAlphaMode() {}
virtual ~LLSelectedTEGetDiffuseAlphaMode() {}
U8 get(LLViewerObject* object, S32 face)
{
- U8 diffuse_mode = _isAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
-
LLTextureEntry* tep = object->getTE(face);
if (tep)
{
LLMaterial* mat = tep->getMaterialParams().get();
if (mat)
{
- diffuse_mode = mat->getDiffuseAlphaMode();
+ return mat->getDiffuseAlphaMode();
+ }
+ }
+
+ bool has_alpha = false;
+ LLViewerTexture* image = object->getTEImage(face);
+ if (image)
+ {
+ LLGLenum format = image->getPrimaryFormat();
+ if (format == GL_RGBA || format == GL_ALPHA)
+ {
+ has_alpha = true;
}
}
+ U8 diffuse_mode = has_alpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
return diffuse_mode;
}
- bool _isAlpha; // whether or not the diffuse texture selected contains alpha information
- } get_diff_mode(diffuse_texture_has_alpha);
+ } get_diff_mode;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &get_diff_mode, diffuse_alpha_mode);
}
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index ebfa825729..86d5282518 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -652,7 +652,7 @@ public:
static void getCurrent(LLMaterialPtr& material_ptr, bool& identical_material);
static void getMaxSpecularRepeats(F32& repeats, bool& identical);
static void getMaxNormalRepeats(F32& repeats, bool& identical);
- static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha);
+ static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical);
static void selectionNormalScaleAutofit(LLPanelFace* panel_face, F32 repeats_per_meter);
static void selectionSpecularScaleAutofit(LLPanelFace* panel_face, F32 repeats_per_meter);
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index 141f370ecb..fd462fb225 100644
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -42,6 +42,7 @@
#include "llcoproceduremanager.h"
#include "lleventcoro.h"
#include "llsdutil.h"
+#include "llstartup.h"
#include "llworld.h"
///----------------------------------------------------------------------------
@@ -460,28 +461,78 @@ void LLViewerAssetStorage::assetRequestCoro(
if (!gAgent.getRegion())
{
- LL_WARNS_ONCE("ViewerAsset") << "Asset request fails: no region set" << LL_ENDL;
- result_code = LL_ERR_ASSET_REQUEST_FAILED;
- ext_status = LLExtStat::NONE;
- removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status, 0);
- return;
+ if (STATE_WORLD_INIT <= LLStartUp::getStartupState())
+ {
+ // Viewer isn't ready, wait for region to become available
+ LL_INFOS_ONCE("ViewerAsset") << "Waiting for agent region to be set" << LL_ENDL;
+
+ LLEventStream region_init("waitForRegion", true);
+ std::string pump_name = region_init.getName();
+
+ boost::signals2::connection region_conn =
+ gAgent.addRegionChangedCallback([pump_name]()
+ {
+ LLEventPumps::instance().obtain(pump_name).post(LLSD());
+ });
+ F32Seconds timeout_seconds(LL_ASSET_STORAGE_TIMEOUT);
+ llcoro::suspendUntilEventOnWithTimeout(region_init, timeout_seconds, LLSDMap("timeout", LLSD::Boolean(true)));
+ gAgent.removeRegionChangedCallback(region_conn);
+ region_conn.disconnect();
+
+ if (LLApp::isExiting() || !gAssetStorage)
+ {
+ return;
+ }
+
+ // recheck region whether suspend ended on timeout or not
+ if (!gAgent.getRegion())
+ {
+ LL_WARNS_ONCE("ViewerAsset") << "Asset request fails: timeout reached while waiting for region" << LL_ENDL;
+ result_code = LL_ERR_NO_CAP;
+ ext_status = LLExtStat::NONE;
+ removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status, 0);
+ return;
+ }
+ }
+ else
+ {
+ LL_WARNS_ONCE("ViewerAsset") << "Asset request fails: no region set" << LL_ENDL;
+ result_code = LL_ERR_NO_CAP;
+ ext_status = LLExtStat::NONE;
+ removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status, 0);
+ return;
+ }
}
- else if (!gAgent.getRegion()->capabilitiesReceived())
+
+ if (!gAgent.getRegion()->capabilitiesReceived())
{
LL_WARNS_ONCE("ViewerAsset") << "Waiting for capabilities" << LL_ENDL;
LLEventStream capsRecv("waitForCaps", true);
- gAgent.getRegion()->setCapabilitiesReceivedCallback(
- boost::bind(&LLViewerAssetStorage::capsRecvForRegion, this, _1, capsRecv.getName()));
+ boost::signals2::connection caps_conn =
+ gAgent.getRegion()->setCapabilitiesReceivedCallback(
+ boost::bind(&LLViewerAssetStorage::capsRecvForRegion, this, _1, capsRecv.getName()));
- llcoro::suspendUntilEventOn(capsRecv);
+ F32Seconds timeout_seconds(LL_ASSET_STORAGE_TIMEOUT); // from minutes to seconds, by default 5 minutes
+ LLSD result = llcoro::suspendUntilEventOnWithTimeout(capsRecv, timeout_seconds, LLSDMap("timeout", LLSD::Boolean(true)));
+ caps_conn.disconnect();
if (LLApp::isExiting() || !gAssetStorage)
{
return;
}
+ if (result.has("timeout"))
+ {
+ // Caps failed to arrive in 5 minutes
+ LL_WARNS_ONCE("ViewerAsset") << "Asset " << uuid << " request fails : capabilities took too long to arrive" << LL_ENDL;
+ result_code = LL_ERR_NO_CAP;
+ ext_status = LLExtStat::NONE;
+ removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status, 0);
+ return;
+ }
+
LL_WARNS_ONCE("ViewerAsset") << "capsRecv got event" << LL_ENDL;
LL_WARNS_ONCE("ViewerAsset") << "region " << gAgent.getRegion() << " mViewerAssetUrl " << mViewerAssetUrl << LL_ENDL;
}
@@ -492,7 +543,7 @@ void LLViewerAssetStorage::assetRequestCoro(
if (mViewerAssetUrl.empty())
{
LL_WARNS_ONCE("ViewerAsset") << "asset request fails: caps received but no viewer asset cap found" << LL_ENDL;
- result_code = LL_ERR_ASSET_REQUEST_FAILED;
+ result_code = LL_ERR_NO_CAP;
ext_status = LLExtStat::NONE;
removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status, 0);
return;
diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp
deleted file mode 100644
index 0984606456..0000000000
--- a/indra/newview/llwatchdog.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-/**
- * @file llthreadwatchdog.cpp
- * @brief The LLThreadWatchdog class definitions
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-#include "llviewerprecompiledheaders.h"
-#include "llwatchdog.h"
-#include "llthread.h"
-#include "llappviewer.h"
-
-constexpr U32 WATCHDOG_SLEEP_TIME_USEC = 1000000U;
-
-// This class runs the watchdog timing thread.
-class LLWatchdogTimerThread : public LLThread
-{
-public:
- LLWatchdogTimerThread() :
- LLThread("Watchdog"),
- mSleepMsecs(0),
- mStopping(false)
- {
- }
-
- ~LLWatchdogTimerThread() {}
-
- void setSleepTime(long ms) { mSleepMsecs = ms; }
- void stop()
- {
- mStopping = true;
- mSleepMsecs = 1;
- }
-
- void run() override
- {
- while(!mStopping)
- {
- LLWatchdog::getInstance()->run();
- ms_sleep(mSleepMsecs);
- }
- }
-
-private:
- long mSleepMsecs;
- bool mStopping;
-};
-
-// LLWatchdogEntry
-LLWatchdogEntry::LLWatchdogEntry(const std::string& thread_name)
- : mThreadName(thread_name)
- , mThreadID(LLThread::currentID())
-{
-}
-
-LLWatchdogEntry::~LLWatchdogEntry()
-{
- stop();
-}
-
-void LLWatchdogEntry::start()
-{
- LLWatchdog::getInstance()->add(this);
-}
-
-void LLWatchdogEntry::stop()
-{
- // this can happen very late in the shutdown sequence
- if (!LLWatchdog::wasDeleted())
- {
- LLWatchdog::getInstance()->remove(this);
- }
-}
-std::string LLWatchdogEntry::getThreadName() const
-{
- return mThreadName + llformat(": %d", mThreadID);
-}
-
-// LLWatchdogTimeout
-const std::string UNINIT_STRING = "uninitialized";
-
-LLWatchdogTimeout::LLWatchdogTimeout(const std::string& thread_name) :
- LLWatchdogEntry(thread_name),
- mTimeout(0.0f),
- mPingState(UNINIT_STRING)
-{
-}
-
-LLWatchdogTimeout::~LLWatchdogTimeout()
-{
-}
-
-bool LLWatchdogTimeout::isAlive() const
-{
- return (mTimer.getStarted() && !mTimer.hasExpired());
-}
-
-void LLWatchdogTimeout::reset()
-{
- mTimer.setTimerExpirySec(mTimeout);
-}
-
-void LLWatchdogTimeout::setTimeout(F32 d)
-{
- mTimeout = d;
-}
-
-void LLWatchdogTimeout::start(std::string_view state)
-{
- if (mTimeout == 0)
- {
- LL_WARNS() << "Cant' start watchdog entry - no timeout set" << LL_ENDL;
- return;
- }
- // Order of operation is very important here.
- // After LLWatchdogEntry::start() is called
- // LLWatchdogTimeout::isAlive() will be called asynchronously.
- ping(state);
- mTimer.start();
- mTimer.setTimerExpirySec(mTimeout); // timer expiration set to 0 by start()
- LLWatchdogEntry::start();
-}
-
-void LLWatchdogTimeout::stop()
-{
- LLWatchdogEntry::stop();
- mTimer.stop();
-}
-
-void LLWatchdogTimeout::ping(std::string_view state)
-{
- if (!state.empty())
- {
- mPingState = state;
- }
- reset();
-}
-
-// LLWatchdog
-LLWatchdog::LLWatchdog()
- :mSuspectsAccessMutex()
- ,mTimer(nullptr)
- ,mLastClockCount(0)
-{
-}
-
-LLWatchdog::~LLWatchdog()
-{
-}
-
-void LLWatchdog::add(LLWatchdogEntry* e)
-{
- lockThread();
- mSuspects.insert(e);
- unlockThread();
-}
-
-void LLWatchdog::remove(LLWatchdogEntry* e)
-{
- lockThread();
- mSuspects.erase(e);
- unlockThread();
-}
-
-void LLWatchdog::init()
-{
- if (!mSuspectsAccessMutex && !mTimer)
- {
- mSuspectsAccessMutex = new LLMutex();
- mTimer = new LLWatchdogTimerThread();
- mTimer->setSleepTime(WATCHDOG_SLEEP_TIME_USEC / 1000);
- mLastClockCount = LLTimer::getTotalTime();
-
- // mTimer->start() kicks off the thread, any code after
- // start needs to use the mSuspectsAccessMutex
- mTimer->start();
- }
-}
-
-void LLWatchdog::cleanup()
-{
- if (mTimer)
- {
- mTimer->stop();
- delete mTimer;
- mTimer = nullptr;
- }
-
- if (mSuspectsAccessMutex)
- {
- delete mSuspectsAccessMutex;
- mSuspectsAccessMutex = nullptr;
- }
-
- mLastClockCount = 0;
-}
-
-void LLWatchdog::run()
-{
- lockThread();
-
- // Check the time since the last call to run...
- // If the time elapsed is two times greater than the regualr sleep time
- // reset the active timeouts.
- constexpr U32 TIME_ELAPSED_MULTIPLIER = 2;
- U64 current_time = LLTimer::getTotalTime();
- U64 current_run_delta = current_time - mLastClockCount;
- mLastClockCount = current_time;
-
- if (current_run_delta > (WATCHDOG_SLEEP_TIME_USEC * TIME_ELAPSED_MULTIPLIER))
- {
- LL_INFOS() << "Watchdog thread delayed: resetting entries." << LL_ENDL;
- for (const auto& suspect : mSuspects)
- {
- suspect->reset();
- }
- }
- else
- {
- SuspectsRegistry::iterator result =
- std::find_if(mSuspects.begin(),
- mSuspects.end(),
- [](const LLWatchdogEntry* suspect){ return ! suspect->isAlive(); });
- if (result != mSuspects.end())
- {
- // error!!!
- if(mTimer)
- {
- mTimer->stop();
- }
- if (LLAppViewer::instance()->logoutRequestSent())
- {
- LLAppViewer::instance()->createErrorMarker(LAST_EXEC_LOGOUT_FROZE);
- }
- else
- {
- LLAppViewer::instance()->createErrorMarker(LAST_EXEC_FROZE);
- }
- // Todo1: Warn user?
- // Todo2: We probably want to report even if 5 seconds passed, just not error 'yet'.
- // Todo3: This will report crash as 'llerror', consider adding 'watchdog' reason.
- std::string last_state = (*result)->getLastState();
- if (last_state.empty())
- {
- LL_ERRS() << "Watchdog timer for thread " << (*result)->getThreadName()
- << " expired; assuming viewer is hung and crashing" << LL_ENDL;
- }
- else
- {
- LL_ERRS() << "Watchdog timer for thread " << (*result)->getThreadName()
- << " expired with state: " << last_state
- << "; assuming viewer is hung and crashing" << LL_ENDL;
- }
- }
- }
-
-
- unlockThread();
-}
-
-void LLWatchdog::lockThread()
-{
- if (mSuspectsAccessMutex)
- {
- mSuspectsAccessMutex->lock();
- }
-}
-
-void LLWatchdog::unlockThread()
-{
- if (mSuspectsAccessMutex)
- {
- mSuspectsAccessMutex->unlock();
- }
-}
diff --git a/indra/newview/llwatchdog.h b/indra/newview/llwatchdog.h
deleted file mode 100644
index a8056f4337..0000000000
--- a/indra/newview/llwatchdog.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * @file llthreadwatchdog.h
- * @brief The LLThreadWatchdog class declaration
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLTHREADWATCHDOG_H
-#define LL_LLTHREADWATCHDOG_H
-
-#ifndef LL_TIMER_H
- #include "lltimer.h"
-#endif
-
-// LLWatchdogEntry is the interface used by the tasks that
-// need to be watched.
-class LLWatchdogEntry
-{
-public:
- LLWatchdogEntry(const std::string &thread_name);
- virtual ~LLWatchdogEntry();
-
- // isAlive is accessed by the watchdog thread.
- // This may mean that resources used by
- // isAlive and other method may need synchronization.
- virtual bool isAlive() const = 0;
- virtual void reset() = 0;
- virtual void start();
- virtual void stop();
- virtual std::string getLastState() const { return std::string(); }
- typedef std::thread::id id_t;
- std::string getThreadName() const;
-
-private:
- id_t mThreadID; // ID of the thread being watched
- std::string mThreadName;
-};
-
-class LLWatchdogTimeout : public LLWatchdogEntry
-{
-public:
- LLWatchdogTimeout(const std::string& thread_name);
- virtual ~LLWatchdogTimeout();
-
- bool isAlive() const override;
- void reset() override;
- void start() override { start(""); }
- void stop() override;
-
- void start(std::string_view state);
- void setTimeout(F32 d);
- void ping(std::string_view state);
- const std::string& getState() {return mPingState; }
- std::string getLastState() const override { return mPingState; }
-
-private:
- LLTimer mTimer;
- F32 mTimeout;
- std::string mPingState;
-};
-
-class LLWatchdogTimerThread; // Defined in the cpp
-class LLWatchdog : public LLSingleton<LLWatchdog>
-{
- LLSINGLETON(LLWatchdog);
- ~LLWatchdog();
-
-public:
- // Add an entry to the watchdog.
- void add(LLWatchdogEntry* e);
- void remove(LLWatchdogEntry* e);
-
- void init();
- void run();
- void cleanup();
-
-private:
- void lockThread();
- void unlockThread();
-
- typedef std::set<LLWatchdogEntry*> SuspectsRegistry;
- SuspectsRegistry mSuspects;
- LLMutex* mSuspectsAccessMutex;
- LLWatchdogTimerThread* mTimer;
- U64 mLastClockCount;
-};
-
-#endif // LL_LLTHREADWATCHDOG_H
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 0ac6cb8268..fe2f1ec1e3 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -2469,7 +2469,7 @@ You already have a landmark for this location.
icon="alert.tga"
name="LandmarkLocationUnknown"
type="alert">
-Viewer wasn't able to get region's location. Region might be temporarily unavailable or was removed.
+Viewer wasn't able to get region's location. Region might be temporarily unavailable, was removed or landmark failed to load.
<usetemplate
name="okbutton"
yestext="OK"/>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index a9e051f2e1..2b24fdcbe9 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -261,9 +261,10 @@ class ViewerManifest(LLManifest):
global CHANNEL_VENDOR_BASE
channel_type=self.channel_type()
if channel_type == 'release':
- return CHANNEL_VENDOR_BASE
+ app_suffix='Viewer'
else:
- return CHANNEL_VENDOR_BASE + ' ' + self.channel_variant()
+ app_suffix=self.channel_variant()
+ return CHANNEL_VENDOR_BASE + ' ' + app_suffix
def exec_name(self):
return "SecondLifeViewer"