From 0af07704bf76de8ca443abdbe0576fb22245d1bd Mon Sep 17 00:00:00 2001 From: Brad Linden <46733234+brad-linden@users.noreply.github.com> Date: Wed, 19 Feb 2025 14:37:21 -0800 Subject: [PATCH 1/4] Increment Viewer Version for 2025.03 (#3588) --- indra/newview/VIEWER_VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 0f9f025fe4..991d8e5c5f 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -7.1.12 +7.1.13 From 5db82e47aa24af721e95794390d54769910ec7fc Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Fri, 21 Feb 2025 16:13:00 +0200 Subject: [PATCH 2/4] #3572 fix for More/Less previews are being disabled in Shape editor --- indra/newview/llscrollingpanelparam.h | 1 - 1 file changed, 1 deletion(-) diff --git a/indra/newview/llscrollingpanelparam.h b/indra/newview/llscrollingpanelparam.h index 3aba4e4e40..93daf22e76 100644 --- a/indra/newview/llscrollingpanelparam.h +++ b/indra/newview/llscrollingpanelparam.h @@ -81,7 +81,6 @@ public: protected: LLTimer mMouseDownTimer; // timer for how long mouse has been held down on a hint. F32 mLastHeldTime; - bool mAllowModify; LLButton* mLessBtn; LLButton* mMoreBtn; From 1754aea5ff8f8a78f5a25e6652692eee7df4ff23 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 20 Feb 2025 23:47:21 +0200 Subject: [PATCH 3/4] #3547 Store and restore position when rebulding picks instead of re-requesting parcel data for a dozen parcels. Add request timeout in case parcel request hits throttle --- indra/newview/llavatarpropertiesprocessor.cpp | 1 + indra/newview/llpanelprofilepicks.cpp | 77 ++++++++++++++++++- indra/newview/llpanelprofilepicks.h | 7 +- 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp index 6277e65b2d..7dce627044 100644 --- a/indra/newview/llavatarpropertiesprocessor.cpp +++ b/indra/newview/llavatarpropertiesprocessor.cpp @@ -669,6 +669,7 @@ void LLAvatarPropertiesProcessor::sendClassifiedInfoUpdate(const LLAvatarClassif void LLAvatarPropertiesProcessor::sendPickInfoRequest(const LLUUID& creator_id, const LLUUID& pick_id) { + LL_DEBUGS("PickInfo") << " Requiesting pick info for " << pick_id << LL_ENDL; // Must ask for a pick based on the creator id because // the pick database is distributed to the inventory cluster. JC std::vector request_params{ creator_id.asString(), pick_id.asString() }; diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp index 08f3d3af5a..c2edc58687 100644 --- a/indra/newview/llpanelprofilepicks.cpp +++ b/indra/newview/llpanelprofilepicks.cpp @@ -55,6 +55,8 @@ static LLPanelInjector t_panel_profile_picks("panel_profile_picks"); static LLPanelInjector t_panel_profile_pick("panel_profile_pick"); +static const F32 REQUEST_TIMOUT = 60; +static const F32 LOCATION_CACHE_TIMOUT = 900; class LLPickHandler : public LLCommandHandler { @@ -306,6 +308,7 @@ void LLPanelProfilePicks::processProperties(void* data, EAvatarProcessorType typ void LLPanelProfilePicks::processProperties(const LLAvatarData* avatar_picks) { + LL_DEBUGS("PickInfo") << "Processing picks for avatar " << getAvatarId() << LL_ENDL; LLUUID selected_id = mPickToSelectOnLoad; bool has_selection = false; if (mPickToSelectOnLoad.isNull()) @@ -320,6 +323,25 @@ void LLPanelProfilePicks::processProperties(const LLAvatarData* avatar_picks) } } + // Avoid pointlesly requesting parcel data, + // store previous values + std::map parcelid_location_map; + std::map pickid_parcelid_map; + + for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx) + { + LLPanelProfilePick* pick_panel = dynamic_cast(mTabContainer->getPanelByIndex(tab_idx)); + if (pick_panel && pick_panel->getPickId().notNull()) + { + std::string location = pick_panel->getPickLocation(); + if (!location.empty()) + { + parcelid_location_map[pick_panel->getParcelID()] = pick_panel->getPickLocation(); + pickid_parcelid_map[pick_panel->getPickId()] = pick_panel->getParcelID(); + } + } + } + mTabContainer->deleteAllTabs(); LLAvatarData::picks_list_t::const_iterator it = avatar_picks->picks_list.begin(); @@ -334,6 +356,15 @@ void LLPanelProfilePicks::processProperties(const LLAvatarData* avatar_picks) pick_panel->setPickName(pick_name); pick_panel->setAvatarId(getAvatarId()); + std::map::const_iterator found_pick = pickid_parcelid_map.find(pick_id); + if (found_pick != pickid_parcelid_map.end()) + { + std::map::const_iterator found = parcelid_location_map.find(found_pick->second); + if (found != parcelid_location_map.end() && !found->second.empty()) + { + pick_panel->setPickLocation(found_pick->second, found->second); + } + } mTabContainer->addTabPanel( LLTabContainer::TabPanelParams(). panel(pick_panel). @@ -353,6 +384,11 @@ void LLPanelProfilePicks::processProperties(const LLAvatarData* avatar_picks) LLPanelProfilePick* pick_panel = LLPanelProfilePick::create(); pick_panel->setAvatarId(getAvatarId()); + std::map::const_iterator found = parcelid_location_map.find(data.parcel_id); + if (found != parcelid_location_map.end() && !found->second.empty()) + { + pick_panel->setPickLocation(data.parcel_id, found->second); + } pick_panel->processProperties(&data); mTabContainer->addTabPanel( LLTabContainer::TabPanelParams(). @@ -638,9 +674,14 @@ void LLPanelProfilePick::processProperties(void* data, EAvatarProcessorType type void LLPanelProfilePick::processProperties(const LLPickData* pick_info) { + LL_DEBUGS("PickInfo") << "Processing properties for pick " << mPickId << LL_ENDL; mIsEditing = false; mPickDescription->setParseHTML(true); - mParcelId = pick_info->parcel_id; + if (mParcelId != pick_info->parcel_id) + { + mParcelId = pick_info->parcel_id; + mPickLocationStr.clear(); + } setSnapshotId(pick_info->snapshot_id); if (!getSelfProfile()) { @@ -650,8 +691,11 @@ void LLPanelProfilePick::processProperties(const LLPickData* pick_info) setPickDesc(pick_info->desc); setPosGlobal(pick_info->pos_global); - // Send remote parcel info request to get parcel name and sim (region) name. - sendParcelInfoRequest(); + if (mPickLocationStr.empty() || mLastRequestTimer.getElapsedTimeF32() > LOCATION_CACHE_TIMOUT) + { + // Send remote parcel info request to get parcel name and sim (region) name. + sendParcelInfoRequest(); + } // *NOTE dzaporozhan // We want to keep listening to APT_PICK_INFO because user may @@ -691,9 +735,17 @@ void LLPanelProfilePick::setPickDesc(const std::string& desc) mPickDescription->setValue(desc); } +void LLPanelProfilePick::setPickLocation(const LLUUID &parcel_id, const std::string& location) +{ + setParcelID(parcel_id); // resets mPickLocationStr + setPickLocation(location); +} + void LLPanelProfilePick::setPickLocation(const std::string& location) { getChild("pick_location")->setValue(location); + mPickLocationStr = location; + mLastRequestTimer.reset(); } void LLPanelProfilePick::onClickMap() @@ -790,16 +842,19 @@ std::string LLPanelProfilePick::getLocationNotice() void LLPanelProfilePick::sendParcelInfoRequest() { - if (mParcelId != mRequestedId) + if (mParcelId != mRequestedId || mLastRequestTimer.getElapsedTimeF32() > REQUEST_TIMOUT) { if (mRequestedId.notNull()) { LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mRequestedId, this); } + LL_DEBUGS("PickInfo") << "Sending parcel request " << mParcelId << " for pick " << mPickId << LL_ENDL; LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this); LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId); mRequestedId = mParcelId; + mLastRequestTimer.reset(); + mPickLocationStr.clear(); } } @@ -816,6 +871,20 @@ void LLPanelProfilePick::processParcelInfo(const LLParcelData& parcel_data) } } +void LLPanelProfilePick::setParcelID(const LLUUID& parcel_id) +{ + if (mParcelId != parcel_id) + { + mParcelId = parcel_id; + mPickLocationStr.clear(); + } + if (mRequestedId.notNull() && mRequestedId != parcel_id) + { + LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mRequestedId, this); + mRequestedId.setNull(); + } +} + void LLPanelProfilePick::sendUpdate() { LLPickData pick_data; diff --git a/indra/newview/llpanelprofilepicks.h b/indra/newview/llpanelprofilepicks.h index e3f50f5576..b4d3eb010e 100644 --- a/indra/newview/llpanelprofilepicks.h +++ b/indra/newview/llpanelprofilepicks.h @@ -117,6 +117,8 @@ public: virtual void setPickName(const std::string& name); const std::string getPickName(); + virtual void setPickLocation(const LLUUID& parcel_id, const std::string& location); + std::string getPickLocation() { return mPickLocationStr; }; void processProperties(void* data, EAvatarProcessorType type) override; void processProperties(const LLPickData* pick_data); @@ -135,7 +137,8 @@ public: //This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing void processParcelInfo(const LLParcelData& parcel_data) override; - void setParcelID(const LLUUID& parcel_id) override { mParcelId = parcel_id; } + void setParcelID(const LLUUID& parcel_id) override; + LLUUID getParcelID() const { return mParcelId; } void setErrorStatus(S32 status, const std::string& reason) override {}; protected: @@ -230,6 +233,8 @@ protected: LLUUID mPickId; LLUUID mRequestedId; std::string mPickNameStr; + std::string mPickLocationStr; + LLTimer mLastRequestTimer; boost::signals2::connection mRegionCallbackConnection; boost::signals2::connection mParcelCallbackConnection; From 056dc00ebe07ba5994a51c7b4eb38d887d4b9355 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 24 Feb 2025 22:43:31 +0200 Subject: [PATCH 4/4] #3591 More test coverage for crashes --- indra/newview/llappviewer.cpp | 21 ++++++++++++ indra/newview/llappviewer.h | 2 ++ indra/newview/llviewermenu.cpp | 32 +++++++++++++++++++ .../skins/default/xui/en/menu_viewer.xml | 14 +++++++- 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 6d10d3413b..973cdd53a0 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -5611,6 +5611,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 diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index b4756eecd6..542379c828 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -175,6 +175,8 @@ public: virtual void forceErrorOSSpecificException(); virtual void forceErrorDriverCrash(); virtual void forceErrorCoroutineCrash(); + virtual void forceErrorCoroprocedureCrash(); + virtual void forceErrorWorkQueueCrash(); virtual void forceErrorThreadCrash(); // The list is found in app_settings/settings_files.xml diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index d92faf4d1b..6281ac1f9e 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -286,6 +286,8 @@ void force_error_software_exception(); void force_error_os_exception(); void force_error_driver_crash(); void force_error_coroutine_crash(); +void force_error_coroprocedure_crash(); +void force_error_work_queue_crash(); void force_error_thread_crash(); void handle_force_delete(); @@ -2634,6 +2636,24 @@ class LLAdvancedForceErrorCoroutineCrash : public view_listener_t } }; +class LLAdvancedForceErrorCoroprocedureCrash : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + force_error_coroprocedure_crash(); + return true; + } +}; + +class LLAdvancedForceErrorWorkQueueCrash : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + force_error_work_queue_crash(); + return true; + } +}; + class LLAdvancedForceErrorThreadCrash : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -8657,6 +8677,16 @@ void force_error_coroutine_crash() LLAppViewer::instance()->forceErrorCoroutineCrash(); } +void force_error_coroprocedure_crash() +{ + LLAppViewer::instance()->forceErrorCoroprocedureCrash(); +} + +void force_error_work_queue_crash() +{ + LLAppViewer::instance()->forceErrorWorkQueueCrash(); +} + void force_error_thread_crash() { LLAppViewer::instance()->forceErrorThreadCrash(); @@ -9861,6 +9891,8 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareExceptionCoro(), "Advanced.ForceErrorSoftwareExceptionCoro"); view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash"); view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash"); + view_listener_t::addMenu(new LLAdvancedForceErrorCoroprocedureCrash(), "Advanced.ForceErrorCoroprocedureCrash"); + view_listener_t::addMenu(new LLAdvancedForceErrorWorkQueueCrash(), "Advanced.ForceErrorWorkQueueCrash"); view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash"); view_listener_t::addMenu(new LLAdvancedForceErrorDisconnectViewer(), "Advanced.ForceErrorDisconnectViewer"); diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 0e70e75c0b..349c8d0e20 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2788,13 +2788,25 @@ function="World.EnvPreset" function="Advanced.ForceErrorOSException" /> - + + + + + + +