Merge branch 'DRTVWR-516-maint' of https://bitbucket.org/lindenlab/viewer

master
Ansariel 2021-04-02 19:33:18 +02:00
commit db72dc7d0f
26 changed files with 278 additions and 130 deletions

View File

@ -2405,18 +2405,18 @@
<key>archive</key>
<map>
<key>hash</key>
<string>c541838a933e0714a954e9ef6c89345d</string>
<string>0a6349b11c8e9d34f0c80b8081736e75</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/73387/708088/llca-202012011600.553112-common-553112.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/79438/751815/llca-202104010215.557744-common-557744.tar.bz2</string>
</map>
<key>name</key>
<string>common</string>
</map>
</map>
<key>version</key>
<string>202012011600.553112</string>
<string>202104010215.557744</string>
</map>
<key>llphysicsextensions_source</key>
<map>

View File

@ -265,10 +265,11 @@ Benja Kepler
Benjamin Bigdipper
Beq Janus
BUG-227094
Beth Walcher
Beq Janus
SL-10288
SL-13583
SL-14766
SL-14927
Beth Walcher
Bezilon Kasei
Biancaluce Robbiani
CT-225

View File

@ -259,6 +259,10 @@ public:
*/
LLRunner& getRunner() { return mRunner; }
#ifdef LL_WINDOWS
virtual void reportCrashToBugsplat(void* pExcepInfo /*EXCEPTION_POINTERS*/) { }
#endif
public:
typedef std::map<std::string, std::string> string_map;
string_map mOptionMap; // Contains all command-line options and arguments in a map

View File

@ -254,8 +254,21 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop, const std::string& name)
{
// C++ exceptions were logged in toplevelTryWrapper, but not SEH
// log SEH exceptions here, to make sure it gets into bugsplat's
// report and because __try won't allow std::string operations
if (code != STATUS_MSC_EXCEPTION)
{
LL_WARNS() << "SEH crash in " << name << ", code: " << code << LL_ENDL;
}
// Handle bugsplat here, since GetExceptionInformation() can only be
// called from within filter for __except(filter), not from __except's {}
// Bugsplat should get all exceptions, C++ and SEH
LLApp::instance()->reportCrashToBugsplat(exception_infop);
// Only convert non C++ exceptions.
if (code == STATUS_MSC_EXCEPTION)
{
// C++ exception, go on
@ -268,29 +281,29 @@ U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
}
}
void LLCoros::winlevel(const callable_t& callable)
void LLCoros::winlevel(const std::string& name, const callable_t& callable)
{
__try
{
callable();
toplevelTryWrapper(name, callable);
}
__except (exception_filter(GetExceptionCode(), GetExceptionInformation()))
__except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name))
{
// convert to C++ styled exception
// convert to C++ styled exception for handlers other than bugsplat
// Note: it might be better to use _se_set_translator
// if you want exception to inherit full callstack
char integer_string[32];
sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
//
// in case of bugsplat this will get to exceptionTerminateHandler and
// looks like fiber will terminate application after that
char integer_string[512];
sprintf(integer_string, "SEH crash in %s, code: %lu\n", name.c_str(), GetExceptionCode());
throw std::exception(integer_string);
}
}
#endif
// Top-level wrapper around caller's coroutine callable.
// Normally we like to pass strings and such by const reference -- but in this
// case, we WANT to copy both the name and the callable to our local stack!
void LLCoros::toplevel(std::string name, callable_t callable)
void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable)
{
// keep the CoroData on this top-level function's stack frame
CoroData corodata(name);
@ -300,18 +313,12 @@ void LLCoros::toplevel(std::string name, callable_t callable)
// run the code the caller actually wants in the coroutine
try
{
// <FS:Ansariel> Disable for more meaningful callstacks
//#if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD
// winlevel(callable);
//#else
callable();
//#endif
// <FS:Ansariel> Disable for more meaningful callstacks
}
catch (const Stop& exc)
{
LL_INFOS("LLCoros") << "coroutine " << name << " terminating because "
<< exc.what() << LL_ENDL;
<< exc.what() << LL_ENDL;
}
catch (const LLContinueError&)
{
@ -324,10 +331,25 @@ void LLCoros::toplevel(std::string name, callable_t callable)
{
// Any OTHER kind of uncaught exception will cause the viewer to
// crash, hopefully informatively.
CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
// to not modify callstack
throw;
}
}
// Top-level wrapper around caller's coroutine callable.
// Normally we like to pass strings and such by const reference -- but in this
// case, we WANT to copy both the name and the callable to our local stack!
void LLCoros::toplevel(std::string name, callable_t callable)
{
#if LL_WINDOWS
// Can not use __try in functions that require unwinding, so use one more wrapper
winlevel(name, callable);
#else
toplevelTryWrapper(name, callable);
#endif
}
//static
void LLCoros::checkStop()
{

View File

@ -290,11 +290,12 @@ public:
private:
std::string generateDistinctName(const std::string& prefix) const;
#if LL_WINDOWS
void winlevel(const std::string& name, const callable_t& callable);
#endif
void toplevelTryWrapper(const std::string& name, const callable_t& callable);
void toplevel(std::string name, callable_t callable);
struct CoroData;
#if LL_WINDOWS
static void winlevel(const callable_t& callable);
#endif
static CoroData& get_CoroData(const std::string& caller);
S32 mStackSize;

View File

@ -1723,7 +1723,7 @@ void LLFolderViewFolder::destroyView()
// extractItem() removes the specified item from the folder, but
// doesn't delete it.
void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
void LLFolderViewFolder::extractItem( LLFolderViewItem* item, bool deparent_model )
{
if (item->isSelected())
getRoot()->clearSelection();
@ -1746,7 +1746,11 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
mItems.erase(it);
}
//item has been removed, need to update filter
getViewModelItem()->removeChild(item->getViewModelItem());
if (deparent_model)
{
// in some cases model does not belong to parent view, is shared between views
getViewModelItem()->removeChild(item->getViewModelItem());
}
//because an item is going away regardless of filter status, force rearrange
requestArrange();
removeChild(item);

View File

@ -402,7 +402,7 @@ public:
// extractItem() removes the specified item from the folder, but
// doesn't delete it.
virtual void extractItem( LLFolderViewItem* item );
virtual void extractItem( LLFolderViewItem* item, bool deparent_model = true);
// This function is called by a child that needs to be resorted.
void resort(LLFolderViewItem* item);

View File

@ -1039,25 +1039,14 @@ boost::signals2::connection LLAgent::addParcelChangedCallback(parcel_changed_cal
}
// static
// <FS:Beq> FIRE-30774 displayname capability is targetting previous region
// void LLAgent::capabilityReceivedCallback(const LLUUID &region_id)
// {
// LLViewerRegion* region = gAgent.getRegion();
// if (region && region->getRegionID() == region_id)
// {
// region->requestSimulatorFeatures();
// LLAppViewer::instance()->updateNameLookupUrl();
// }
// }
void LLAgent::capabilityReceivedCallback(LLViewerRegion* regionp)
void LLAgent::capabilityReceivedCallback(const LLUUID &region_id, LLViewerRegion *regionp)
{
if (regionp)
if (regionp && regionp->getRegionID() == region_id)
{
regionp->requestSimulatorFeatures();
LLAppViewer::instance()->updateNameLookupUrl(regionp);
}
}
// </FS:Beq>
//-----------------------------------------------------------------------------
// setRegion()
@ -1109,17 +1098,11 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
if (regionp->capabilitiesReceived())
{
regionp->requestSimulatorFeatures();
// <FS:Beq> FIRE-30774 displayname capability is targetting previous region
// LLAppViewer::instance()->updateNameLookupUrl();
LLAppViewer::instance()->updateNameLookupUrl(regionp);
// </FS:Beq>
}
else
{
// <FS:Beq> FIRE-30774 displayname capability is targetting previous region
// regionp->setCapabilitiesReceivedCallback(LLAgent::capabilityReceivedCallback);
regionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::capabilityReceivedCallback, regionp));
// </FS:Beq>
regionp->setCapabilitiesReceivedCallback(LLAgent::capabilityReceivedCallback);
}
}
@ -1141,17 +1124,11 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
if (regionp->capabilitiesReceived())
{
// <FS:Beq> FIRE-30774 displayname capability is targetting previous region
// LLAppViewer::instance()->updateNameLookupUrl();
LLAppViewer::instance()->updateNameLookupUrl(regionp);
// </FS:Beq>
}
else
{
// <FS:Beq> FIRE-30774 displayname capability is targetting previous region
// regionp->setCapabilitiesReceivedCallback([regionp](const LLUUID &region_id) {LLAppViewer::instance()->updateNameLookupUrl(); });
regionp->setCapabilitiesReceivedCallback([regionp](const LLUUID &region_id) { LLAppViewer::instance()->updateNameLookupUrl(regionp); });
// </FS:Beq>
regionp->setCapabilitiesReceivedCallback([](const LLUUID &region_id, LLViewerRegion* regionp) {LLAppViewer::instance()->updateNameLookupUrl(regionp); });
}
}

View File

@ -258,10 +258,7 @@ public:
boost::signals2::connection addParcelChangedCallback(parcel_changed_callback_t);
private:
// <FS:Beq> FIRE-30774 displayname capability is targetting previous region
// static void capabilityReceivedCallback(const LLUUID &region_id);
static void capabilityReceivedCallback(LLViewerRegion* regionp);
// </FS:Beq>
static void capabilityReceivedCallback(const LLUUID &region_id, LLViewerRegion *regionp);
typedef boost::signals2::signal<void()> parcel_changed_signal_t;
parcel_changed_signal_t mParcelChangedSignal;

View File

@ -6042,13 +6042,9 @@ void LLAppViewer::sendLogoutRequest()
}
}
// <FS:Beq> FIRE-30774 displayname capability is targetting previous region
// void LLAppViewer::updateNameLookupUrl()
void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * region)
// </FS:Beq>
void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * regionp)
{
// LLViewerRegion* region = gAgent.getRegion(); <FS:Beq/>
if (!region || !region->capabilitiesReceived())
if (!regionp || !regionp->capabilitiesReceived())
{
return;
}
@ -6057,7 +6053,7 @@ void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * region)
bool had_capability = name_cache->hasNameLookupURL();
std::string name_lookup_url;
name_lookup_url.reserve(128); // avoid a memory allocation below
name_lookup_url = region->getCapability("GetDisplayNames");
name_lookup_url = regionp->getCapability("GetDisplayNames");
bool have_capability = !name_lookup_url.empty();
if (have_capability)
{
@ -6405,6 +6401,33 @@ void LLAppViewer::forceErrorDriverCrash()
glDeleteTextures(1, NULL);
}
void LLAppViewer::forceErrorCoroutineCrash()
{
LL_WARNS() << "Forcing a crash in LLCoros" << LL_ENDL;
LLCoros::instance().launch("LLAppViewer::crashyCoro", [] {throw LLException("A deliberate crash from LLCoros"); });
}
void LLAppViewer::forceErrorThreadCrash()
{
class LLCrashTestThread : public LLThread
{
public:
LLCrashTestThread() : LLThread("Crash logging test thread")
{
}
void run()
{
LL_ERRS() << "This is a deliberate llerror in thread" << LL_ENDL;
}
};
LL_WARNS() << "This is a deliberate crash in a thread" << LL_ENDL;
LLCrashTestThread *thread = new LLCrashTestThread();
thread->start();
}
// <FS:ND> Change from std::string to char const*, saving a lot of object construction/destruction per frame
//void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs)
void LLAppViewer::initMainloopTimeout( char const* state, F32 secs)

View File

@ -58,7 +58,7 @@ class LLImageDecodeThread;
class LLTextureFetch;
class LLWatchdogTimeout;
class LLViewerJoystick;
class LLViewerRegion; // <FS:Beq/>
class LLViewerRegion;
extern LLTrace::BlockTimerStatHandle FTM_FRAME;
@ -149,6 +149,8 @@ public:
virtual void forceErrorInfiniteLoop();
virtual void forceErrorSoftwareException();
virtual void forceErrorDriverCrash();
virtual void forceErrorCoroutineCrash();
virtual void forceErrorThreadCrash();
// The list is found in app_settings/settings_files.xml
// but since they are used explicitly in code,
@ -223,10 +225,7 @@ public:
// llcorehttp init/shutdown/config information.
LLAppCoreHttp & getAppCoreHttp() { return mAppCoreHttp; }
// <FS:Beq> FIRE-30774 displayname capability is targetting previous region
// void updateNameLookupUrl();
void updateNameLookupUrl( const LLViewerRegion * region );
// </FS:Beq>
void updateNameLookupUrl(const LLViewerRegion* regionp);
protected:
virtual bool initWindow(); // Initialize the viewer's window.

View File

@ -784,6 +784,13 @@ bool LLAppViewerWin32::init()
#else // LL_BUGSPLAT
#pragma message("Building with BugSplat")
// <FS:ND> Pre BugSplat dance, make sure settings are valid, query crash behavior and then set up Bugsplat accordingly"
//if (!isSecondInstance())
//{
// // Cleanup previous session
// std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log");
// LLFile::remove(log_file, ENOENT);
//}
success = LLAppViewer::init();
if (!success)
return false;
@ -812,7 +819,7 @@ bool LLAppViewerWin32::init()
llifstream inf(build_data_fname.c_str());
if (! inf.is_open())
{
LL_WARNS() << "Can't initialize BugSplat, can't read '" << build_data_fname
LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't read '" << build_data_fname
<< "'" << LL_ENDL;
}
else
@ -822,7 +829,7 @@ bool LLAppViewerWin32::init()
if (! reader.parse(inf, build_data, false)) // don't collect comments
{
// gah, the typo is baked into Json::Reader API
LL_WARNS() << "Can't initialize BugSplat, can't parse '" << build_data_fname
LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't parse '" << build_data_fname
<< "': " << reader.getFormatedErrorMessages() << LL_ENDL;
}
else
@ -830,7 +837,7 @@ bool LLAppViewerWin32::init()
Json::Value BugSplat_DB = build_data["BugSplat DB"];
if (! BugSplat_DB)
{
LL_WARNS() << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"
LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"
<< build_data_fname << "'" << LL_ENDL;
}
else
@ -841,31 +848,40 @@ bool LLAppViewerWin32::init()
LL_VIEWER_VERSION_PATCH << '.' <<
LL_VIEWER_VERSION_BUILD));
// have to convert normal wide strings to strings of __wchar_t
// <FS:ND> Set up Bugsplat to ask or always send
//DWORD dwFlags = MDSF_NONINTERACTIVE | // automatically submit report without prompting
// MDSF_PREVENTHIJACKING; // disallow swiping Exception filter
DWORD dwFlags = dwAsk |
MDSF_PREVENTHIJACKING; // disallow swiping Exception filter
// </FS:ND>
// sBugSplatSender = new MiniDmpSender(
// WCSTR(BugSplat_DB.asString()),
// WCSTR(LL_TO_WSTRING(LL_VIEWER_CHANNEL)),
// WCSTR(version_string),
// nullptr, // szAppIdentifier -- set later
// MDSF_NONINTERACTIVE | // automatically submit report without prompting
// MDSF_PREVENTHIJACKING); // disallow swiping Exception filter
//bool needs_log_file = !isSecondInstance() && debugLoggingEnabled("BUGSPLAT");
//if (needs_log_file)
//{
// // Startup only!
// LL_INFOS("BUGSPLAT") << "Engaged BugSplat logging to bugsplat.log" << LL_ENDL;
// dwFlags |= MDSF_LOGFILE | MDSF_LOG_VERBOSE;
//}
// have to convert normal wide strings to strings of __wchar_t
sBugSplatSender = new MiniDmpSender(
WCSTR(BugSplat_DB.asString()),
WCSTR(LL_TO_WSTRING(LL_VIEWER_CHANNEL)),
WCSTR(version_string),
nullptr, // szAppIdentifier -- set later
dwAsk |
MDSF_PREVENTHIJACKING); // disallow swiping Exception filter
// </FS:ND>
dwFlags);
sBugSplatSender->setCallback(bugsplatSendLog);
//if (needs_log_file)
//{
// // Log file will be created in %TEMP%, but it will be moved into logs folder in case of crash
// std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log");
// sBugSplatSender->setLogFilePath(WCSTR(log_file));
//}
// engage stringize() overload that converts from wstring
LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
LL_INFOS("BUGSPLAT") << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
<< ' ' << stringize(version_string) << ')' << LL_ENDL;
} // got BugSplat_DB
} // parsed build_data.json
@ -899,6 +915,16 @@ bool LLAppViewerWin32::cleanup()
return result;
}
void LLAppViewerWin32::reportCrashToBugsplat(void* pExcepInfo)
{
#if defined(LL_BUGSPLAT)
if (sBugSplatSender)
{
sBugSplatSender->createReport((EXCEPTION_POINTERS*)pExcepInfo);
}
#endif // LL_BUGSPLAT
}
void LLAppViewerWin32::initLoggingAndGetLastDuration()
{
LLAppViewer::initLoggingAndGetLastDuration();

View File

@ -40,20 +40,22 @@ public:
//
// Main application logic
//
virtual bool init(); // Override to do application initialization
virtual bool cleanup();
bool init() override; // Override to do application initialization
bool cleanup() override;
void reportCrashToBugsplat(void* pExcepInfo) override;
protected:
virtual void initLoggingAndGetLastDuration(); // Override to clean stack_trace info.
virtual void initConsole(); // Initialize OS level debugging console.
virtual bool initHardwareTest(); // Win32 uses DX9 to test hardware.
virtual bool initParseCommandLine(LLCommandLineParser& clp);
void initLoggingAndGetLastDuration() override; // Override to clean stack_trace info.
void initConsole() override; // Initialize OS level debugging console.
bool initHardwareTest() override; // Win32 uses DX9 to test hardware.
bool initParseCommandLine(LLCommandLineParser& clp) override;
virtual bool beingDebugged();
virtual bool restoreErrorTrap();
virtual void initCrashReporting(bool reportFreeze);
bool beingDebugged() override;
bool restoreErrorTrap() override;
void initCrashReporting(bool reportFreeze) override;
virtual bool sendURLToOtherInstance(const std::string& url);
bool sendURLToOtherInstance(const std::string& url) override;
std::string generateSerialNumber();

View File

@ -357,7 +357,7 @@ LLConversationItemParticipant* LLConversationItemSession::findParticipant(const
for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
{
participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
if (participant->hasSameValue(participant_id))
if (participant && participant->hasSameValue(participant_id))
{
break;
}
@ -468,7 +468,7 @@ const bool LLConversationItemSession::getTime(F64& time) const
{
participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
F64 participant_time;
if (participant->getTime(participant_time))
if (participant && participant->getTime(participant_time))
{
has_time = true;
most_recent_time = llmax(most_recent_time,participant_time);

View File

@ -619,10 +619,13 @@ void LLConversationViewParticipant::refresh()
{
// Refresh the participant view from its model data
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
participant_model->resetRefresh();
// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted());
if (participant_model)
{
participant_model->resetRefresh();
// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted());
}
// Do the regular upstream refresh
LLFolderViewItem::refresh();

View File

@ -1110,7 +1110,7 @@ void LLEnvironment::onRegionChange()
}
if (!cur_region->capabilitiesReceived())
{
cur_region->setCapabilitiesReceivedCallback([](const LLUUID &region_id) { LLEnvironment::instance().requestRegion(); });
cur_region->setCapabilitiesReceivedCallback([](const LLUUID &region_id, LLViewerRegion* regionp) { LLEnvironment::instance().requestRegion(); });
return;
}
requestRegion();

View File

@ -63,7 +63,9 @@
#include "boost/foreach.hpp"
const S32 EVENTS_PER_IDLE_LOOP = 100;
const S32 EVENTS_PER_IDLE_LOOP_CURRENT_SESSION = 80;
const S32 EVENTS_PER_IDLE_LOOP_BACKGROUND = 40;
const F32 EVENTS_PER_IDLE_LOOP_MIN_PERCENTAGE = 0.01f; // process a minimum of 1% of total events per frame
//
// LLFloaterIMContainer
@ -420,8 +422,11 @@ void LLFloaterIMContainer::processParticipantsStyleUpdate()
while (current_participant_model != end_participant_model)
{
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
// Get the avatar name for this participant id from the cache and update the model
participant_model->updateName();
if (participant_model)
{
// Get the avatar name for this participant id from the cache and update the model
participant_model->updateName();
}
// Next participant
current_participant_model++;
}
@ -468,8 +473,11 @@ void LLFloaterIMContainer::idleUpdate()
while (current_participant_model != end_participant_model)
{
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
participant_model->setModeratorOptionsVisible(is_moderator);
participant_model->setGroupBanVisible(can_ban && participant_model->getUUID() != gAgentID);
if (participant_model)
{
participant_model->setModeratorOptionsVisible(is_moderator);
participant_model->setGroupBanVisible(can_ban && participant_model->getUUID() != gAgentID);
}
current_participant_model++;
}
@ -502,20 +510,49 @@ void LLFloaterIMContainer::idleUpdate()
void LLFloaterIMContainer::idleProcessEvents()
{
if (!mConversationEventQueue.empty())
{
S32 events_to_handle = llmin((S32)mConversationEventQueue.size(), EVENTS_PER_IDLE_LOOP);
for (S32 i = 0; i < events_to_handle; i++)
{
handleConversationModelEvent(mConversationEventQueue.back());
mConversationEventQueue.pop_back();
}
}
LLUUID current_session_id = getSelectedSession();
conversations_items_deque::iterator iter = mConversationEventQueue.begin();
conversations_items_deque::iterator end = mConversationEventQueue.end();
while (iter != end)
{
std::deque<LLSD> &events = iter->second;
if (!events.empty())
{
S32 events_to_handle;
S32 query_size = (S32)events.size();
if (current_session_id == iter->first)
{
events_to_handle = EVENTS_PER_IDLE_LOOP_CURRENT_SESSION;
}
else
{
events_to_handle = EVENTS_PER_IDLE_LOOP_BACKGROUND;
}
if (events_to_handle <= query_size)
{
// Some groups can be very large and can generate huge amount of updates, scale processing up to keep up
events_to_handle = llmax(events_to_handle, (S32)(query_size * EVENTS_PER_IDLE_LOOP_MIN_PERCENTAGE));
}
else
{
events_to_handle = query_size;
}
for (S32 i = 0; i < events_to_handle; i++)
{
handleConversationModelEvent(events.back());
events.pop_back();
}
}
iter++;
}
}
bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
{
mConversationEventQueue.push_front(event);
LLUUID id = event.get("session_uuid").asUUID();
mConversationEventQueue[id].push_front(event);
return true;
}
@ -1835,6 +1872,8 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
// Suppress the conversation items and widgets from their respective maps
mConversationsItems.erase(uuid);
mConversationsWidgets.erase(uuid);
// Clear event query (otherwise reopening session in some way can bombard session with stale data)
mConversationEventQueue.erase(uuid);
// Don't let the focus fall IW, select and refocus on the first conversation in the list
if (change_focus)

View File

@ -231,9 +231,10 @@ private:
conversations_widgets_map mConversationsWidgets;
LLConversationViewModel mConversationViewModel;
LLFolderView* mConversationsRoot;
LLEventStream mConversationsEventStream;
LLEventStream mConversationsEventStream;
std::deque<LLSD> mConversationEventQueue;
typedef std::map<LLUUID, std::deque<LLSD> > conversations_items_deque;
conversations_items_deque mConversationEventQueue;
LLTimer mParticipantRefreshTimer;
};

View File

@ -494,7 +494,10 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant()
while (current_participant_model != end_participant_model)
{
LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
addConversationViewParticipant(participant_model);
if (participant_model)
{
addConversationViewParticipant(participant_model);
}
current_participant_model++;
}
}
@ -531,7 +534,7 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part
LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
if (widget)
{
mConversationsRoot->extractItem(widget);
mConversationsRoot->extractItem(widget, false);
delete widget;
}
mConversationsWidgets.erase(participant_id);

View File

@ -1261,6 +1261,7 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)
httpOpts->setFollowRedirects(true);
httpOpts->setWantHeaders(true);
httpOpts->setSSLVerifyPeer(false); // viewer's cert bundle doesn't appear to agree with web certs from "https://my.secondlife.com/"
LLURL hostUrl(url.c_str());
std::string hostAuth = hostUrl.getAuthority();

View File

@ -347,6 +347,8 @@ void force_error_bad_memory_access(void *);
void force_error_infinite_loop(void *);
void force_error_software_exception(void *);
void force_error_driver_crash(void *);
void force_error_coroutine_crash(void *);
void force_error_thread_crash(void *);
void handle_force_delete(void*);
void print_object_info(void*);
@ -2658,6 +2660,24 @@ class LLAdvancedForceErrorDriverCrash : public view_listener_t
}
};
class LLAdvancedForceErrorCoroutineCrash : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
force_error_coroutine_crash(NULL);
return true;
}
};
class LLAdvancedForceErrorThreadCrash : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
force_error_thread_crash(NULL);
return true;
}
};
class LLAdvancedForceErrorDisconnectViewer : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@ -10257,6 +10277,16 @@ void force_error_driver_crash(void *)
LLAppViewer::instance()->forceErrorDriverCrash();
}
void force_error_coroutine_crash(void *)
{
LLAppViewer::instance()->forceErrorCoroutineCrash();
}
void force_error_thread_crash(void *)
{
LLAppViewer::instance()->forceErrorThreadCrash();
}
class LLToolsUseSelectionForGrid : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@ -11840,6 +11870,8 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");
view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException");
view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash");
view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash");
view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash");
view_listener_t::addMenu(new LLAdvancedForceErrorDisconnectViewer(), "Advanced.ForceErrorDisconnectViewer");
// Advanced (toplevel)

View File

@ -2407,7 +2407,7 @@ void LLViewerRegion::setSimulatorFeaturesReceived(bool received)
mSimulatorFeaturesReceived = received;
if (received)
{
mSimulatorFeaturesReceivedSignal(getRegionID());
mSimulatorFeaturesReceivedSignal(getRegionID(), this);
mSimulatorFeaturesReceivedSignal.disconnect_all_slots();
}
}
@ -3421,7 +3421,7 @@ void LLViewerRegion::setCapabilitiesReceived(bool received)
// so that they can safely use getCapability().
if (received)
{
mCapabilitiesReceivedSignal(getRegionID());
mCapabilitiesReceivedSignal(getRegionID(), this);
LLFloaterPermsDefault::sendInitialPerms();

View File

@ -97,7 +97,7 @@ public:
NUM_PARTITIONS
} eObjectPartitions;
typedef boost::signals2::signal<void(const LLUUID& region_id)> caps_received_signal_t;
typedef boost::signals2::signal<void(const LLUUID& region_id, LLViewerRegion* regionp)> caps_received_signal_t;
LLViewerRegion(const U64 &handle,
const LLHost &host,

View File

@ -113,6 +113,7 @@ void LLWebProfile::uploadImageCoro(LLPointer<LLImageFormatted> image, std::strin
httpOpts->setWantHeaders(true);
httpOpts->setFollowRedirects(false);
httpOpts->setSSLVerifyPeer(false); ; // viewer's cert bundle doesn't appear to agree with web certs from "https://my.secondlife.com/"
// Get upload configuration data.
std::string configUrl(getProfileURL(std::string()) + "snapshots/s3_upload_config");

View File

@ -51,7 +51,7 @@ bool LLEnvironmentRequest::initiate(LLEnvironment::environment_apply_fn cb)
if (!cur_region->capabilitiesReceived())
{
LL_INFOS("WindlightCaps") << "Deferring windlight settings request until we've got region caps" << LL_ENDL;
cur_region->setCapabilitiesReceivedCallback([cb](const LLUUID &region_id) { LLEnvironmentRequest::onRegionCapsReceived(region_id, cb); });
cur_region->setCapabilitiesReceivedCallback([cb](const LLUUID &region_id, LLViewerRegion* regionp) { LLEnvironmentRequest::onRegionCapsReceived(region_id, cb); });
return false;
}

View File

@ -3642,6 +3642,18 @@
<menu_item_call.on_click
function="Advanced.ForceErrorSoftwareException" />
</menu_item_call>
<menu_item_call
label="Force a Crash in a Coroutine"
name="Force a Crash in a Coroutine">
<menu_item_call.on_click
function="Advanced.ForceErrorCoroutineCrash" />
</menu_item_call>
<menu_item_call
label="Force a Crash in a Thread"
name="Force a Crash in a Thread">
<menu_item_call.on_click
function="Advanced.ForceErrorThreadCrash" />
</menu_item_call>
<menu_item_call
label="Force Disconnect Viewer"
name="Force Disconnect Viewer">