FIRE-30667 - Address problems highlighted by excessive group notices

The problem itself will be fixed server side these fixes improve general case behaviour and possibly OpenSim
master
Beq 2021-01-28 18:05:49 +00:00
parent c874f17765
commit 68d5be3856
8 changed files with 87 additions and 13 deletions

2
.gitignore vendored
View File

@ -106,3 +106,5 @@ my_autobuild.xml
*.srctrlprj *.srctrlprj
compile_commands.json compile_commands.json
# ignore tracy for now
indra/tracy

View File

@ -2915,10 +2915,20 @@ void LLScrollListCtrl::sortByColumnIndex(U32 column, BOOL ascending)
updateSort(); updateSort();
} }
// <FS:Beq/> FIRE-30667 et al. Group hang issues (grab settings)
extern LLControlGroup gSavedSettings;
void LLScrollListCtrl::updateSort() const void LLScrollListCtrl::updateSort() const
{ {
if (hasSortOrder() && !isSorted()) // <FS:Beq> FIRE-30667 et al. Group hang issues
// if (hasSortOrder() && !isSorted())
// {
static LLCachedControl<U32> sortDeferFrameCount( gSavedSettings, "FSSortDeferalFrames" );
if ( hasSortOrder() && !isSorted() && ( mLastUpdateFrame > 1 && ( LLFrameTimer::getFrameCount() - mLastUpdateFrame ) >= sortDeferFrameCount ) )
// encoding two (unlikely) special values into mLastUpdateFrame 1 means we've sorted and 0 means we've nothing new to do.
// 0 is set after sorting, 1 can be set by a parent for any post sorting action.
{ {
mLastUpdateFrame=0;
// </FS:Beq>
// do stable sort to preserve any previous sorts // do stable sort to preserve any previous sorts
std::stable_sort( std::stable_sort(
mItemList.begin(), mItemList.begin(),

View File

@ -412,7 +412,9 @@ public:
void sortOnce(S32 column, BOOL ascending); void sortOnce(S32 column, BOOL ascending);
// manually call this whenever editing list items in place to flag need for resorting // manually call this whenever editing list items in place to flag need for resorting
void setNeedsSort(bool val = true) { mSorted = !val; } // <FS:Beq/> FIRE-30667 et al. Avoid hangs on large list updates
// void setNeedsSort(bool val = true) { mSorted = !val; }
void setNeedsSort(bool val = true) { mSorted = !val; mLastUpdateFrame = LLFrameTimer::getFrameCount(); }
void dirtyColumns(); // some operation has potentially affected column layout or ordering void dirtyColumns(); // some operation has potentially affected column layout or ordering
boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb ) boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb )
@ -452,6 +454,8 @@ protected:
public: public:
void updateLineHeight(); void updateLineHeight();
// <FS:Beq/> FIRE-30667 et al. Avoid hangs on large list updates
mutable U32 mLastUpdateFrame;
private: private:
void selectPrevItem(BOOL extend_selection); void selectPrevItem(BOOL extend_selection);
@ -478,6 +482,7 @@ private:
static void copyNameToClipboard(std::string id, bool is_group); static void copyNameToClipboard(std::string id, bool is_group);
static void copySLURLToClipboard(std::string id, bool is_group); static void copySLURLToClipboard(std::string id, bool is_group);
S32 mLineHeight; // the max height of a single line S32 mLineHeight; // the max height of a single line
S32 mScrollLines; // how many lines we've scrolled down S32 mScrollLines; // how many lines we've scrolled down
S32 mPageLines; // max number of lines is it possible to see on the screen given mRect and mLineHeight S32 mPageLines; // max number of lines is it possible to see on the screen given mRect and mLineHeight

View File

@ -344,6 +344,17 @@
<key>Value</key> <key>Value</key>
<integer>0</integer> <integer>0</integer>
</map> </map>
<key>FSSortDeferalFrames</key>
<map>
<key>Comment</key>
<string>How many frames after an update should we wait before sorting</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>2</integer>
</map>
<key>FSGroupNotifyNoTransparency</key> <key>FSGroupNotifyNoTransparency</key>
<map> <map>
<key>Comment</key> <key>Comment</key>

View File

@ -6137,6 +6137,7 @@ void LLAppViewer::idleNameCache()
#ifdef TIME_THROTTLE_MESSAGES #ifdef TIME_THROTTLE_MESSAGES
#define CHECK_MESSAGES_DEFAULT_MAX_TIME .020f // 50 ms = 50 fps (just for messages!) #define CHECK_MESSAGES_DEFAULT_MAX_TIME .020f // 50 ms = 50 fps (just for messages!)
#define CHECK_MESSAGES_MAX_TIME_LIMIT 1.0f // 1 second, a long time but still able to stay connected
static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
#endif #endif
@ -6202,11 +6203,24 @@ void LLAppViewer::idleNetwork()
#ifdef TIME_THROTTLE_MESSAGES #ifdef TIME_THROTTLE_MESSAGES
if (total_time >= CheckMessagesMaxTime) if (total_time >= CheckMessagesMaxTime)
{ {
// Increase CheckMessagesMaxTime so that we will eventually catch up // <FS:Beq> Don't allow busy network to excessively starve rendering loop
CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames // // Increase CheckMessagesMaxTime so that we will eventually catch up
// CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames
// }
// else
// {
if( CheckMessagesMaxTime < CHECK_MESSAGES_MAX_TIME_LIMIT ) // cap the increase to avoid logout through ping starvation
{// Increase CheckMessagesMaxTime so that we will eventually catch up
CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames
}
else
{
CheckMessagesMaxTime = CHECK_MESSAGES_MAX_TIME_LIMIT;
}
} }
else else
{ {
// </FS:Beq>
// Reset CheckMessagesMaxTime to default value // Reset CheckMessagesMaxTime to default value
CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
} }

View File

@ -667,6 +667,13 @@ void LLPanelGroup::draw()
{ {
LLPanel::draw(); LLPanel::draw();
// <FS:Beq> FIRE-30667 - group hang fixes
LLPanelGroupNotices* panel_notices = findChild<LLPanelGroupNotices>("group_notices_tab_panel");
if(panel_notices)
{
panel_notices->updateSelected();
}
// </FS:Beq>
if (mRefreshTimer.hasExpired()) if (mRefreshTimer.hasExpired())
{ {
mRefreshTimer.stop(); mRefreshTimer.stop();

View File

@ -473,6 +473,8 @@ void LLPanelGroupNotices::clearNoticeList()
{ {
mPrevSelectedNotice = mNoticesList->getStringUUIDSelectedItem(); mPrevSelectedNotice = mNoticesList->getStringUUIDSelectedItem();
mNoticesList->deleteAllItems(); mNoticesList->deleteAllItems();
// <FS:Beq/> FIRE-30766 group hang prevention.
mNoticeIDs.clear();
} }
void LLPanelGroupNotices::onClickRefreshNotices(void* data) void LLPanelGroupNotices::onClickRefreshNotices(void* data)
@ -536,7 +538,8 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)
//save sort state and set unsorted state to prevent unnecessary //save sort state and set unsorted state to prevent unnecessary
//sorting while adding notices //sorting while adding notices
bool save_sort = mNoticesList->isSorted(); // <FS:Beq> FIRE-30667 et al. we will need sorting at the end
// bool save_sort = mNoticesList->isSorted();
mNoticesList->setNeedsSort(false); mNoticesList->setNeedsSort(false);
for (;i<count;++i) for (;i<count;++i)
@ -552,9 +555,12 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)
//with some network delays we can receive notice list more then once... //with some network delays we can receive notice list more then once...
//so add only unique notices //so add only unique notices
S32 pos = mNoticesList->getItemIndex(id); // <FS:Beq> FIRE-30667 et al. add a set for tracking to avoid the linear time lookup
// S32 pos = mNoticesList->getItemIndex(id);
if(pos!=-1)//if items with this ID already in the list - skip it // if(pos!=-1)//if items with this ID already in the list - skip it
auto exists = mNoticeIDs.emplace(id);
if (!exists.second)
// </FS:Beq>
continue; continue;
msg->getString("Data","Subject",subj,i); msg->getString("Data","Subject",subj,i);
@ -596,15 +602,32 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)
mNoticesList->addElement(row, ADD_BOTTOM); mNoticesList->addElement(row, ADD_BOTTOM);
} }
mNoticesList->setNeedsSort(save_sort); mNoticesList->setNeedsSort(true);
mNoticesList->updateSort(); // <FS:Beq> FIRE-30667 et al. defer sorting and updating selection
if (mPanelViewNotice->getVisible()) // mNoticesList->updateSort();
// if (mPanelViewNotice->getVisible())
// {
// if (!mNoticesList->selectByID(mPrevSelectedNotice))
// {
// mNoticesList->selectFirstItem();
// }
// }
}
void LLPanelGroupNotices::updateSelected()
{
if( mNoticesList->mLastUpdateFrame == 0 )
{ {
if (!mNoticesList->selectByID(mPrevSelectedNotice)) if (mPanelViewNotice->getVisible())
{ {
mNoticesList->selectFirstItem(); if (!mNoticesList->selectByID(mPrevSelectedNotice))
{
mNoticesList->selectFirstItem();
}
} }
mNoticesList->mLastUpdateFrame = 1;
} }
// </FS:Beq>
} }
void LLPanelGroupNotices::onSelectNotice(LLUICtrl* ctrl, void* data) void LLPanelGroupNotices::onSelectNotice(LLUICtrl* ctrl, void* data)

View File

@ -64,6 +64,7 @@ public:
LLOfferInfo* inventory_offer); LLOfferInfo* inventory_offer);
void refreshNotices(); void refreshNotices();
void updateSelected(); // FS:Beq FIRE-30667 group notices hang
void clearNoticeList(); void clearNoticeList();
@ -111,6 +112,7 @@ private:
//LLIconCtrl *mViewInventoryIcon; //LLIconCtrl *mViewInventoryIcon;
LLScrollListCtrl *mNoticesList; LLScrollListCtrl *mNoticesList;
std::set<LLUUID> mNoticeIDs; // FS:Beq FIRE-30667 group notices hang
std::string mNoNoticesStr; std::string mNoNoticesStr;