summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt28
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/llaccountingcostmanager.cpp4
-rw-r--r--indra/newview/llappviewer.cpp152
-rw-r--r--indra/newview/llappviewerwin32.cpp116
-rw-r--r--indra/newview/llchannelmanager.cpp9
-rw-r--r--indra/newview/llchathistory.cpp4
-rw-r--r--indra/newview/llcurrencyuimanager.cpp20
-rw-r--r--indra/newview/llfloaterregioninfo.cpp4
-rw-r--r--indra/newview/llfloaterreporter.cpp4
-rw-r--r--indra/newview/llimprocessing.cpp110
-rw-r--r--indra/newview/lllogininstance.cpp30
-rw-r--r--indra/newview/llpaneleditwearable.cpp6
-rw-r--r--indra/newview/llpanellogin.cpp12
-rw-r--r--indra/newview/llscenemonitor.cpp44
-rw-r--r--indra/newview/llstartup.cpp72
-rw-r--r--indra/newview/llstartup.h1
-rw-r--r--indra/newview/llstartuplistener.cpp26
-rw-r--r--indra/newview/llstartuplistener.h1
-rw-r--r--indra/newview/lltexturestats.cpp4
-rw-r--r--indra/newview/lltoast.cpp23
-rw-r--r--indra/newview/lltranslate.cpp20
-rw-r--r--indra/newview/llversioninfo.cpp107
-rw-r--r--indra/newview/llversioninfo.h68
-rw-r--r--indra/newview/llviewercontrollistener.cpp12
-rw-r--r--indra/newview/llviewerjoystick.cpp73
-rw-r--r--indra/newview/llviewermedia.cpp4
-rw-r--r--indra/newview/llviewerprecompiledheaders.h2
-rw-r--r--indra/newview/llviewerstats.cpp2
-rw-r--r--indra/newview/llviewerwindow.cpp2
-rw-r--r--indra/newview/llvoicevivox.cpp142
-rw-r--r--indra/newview/llvovolume.cpp2
-rw-r--r--indra/newview/llwatchdog.cpp6
-rw-r--r--indra/newview/llweb.cpp12
-rw-r--r--indra/newview/llwindebug.h4
-rw-r--r--indra/newview/llxmlrpclistener.cpp3
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml5
-rw-r--r--indra/newview/tests/lllogininstance_test.cpp2
-rw-r--r--indra/newview/tests/llversioninfo_test.cpp24
-rwxr-xr-xindra/newview/viewer_manifest.py39
40 files changed, 652 insertions, 549 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 6164e717c5..0d204fd716 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -15,7 +15,6 @@ include(BuildPackagesInfo)
include(BuildVersion)
include(CMakeCopyIfDifferent)
include(DBusGlib)
-include(DirectX)
include(DragDrop)
include(EXPAT)
include(FMODSTUDIO)
@@ -1585,20 +1584,12 @@ if (WINDOWS)
list(APPEND viewer_SOURCE_FILES ${viewer_RESOURCE_FILES})
endif (NOT USESYSTEMLIBS)
- find_library(DINPUT_LIBRARY dinput8 ${DIRECTX_LIBRARY_DIR})
- find_library(DXGUID_LIBRARY dxguid ${DIRECTX_LIBRARY_DIR})
- mark_as_advanced(
- DINPUT_LIBRARY
- DXGUID_LIBRARY
- )
-
# see EXP-1765 - theory is opengl32.lib needs to be included before gdi32.lib (windows libs)
set(viewer_LIBRARIES
opengl32
${WINDOWS_LIBRARIES}
comdlg32
- ${DINPUT_LIBRARY}
- ${DXGUID_LIBRARY}
+ dxguid
kernel32
odbc32
odbccp32
@@ -1785,6 +1776,11 @@ if (WINDOWS)
# be met. I'm looking forward to a source-code split-up project next year that will address this kind of thing.
# In the meantime, if you have any ideas on how to easily maintain one list, either here or in viewer_manifest.py
# and have the build deps get tracked *please* tell me about it.
+ # nat: https://cmake.org/cmake/help/v3.14/command/file.html
+ # "For example, the code
+ # file(STRINGS myfile.txt myfile)
+ # stores a list in the variable myfile in which each item is a line from the input file."
+ # And of course it's straightforward to read a text file in Python.
set(COPY_INPUT_DEPENDENCIES
# The following commented dependencies are determined at variably at build time. Can't do this here.
@@ -1803,12 +1799,6 @@ if (WINDOWS)
${SHARED_LIB_STAGING_DIR}/Release/openjpeg.dll
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/openjpeg.dll
${SHARED_LIB_STAGING_DIR}/Debug/openjpegd.dll
- ${SHARED_LIB_STAGING_DIR}/Release/msvcr100.dll
- ${SHARED_LIB_STAGING_DIR}/Release/msvcp100.dll
- ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/msvcr100.dll
- ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/msvcp100.dll
- ${SHARED_LIB_STAGING_DIR}/Debug/msvcr100d.dll
- ${SHARED_LIB_STAGING_DIR}/Debug/msvcp100d.dll
${SHARED_LIB_STAGING_DIR}/Release/libhunspell.dll
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libhunspell.dll
${SHARED_LIB_STAGING_DIR}/Debug/libhunspell.dll
@@ -1992,6 +1982,7 @@ endif (WINDOWS)
# modern version.
target_link_libraries(${VIEWER_BINARY_NAME}
+ ${LEGACY_STDIO_LIBS}
${PNG_PRELOAD_ARCHIVES}
${ZLIB_PRELOAD_ARCHIVES}
${URIPARSER_PRELOAD_ARCHIVES}
@@ -2018,7 +2009,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${viewer_LIBRARIES}
${BOOST_PROGRAM_OPTIONS_LIBRARY}
${BOOST_REGEX_LIBRARY}
- ${BOOST_COROUTINE_LIBRARY}
+ ${BOOST_FIBER_LIBRARY}
${BOOST_CONTEXT_LIBRARY}
${DBUSGLIB_LIBRARIES}
${OPENGL_LIBRARIES}
@@ -2452,6 +2443,7 @@ if (LL_TESTS)
set_source_files_properties(
lllogininstance.cpp
PROPERTIES
+ LL_TEST_ADDITIONAL_SOURCE_FILES llversioninfo.cpp
LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
)
@@ -2501,7 +2493,7 @@ if (LL_TESTS)
${OPENSSL_LIBRARIES}
${CRYPTO_LIBRARIES}
${LIBRT_LIBRARY}
- ${BOOST_COROUTINE_LIBRARY}
+ ${BOOST_FIBER_LIBRARY}
${BOOST_CONTEXT_LIBRARY}
)
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 7d765dabde..3d05e8cfb4 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.4.5
+6.4.6
diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp
index 1dddf52961..e09527a34b 100644
--- a/indra/newview/llaccountingcostmanager.cpp
+++ b/indra/newview/llaccountingcostmanager.cpp
@@ -48,7 +48,7 @@ LLAccountingCostManager::LLAccountingCostManager()
void LLAccountingCostManager::accountingCostCoro(std::string url,
eSelectionType selectionType, const LLHandle<LLAccountingCostObserver> observerHandle)
{
- LL_DEBUGS("LLAccountingCostManager") << "Entering coroutine " << LLCoros::instance().getName()
+ LL_DEBUGS("LLAccountingCostManager") << "Entering coroutine " << LLCoros::getName()
<< " with url '" << url << LL_ENDL;
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
@@ -158,7 +158,7 @@ void LLAccountingCostManager::accountingCostCoro(std::string url,
}
catch (...)
{
- LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::instance().getName()
+ LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::getName()
<< "('" << url << "')"));
throw;
}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index d82e6fc58c..a07aae9738 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1126,7 +1126,7 @@ bool LLAppViewer::init()
// Save the current version to the prefs file
gSavedSettings.setString("LastRunVersion",
- LLVersionInfo::getChannelAndVersion());
+ LLVersionInfo::instance().getChannelAndVersion());
gSimLastTime = gRenderStartTime.getElapsedTimeF32();
gSimFrames = (F32)gFrameCount;
@@ -1165,7 +1165,7 @@ bool LLAppViewer::init()
// UpdaterServiceSettings
updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
// channel
- updater.args.add(LLVersionInfo::getChannel());
+ updater.args.add(LLVersionInfo::instance().getChannel());
// testok
updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest")));
// ForceAddressSize
@@ -1429,6 +1429,8 @@ bool LLAppViewer::doFrame()
// canonical per-frame event
mainloop.post(newFrame);
+ // give listeners a chance to run
+ llcoro::suspend();
if (!LLApp::isExiting())
{
@@ -1690,24 +1692,9 @@ bool LLAppViewer::cleanup()
gDirUtilp->deleteFilesInDir(logdir, "*-*-*-*-*.dmp");
}
- {
- // Kill off LLLeap objects. We can find them all because LLLeap is derived
- // from LLInstanceTracker. But collect instances first: LLInstanceTracker
- // specifically forbids adding/deleting instances while iterating.
- std::vector<LLLeap*> leaps;
- leaps.reserve(LLLeap::instanceCount());
- for (LLLeap::instance_iter li(LLLeap::beginInstances()), lend(LLLeap::endInstances());
- li != lend; ++li)
- {
- leaps.push_back(&*li);
- }
- // Okay, now trash them all. We don't have to NULL or erase the entry
- // in 'leaps' because the whole vector is going away momentarily.
- BOOST_FOREACH(LLLeap* leap, leaps)
- {
- delete leap;
- }
- } // destroy 'leaps'
+ // Kill off LLLeap objects. We can find them all because LLLeap is derived
+ // from LLInstanceTracker.
+ LLLeap::instance_snapshot().deleteAll();
//flag all elements as needing to be destroyed immediately
// to ensure shutdown order
@@ -2128,25 +2115,19 @@ bool LLAppViewer::cleanup()
removeMarkerFiles();
- // It's not at first obvious where, in this long sequence, generic cleanup
- // calls OUGHT to go. So let's say this: as we migrate cleanup from
+ // It's not at first obvious where, in this long sequence, a generic cleanup
+ // call OUGHT to go. So let's say this: as we migrate cleanup from
// explicit hand-placed calls into the generic mechanism, eventually
- // all cleanup will get subsumed into the generic calls. So the calls you
+ // all cleanup will get subsumed into the generic call. So the calls you
// still see above are calls that MUST happen before the generic cleanup
// kicks in.
- // This calls every remaining LLSingleton's cleanupSingleton() method.
- // This method should perform any cleanup that might take significant
- // realtime, or might throw an exception.
- LLSingletonBase::cleanupAll();
-
// The logging subsystem depends on an LLSingleton. Any logging after
// LLSingletonBase::deleteAll() won't be recorded.
LL_INFOS() << "Goodbye!" << LL_ENDL;
- // This calls every remaining LLSingleton's deleteSingleton() method.
- // No class destructor should perform any cleanup that might take
- // significant realtime, or throw an exception.
+ // This calls every remaining LLSingleton's cleanupSingleton() and
+ // deleteSingleton() methods.
LLSingletonBase::deleteAll();
removeDumpDir();
@@ -2659,7 +2640,7 @@ bool LLAppViewer::initConfiguration()
std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel"));
if(! CmdLineChannel.empty())
{
- LLVersionInfo::resetChannel(CmdLineChannel);
+ LLVersionInfo::instance().resetChannel(CmdLineChannel);
}
// If we have specified crash on startup, set the global so we'll trigger the crash at the right time
@@ -2880,12 +2861,11 @@ bool LLAppViewer::initConfiguration()
// Let anyone else who cares know that we've populated our settings
// variables.
- for (LLControlGroup::key_iter ki(LLControlGroup::beginKeys()), kend(LLControlGroup::endKeys());
- ki != kend; ++ki)
+ for (const auto& key : LLControlGroup::key_snapshot())
{
// For each named instance of LLControlGroup, send an event saying
// we've initialized an LLControlGroup instance by that name.
- LLEventPumps::instance().obtain("LLControlGroup").post(LLSDMap("init", *ki));
+ LLEventPumps::instance().obtain("LLControlGroup").post(LLSDMap("init", key));
}
return true; // Config was successful.
@@ -3105,16 +3085,12 @@ LLSD LLAppViewer::getViewerInfo() const
// is available to a getInfo() caller as to the user opening
// LLFloaterAbout.
LLSD info;
- LLSD version;
- version.append(LLVersionInfo::getMajor());
- version.append(LLVersionInfo::getMinor());
- version.append(LLVersionInfo::getPatch());
- version.append(LLVersionInfo::getBuild());
- info["VIEWER_VERSION"] = version;
- info["VIEWER_VERSION_STR"] = LLVersionInfo::getVersion();
- info["CHANNEL"] = LLVersionInfo::getChannel();
+ auto& versionInfo(LLVersionInfo::instance());
+ info["VIEWER_VERSION"] = LLSDArray(versionInfo.getMajor())(versionInfo.getMinor())(versionInfo.getPatch())(versionInfo.getBuild());
+ info["VIEWER_VERSION_STR"] = versionInfo.getVersion();
+ info["CHANNEL"] = versionInfo.getChannel();
info["ADDRESS_SIZE"] = ADDRESS_SIZE;
- std::string build_config = LLVersionInfo::getBuildConfig();
+ std::string build_config = versionInfo.getBuildConfig();
if (build_config != "Release")
{
info["BUILD_CONFIG"] = build_config;
@@ -3122,12 +3098,8 @@ LLSD LLAppViewer::getViewerInfo() const
// return a URL to the release notes for this viewer, such as:
// https://releasenotes.secondlife.com/viewer/2.1.0.123456.html
- std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL");
- if (! LLStringUtil::endsWith(url, "/"))
- url += "/";
- url += LLURI::escape(LLVersionInfo::getVersion()) + ".html";
-
- info["VIEWER_RELEASE_NOTES_URL"] = url;
+ std::string url = versionInfo.getReleaseNotes();
+ info["VIEWER_RELEASE_NOTES_URL"] = url.empty()? LLTrans::getString("RetrievingData") : url;
// Position
LLViewerRegion* region = gAgent.getRegion();
@@ -3420,12 +3392,12 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.old"); //LLError::logFileName();
#endif
- gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel();
- gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
- gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor();
- gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::getPatch();
- gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::getBuild();
- gDebugInfo["ClientInfo"]["AddressSize"] = LLVersionInfo::getAddressSize();
+ gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::instance().getChannel();
+ gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::instance().getMajor();
+ gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::instance().getMinor();
+ gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::instance().getPatch();
+ gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::instance().getBuild();
+ gDebugInfo["ClientInfo"]["AddressSize"] = LLVersionInfo::instance().getAddressSize();
gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
@@ -3468,7 +3440,7 @@ void LLAppViewer::writeSystemInfo()
// Dump some debugging info
LL_INFOS("SystemInfo") << "Application: " << LLTrans::getString("APP_NAME") << LL_ENDL;
- LL_INFOS("SystemInfo") << "Version: " << LLVersionInfo::getChannelAndVersion() << LL_ENDL;
+ LL_INFOS("SystemInfo") << "Version: " << LLVersionInfo::instance().getChannelAndVersion() << LL_ENDL;
// Dump the local time and time zone
time_t now;
@@ -3696,7 +3668,7 @@ void LLAppViewer::handleViewerCrash()
// static
void LLAppViewer::recordMarkerVersion(LLAPRFile& marker_file)
{
- std::string marker_version(LLVersionInfo::getChannelAndVersion());
+ std::string marker_version(LLVersionInfo::instance().getChannelAndVersion());
if ( marker_version.length() > MAX_MARKER_LENGTH )
{
LL_WARNS_ONCE("MarkerFile") << "Version length ("<< marker_version.length()<< ")"
@@ -3713,7 +3685,7 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const
{
bool sameVersion = false;
- std::string my_version(LLVersionInfo::getChannelAndVersion());
+ std::string my_version(LLVersionInfo::instance().getChannelAndVersion());
char marker_version[MAX_MARKER_LENGTH];
S32 marker_version_length;
@@ -4673,6 +4645,9 @@ void LLAppViewer::idle()
LLFrameTimer::updateFrameTime();
LLFrameTimer::updateFrameCount();
LLEventTimer::updateClass();
+ // LLApp::stepFrame() performs the above three calls plus mRunner.run().
+ // Not sure why we don't call stepFrame() here, except that LLRunner seems
+ // completely redundant with LLEventTimer.
LLNotificationsUI::LLToast::updateClass();
LLSmoothInterpolation::updateInterpolants();
LLMortician::updateClass();
@@ -5285,37 +5260,40 @@ void LLAppViewer::idleNetwork()
const S64 frame_count = gFrameCount; // U32->S64
F32 total_time = 0.0f;
- while (gMessageSystem->checkAllMessages(frame_count, gServicePump))
{
- if (gDoDisconnect)
+ LockMessageChecker lmc(gMessageSystem);
+ while (lmc.checkAllMessages(frame_count, gServicePump))
{
- // We're disconnecting, don't process any more messages from the server
- // We're usually disconnecting due to either network corruption or a
- // server going down, so this is OK.
- break;
- }
+ if (gDoDisconnect)
+ {
+ // We're disconnecting, don't process any more messages from the server
+ // We're usually disconnecting due to either network corruption or a
+ // server going down, so this is OK.
+ break;
+ }
- total_decoded++;
- gPacketsIn++;
+ total_decoded++;
+ gPacketsIn++;
- if (total_decoded > MESSAGE_MAX_PER_FRAME)
- {
- break;
- }
+ if (total_decoded > MESSAGE_MAX_PER_FRAME)
+ {
+ 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)
- break;
+ // 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)
+ break;
#endif
- }
+ }
- // Handle per-frame message system processing.
- gMessageSystem->processAcks(gSavedSettings.getF32("AckCollectTime"));
+ // Handle per-frame message system processing.
+ lmc.processAcks(gSavedSettings.getF32("AckCollectTime"));
+ }
#ifdef TIME_THROTTLE_MESSAGES
if (total_time >= CheckMessagesMaxTime)
@@ -5573,12 +5551,12 @@ void LLAppViewer::handleLoginComplete()
initMainloopTimeout("Mainloop Init");
// Store some data to DebugInfo in case of a freeze.
- gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel();
+ gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::instance().getChannel();
- gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
- gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor();
- gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::getPatch();
- gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::getBuild();
+ gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::instance().getMajor();
+ gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::instance().getMinor();
+ gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::instance().getPatch();
+ gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::instance().getBuild();
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if ( parcel && parcel->getMusicURL()[0])
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index d208e135bb..156a1c5893 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -500,68 +500,76 @@ void LLAppViewerWin32::disableWinErrorReporting()
}
const S32 MAX_CONSOLE_LINES = 500;
+// Only defined in newer SDKs than we currently use
+#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
+#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 4
+#endif
-static bool create_console()
-{
- int h_con_handle;
- long l_std_handle;
-
- CONSOLE_SCREEN_BUFFER_INFO coninfo;
- FILE *fp;
-
- // allocate a console for this app
- const bool isConsoleAllocated = AllocConsole();
-
- // set the screen buffer to be big enough to let us scroll text
- GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
- coninfo.dwSize.Y = MAX_CONSOLE_LINES;
- SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
+namespace {
- // redirect unbuffered STDOUT to the console
- l_std_handle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
- h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT);
- if (h_con_handle == -1)
- {
- LL_WARNS() << "create_console() failed to open stdout handle" << LL_ENDL;
- }
- else
- {
- fp = _fdopen( h_con_handle, "w" );
- *stdout = *fp;
- setvbuf( stdout, NULL, _IONBF, 0 );
- }
+void set_stream(const char* desc, FILE* fp, DWORD handle_id, const char* name, const char* mode="w");
- // redirect unbuffered STDIN to the console
- l_std_handle = (long)GetStdHandle(STD_INPUT_HANDLE);
- h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT);
- if (h_con_handle == -1)
- {
- LL_WARNS() << "create_console() failed to open stdin handle" << LL_ENDL;
- }
- else
- {
- fp = _fdopen( h_con_handle, "r" );
- *stdin = *fp;
- setvbuf( stdin, NULL, _IONBF, 0 );
- }
+bool create_console()
+{
+ // allocate a console for this app
+ const bool isConsoleAllocated = AllocConsole();
- // redirect unbuffered STDERR to the console
- l_std_handle = (long)GetStdHandle(STD_ERROR_HANDLE);
- h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT);
- if (h_con_handle == -1)
- {
- LL_WARNS() << "create_console() failed to open stderr handle" << LL_ENDL;
- }
- else
- {
- fp = _fdopen( h_con_handle, "w" );
- *stderr = *fp;
- setvbuf( stderr, NULL, _IONBF, 0 );
- }
+ if (isConsoleAllocated)
+ {
+ // set the screen buffer to be big enough to let us scroll text
+ CONSOLE_SCREEN_BUFFER_INFO coninfo;
+ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
+ coninfo.dwSize.Y = MAX_CONSOLE_LINES;
+ SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
+
+ // redirect unbuffered STDOUT to the console
+ set_stream("stdout", stdout, STD_OUTPUT_HANDLE, "CONOUT$");
+ // redirect unbuffered STDERR to the console
+ set_stream("stderr", stderr, STD_ERROR_HANDLE, "CONOUT$");
+ // redirect unbuffered STDIN to the console
+ // Don't bother: our console is solely for log output. We never read stdin.
+// set_stream("stdin", stdin, STD_INPUT_HANDLE, "CONIN$", "r");
+ }
return isConsoleAllocated;
}
+void set_stream(const char* desc, FILE* fp, DWORD handle_id, const char* name, const char* mode)
+{
+ // SL-13528: This code used to be based on
+ // http://dslweb.nwnexus.com/~ast/dload/guicon.htm
+ // (referenced in https://stackoverflow.com/a/191880).
+ // But one of the comments on that StackOverflow answer points out that
+ // assigning to *stdout or *stderr "probably doesn't even work with the
+ // Universal CRT that was introduced in 2015," suggesting freopen_s()
+ // instead. Code below is based on https://stackoverflow.com/a/55875595.
+ auto std_handle = GetStdHandle(handle_id);
+ if (std_handle == INVALID_HANDLE_VALUE)
+ {
+ LL_WARNS() << "create_console() failed to get " << desc << " handle" << LL_ENDL;
+ }
+ else
+ {
+ if (mode == std::string("w"))
+ {
+ // Enable color processing on Windows 10 console windows.
+ DWORD dwMode = 0;
+ GetConsoleMode(std_handle, &dwMode);
+ dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
+ SetConsoleMode(std_handle, dwMode);
+ }
+ // Redirect the passed fp to the console.
+ FILE* ignore;
+ if (freopen_s(&ignore, name, mode, fp) == 0)
+ {
+ // use unbuffered I/O
+ setvbuf( fp, NULL, _IONBF, 0 );
+ }
+ }
+}
+
+} // anonymous namespace
+
LLAppViewerWin32::LLAppViewerWin32(const char* cmd_line) :
mCmdLine(cmd_line),
mIsConsoleAllocated(false)
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 0b7b9cbbc7..9e7a8ba95c 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -48,11 +48,18 @@ LLChannelManager::LLChannelManager()
LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLChannelManager::onLoginCompleted, this));
mChannelList.clear();
mStartUpChannel = NULL;
-
+
if(!gViewerWindow)
{
LL_ERRS() << "LLChannelManager::LLChannelManager() - viwer window is not initialized yet" << LL_ENDL;
}
+
+ // We don't actually need this instance right now, but our
+ // cleanupSingleton() method deletes LLScreenChannels, which need to
+ // unregister from LLUI. Calling LLUI::instance() here establishes the
+ // dependency so LLSingletonBase::deleteAll() calls our deleteSingleton()
+ // before LLUI::deleteSingleton().
+ LLUI::instance();
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 1099d4bc09..4131af828e 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -1344,10 +1344,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
// We don't want multiple friendship offers to appear, this code checks if there are previous offers
// by iterating though all panels.
// Note: it might be better to simply add a "pending offer" flag somewhere
- for (LLToastNotifyPanel::instance_iter ti(LLToastNotifyPanel::beginInstances())
- , tend(LLToastNotifyPanel::endInstances()); ti != tend; ++ti)
+ for (auto& panel : LLToastNotifyPanel::instance_snapshot())
{
- LLToastNotifyPanel& panel = *ti;
LLIMToastNotifyPanel * imtoastp = dynamic_cast<LLIMToastNotifyPanel *>(&panel);
const std::string& notification_name = panel.getNotificationName();
if (notification_name == "OfferFriendship"
diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp
index b4a1457f47..df94e337da 100644
--- a/indra/newview/llcurrencyuimanager.cpp
+++ b/indra/newview/llcurrencyuimanager.cpp
@@ -166,11 +166,11 @@ void LLCurrencyUIManager::Impl::updateCurrencyInfo()
gAgent.getSecureSessionID().asString());
keywordArgs.appendString("language", LLUI::getLanguage());
keywordArgs.appendInt("currencyBuy", mUserCurrencyBuy);
- keywordArgs.appendString("viewerChannel", LLVersionInfo::getChannel());
- keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::getMajor());
- keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::getMinor());
- keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::getPatch());
- keywordArgs.appendInt("viewerBuildVersion", LLVersionInfo::getBuild());
+ keywordArgs.appendString("viewerChannel", LLVersionInfo::instance().getChannel());
+ keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::instance().getMajor());
+ keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::instance().getMinor());
+ keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::instance().getPatch());
+ keywordArgs.appendInt("viewerBuildVersion", LLVersionInfo::instance().getBuild());
LLXMLRPCValue params = LLXMLRPCValue::createArray();
params.append(keywordArgs);
@@ -241,11 +241,11 @@ void LLCurrencyUIManager::Impl::startCurrencyBuy(const std::string& password)
{
keywordArgs.appendString("password", password);
}
- keywordArgs.appendString("viewerChannel", LLVersionInfo::getChannel());
- keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::getMajor());
- keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::getMinor());
- keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::getPatch());
- keywordArgs.appendInt("viewerBuildVersion", LLVersionInfo::getBuild());
+ keywordArgs.appendString("viewerChannel", LLVersionInfo::instance().getChannel());
+ keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::instance().getMajor());
+ keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::instance().getMinor());
+ keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::instance().getPatch());
+ keywordArgs.appendInt("viewerBuildVersion", LLVersionInfo::instance().getBuild());
LLXMLRPCValue params = LLXMLRPCValue::createArray();
params.append(keywordArgs);
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 8bcc5bbe7a..ec1909d02a 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -637,11 +637,7 @@ void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region)
mInfoPanels.begin(),
mInfoPanels.end(),
llbind2nd(
-#if LL_WINDOWS
- std::mem_fun1(&LLPanelRegionInfo::refreshFromRegion),
-#else
std::mem_fun(&LLPanelRegionInfo::refreshFromRegion),
-#endif
region));
mEnvironmentPanel->refreshFromRegion(region);
}
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 4cc43254a5..64b7880938 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -765,7 +765,7 @@ LLSD LLFloaterReporter::gatherReport()
std::ostringstream details;
- details << "V" << LLVersionInfo::getVersion() << std::endl << std::endl; // client version moved to body of email for abuse reports
+ details << "V" << LLVersionInfo::instance().getVersion() << std::endl << std::endl; // client version moved to body of email for abuse reports
std::string object_name = getChild<LLUICtrl>("object_name")->getValue().asString();
if (!object_name.empty() && !mOwnerName.empty())
@@ -783,7 +783,7 @@ LLSD LLFloaterReporter::gatherReport()
std::string version_string;
version_string = llformat(
"%s %s %s %s %s",
- LLVersionInfo::getShortVersion().c_str(),
+ LLVersionInfo::instance().getShortVersion().c_str(),
platform,
gSysCPU.getFamily().c_str(),
gGLManager.mGLRenderer.c_str(),
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index 6da7bbe263..7b87b43243 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -857,41 +857,41 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
}
else // IM_TASK_INVENTORY_OFFERED
{
- if (offline == IM_OFFLINE && session_id.isNull() && aux_id.notNull() && binary_bucket_size > sizeof(S8)* 5)
+ if (sizeof(S8) == binary_bucket_size)
{
- // cap received offline message
- std::string str_bucket = ll_safe_string((char*)binary_bucket, binary_bucket_size);
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
- tokenizer tokens(str_bucket, sep);
- tokenizer::iterator iter = tokens.begin();
-
- info->mType = (LLAssetType::EType)(atoi((*(iter++)).c_str()));
- // Note There is more elements in 'tokens' ...
-
- info->mObjectID = LLUUID::null;
- info->mFromObject = TRUE;
+ info->mType = (LLAssetType::EType) binary_bucket[0];
}
else
{
- if (sizeof(S8) != binary_bucket_size)
- {
- LL_WARNS("Messaging") << "Malformed inventory offer from object" << LL_ENDL;
- delete info;
- break;
- }
- info->mType = (LLAssetType::EType) binary_bucket[0];
- info->mObjectID = LLUUID::null;
- info->mFromObject = TRUE;
+ /*RIDER*/ // The previous version of the protocol returned the wrong binary bucket... we
+ // still might be able to figure out the type... even though the offer is not retrievable.
+
+ // Should be safe to remove once DRTSIM-451 fully deploys
+ std::string str_bucket(reinterpret_cast<char *>(binary_bucket));
+ std::string str_type(str_bucket.substr(0, str_bucket.find('|')));
+
+ std::stringstream type_convert(str_type);
+
+ S32 type;
+ type_convert >> type;
+
+ // We could try AT_UNKNOWN which would be more accurate, but that causes an auto decline
+ info->mType = static_cast<LLAssetType::EType>(type);
+ // Don't break in the case of a bad binary bucket. Go ahead and show the
+ // accept/decline popup even though it will not do anything.
+ LL_WARNS("Messaging") << "Malformed inventory offer from object, type might be " << info->mType << LL_ENDL;
}
+ info->mObjectID = LLUUID::null;
+ info->mFromObject = TRUE;
}
info->mIM = dialog;
info->mFromID = from_id;
info->mFromGroup = from_group;
- info->mTransactionID = session_id;
info->mFolderID = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(info->mType));
+ info->mTransactionID = session_id.notNull() ? session_id : aux_id;
+
info->mFromName = name;
info->mDesc = message;
info->mHost = sender;
@@ -1404,10 +1404,8 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
payload["sender"] = sender.getIPandPort();
bool add_notification = true;
- for (LLToastNotifyPanel::instance_iter ti(LLToastNotifyPanel::beginInstances())
- , tend(LLToastNotifyPanel::endInstances()); ti != tend; ++ti)
+ for (auto& panel : LLToastNotifyPanel::instance_snapshot())
{
- LLToastNotifyPanel& panel = *ti;
const std::string& notification_name = panel.getNotificationName();
if (notification_name == "OfferFriendship" && panel.isControlPanelEnabled())
{
@@ -1569,7 +1567,7 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url)
return;
}
- if (gAgent.getRegion() == NULL)
+ if (!gAgent.getRegion())
{
LL_WARNS("Messaging") << "Region null while attempting to load messages." << LL_ENDL;
return;
@@ -1577,8 +1575,6 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url)
LL_INFOS("Messaging") << "Processing offline messages." << LL_ENDL;
- std::vector<U8> data;
- S32 binary_bucket_size = 0;
LLHost sender = gAgent.getRegionHost();
LLSD::array_iterator i = messages.beginArray();
@@ -1587,38 +1583,58 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url)
{
const LLSD &message_data(*i);
- LLVector3 position(message_data["local_x"].asReal(), message_data["local_y"].asReal(), message_data["local_z"].asReal());
- data = message_data["binary_bucket"].asBinary();
- binary_bucket_size = data.size(); // message_data["count"] always 0
- U32 parent_estate_id = message_data.has("parent_estate_id") ? message_data["parent_estate_id"].asInteger() : 1; // 1 - IMMainland
+ /* RIDER: Many fields in this message are using a '_' rather than the standard '-'. This
+ * should be changed but would require tight coordination with the simulator.
+ */
+ LLVector3 position;
+ if (message_data.has("position"))
+ {
+ position.setValue(message_data["position"]);
+ }
+ else
+ {
+ position.set(message_data["local_x"].asReal(), message_data["local_y"].asReal(), message_data["local_z"].asReal());
+ }
- // Todo: once dirtsim-369 releases, remove one of the int/str options
- BOOL from_group;
- if (message_data["from_group"].isInteger())
+ std::vector<U8> bin_bucket;
+ if (message_data.has("binary_bucket"))
{
- from_group = message_data["from_group"].asInteger();
+ bin_bucket = message_data["binary_bucket"].asBinary();
}
else
{
- from_group = message_data["from_group"].asString() == "Y";
+ bin_bucket.push_back(0);
}
- LLIMProcessing::processNewMessage(message_data["from_agent_id"].asUUID(),
+ // Todo: once drtsim-451 releases, remove the string option
+ BOOL from_group;
+ if (message_data["from_group"].isInteger())
+ {
+ from_group = message_data["from_group"].asInteger();
+ }
+ else
+ {
+ from_group = message_data["from_group"].asString() == "Y";
+ }
+
+ LLIMProcessing::processNewMessage(
+ message_data["from_agent_id"].asUUID(),
from_group,
message_data["to_agent_id"].asUUID(),
- IM_OFFLINE,
- (EInstantMessage)message_data["dialog"].asInteger(),
- LLUUID::null, // session id, since there is none we can only use frienship/group invite caps
- message_data["timestamp"].asInteger(),
+ message_data.has("offline") ? static_cast<U8>(message_data["offline"].asInteger()) : IM_OFFLINE,
+ static_cast<EInstantMessage>(message_data["dialog"].asInteger()),
+ message_data["transaction-id"].asUUID(),
+ static_cast<U32>(message_data["timestamp"].asInteger()),
message_data["from_agent_name"].asString(),
message_data["message"].asString(),
- parent_estate_id,
+ static_cast<U32>((message_data.has("parent_estate_id")) ? message_data["parent_estate_id"].asInteger() : 1), // 1 - IMMainland
message_data["region_id"].asUUID(),
position,
- &data[0],
- binary_bucket_size,
+ bin_bucket.data(),
+ bin_bucket.size(),
sender,
- message_data["asset_id"].asUUID()); // not necessarily an asset
+ message_data["asset_id"].asUUID());
+
}
}
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 873531ef22..9d54c8c9c5 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -215,8 +215,8 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
request_params["last_exec_event"] = mLastExecEvent;
request_params["last_exec_duration"] = mLastExecDuration;
request_params["mac"] = (char*)hashed_unique_id_string;
- request_params["version"] = LLVersionInfo::getVersion();
- request_params["channel"] = LLVersionInfo::getChannel();
+ request_params["version"] = LLVersionInfo::instance().getVersion();
+ request_params["channel"] = LLVersionInfo::instance().getChannel();
request_params["platform"] = mPlatform;
request_params["address_size"] = ADDRESS_SIZE;
request_params["platform_version"] = mPlatformVersion;
@@ -332,7 +332,7 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
{
data["certificate"] = response["certificate"];
}
-
+
if (gViewerWindow)
gViewerWindow->setShowProgress(FALSE);
@@ -349,13 +349,31 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
// login.cgi is insisting on a required update. We were called with an
// event that bundles both the login.cgi 'response' and the
// synchronization event from the 'updater'.
- std::string required_version = response["message_args"]["VERSION"];
- LL_WARNS("LLLogin") << "Login failed because an update to version " << required_version << " is required." << LL_ENDL;
+ std::string login_version = response["message_args"]["VERSION"];
+ std::string vvm_version = updater["VERSION"];
+ std::string relnotes = updater["URL"];
+ LL_WARNS("LLLogin") << "Login failed because an update to version " << login_version << " is required." << LL_ENDL;
+ // vvm_version might be empty because we might not have gotten
+ // SLVersionChecker's LoginSync handshake. But if it IS populated, it
+ // should (!) be the same as the version we got from login.cgi.
+ if ((! vvm_version.empty()) && vvm_version != login_version)
+ {
+ LL_WARNS("LLLogin") << "VVM update version " << vvm_version
+ << " differs from login version " << login_version
+ << "; presenting VVM version to match release notes URL"
+ << LL_ENDL;
+ login_version = vvm_version;
+ }
+ if (relnotes.empty())
+ {
+ // I thought this would be available in strings.xml or some such
+ relnotes = "https://secondlife.com/support/downloads/";
+ }
if (gViewerWindow)
gViewerWindow->setShowProgress(FALSE);
- LLSD args(LLSDMap("VERSION", required_version));
+ LLSD args(LLSDMap("VERSION", login_version)("URL", relnotes));
if (updater.isUndefined())
{
// If the updater failed to shake hands, better advise the user to
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index 6573be0aaf..c601a6c210 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -778,7 +778,7 @@ BOOL LLPanelEditWearable::postBuild()
LL_WARNS() << "could not get wearable dictionary entry for wearable of type: " << type << LL_ENDL;
continue;
}
- U8 num_subparts = wearable_entry->mSubparts.size();
+ U8 num_subparts = (U8)(wearable_entry->mSubparts.size());
for (U8 index = 0; index < num_subparts; ++index)
{
@@ -1181,7 +1181,7 @@ void LLPanelEditWearable::showWearable(LLViewerWearable* wearable, BOOL show, BO
updatePanelPickerControls(type);
// clear and rebuild visual param list
- U8 num_subparts = wearable_entry->mSubparts.size();
+ U8 num_subparts = (U8)(wearable_entry->mSubparts.size());
for (U8 index = 0; index < num_subparts; ++index)
{
@@ -1372,7 +1372,7 @@ void LLPanelEditWearable::updateScrollingPanelUI()
const LLEditWearableDictionary::WearableEntry *wearable_entry = LLEditWearableDictionary::getInstance()->getWearable(type);
llassert(wearable_entry);
if (!wearable_entry) return;
- U8 num_subparts = wearable_entry->mSubparts.size();
+ U8 num_subparts = (U8)(wearable_entry->mSubparts.size());
LLScrollingPanelParam::sUpdateDelayFrames = 0;
for (U8 index = 0; index < num_subparts; ++index)
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 224cec9650..70757882d8 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -338,10 +338,10 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
LLButton* def_btn = getChild<LLButton>("connect_btn");
setDefaultBtn(def_btn);
- std::string channel = LLVersionInfo::getChannel();
+ std::string channel = LLVersionInfo::instance().getChannel();
std::string version = llformat("%s (%d)",
- LLVersionInfo::getShortVersion().c_str(),
- LLVersionInfo::getBuild());
+ LLVersionInfo::instance().getShortVersion().c_str(),
+ LLVersionInfo::instance().getBuild());
LLTextBox* forgot_password_text = getChild<LLTextBox>("forgot_password_text");
forgot_password_text->setClickedCallback(onClickForgotPassword, NULL);
@@ -943,9 +943,9 @@ void LLPanelLogin::loadLoginPage()
// Channel and Version
params["version"] = llformat("%s (%d)",
- LLVersionInfo::getShortVersion().c_str(),
- LLVersionInfo::getBuild());
- params["channel"] = LLVersionInfo::getChannel();
+ LLVersionInfo::instance().getShortVersion().c_str(),
+ LLVersionInfo::instance().getBuild());
+ params["channel"] = LLVersionInfo::instance().getChannel();
// Grid
params["grid"] = LLGridManager::getInstance()->getGridId();
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
index 5ab0013055..2c0c38dc75 100644
--- a/indra/newview/llscenemonitor.cpp
+++ b/indra/newview/llscenemonitor.cpp
@@ -559,16 +559,14 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
typedef StatType<CountAccumulator> trace_count;
- for (trace_count::instance_iter it = trace_count::beginInstances(), end_it = trace_count::endInstances();
- it != end_it;
- ++it)
+ for (auto& it : trace_count::instance_snapshot())
{
std::ostringstream row;
row << std::setprecision(10);
- row << it->getName();
+ row << it.getName();
- const char* unit_label = it->getUnitLabel();
+ const char* unit_label = it.getUnitLabel();
if(unit_label[0])
{
row << "(" << unit_label << ")";
@@ -579,8 +577,8 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
for (S32 frame = 1; frame <= frame_count; frame++)
{
Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
- samples += recording.getSampleCount(*it);
- row << ", " << recording.getSum(*it);
+ samples += recording.getSampleCount(it);
+ row << ", " << recording.getSum(it);
}
row << '\n';
@@ -593,15 +591,13 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
typedef StatType<EventAccumulator> trace_event;
- for (trace_event::instance_iter it = trace_event::beginInstances(), end_it = trace_event::endInstances();
- it != end_it;
- ++it)
+ for (auto& it : trace_event::instance_snapshot())
{
std::ostringstream row;
row << std::setprecision(10);
- row << it->getName();
+ row << it.getName();
- const char* unit_label = it->getUnitLabel();
+ const char* unit_label = it.getUnitLabel();
if(unit_label[0])
{
row << "(" << unit_label << ")";
@@ -612,8 +608,8 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
for (S32 frame = 1; frame <= frame_count; frame++)
{
Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
- samples += recording.getSampleCount(*it);
- F64 mean = recording.getMean(*it);
+ samples += recording.getSampleCount(it);
+ F64 mean = recording.getMean(it);
if (llisnan(mean))
{
row << ", n/a";
@@ -634,15 +630,13 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
typedef StatType<SampleAccumulator> trace_sample;
- for (trace_sample::instance_iter it = trace_sample::beginInstances(), end_it = trace_sample::endInstances();
- it != end_it;
- ++it)
+ for (auto& it : trace_sample::instance_snapshot())
{
std::ostringstream row;
row << std::setprecision(10);
- row << it->getName();
+ row << it.getName();
- const char* unit_label = it->getUnitLabel();
+ const char* unit_label = it.getUnitLabel();
if(unit_label[0])
{
row << "(" << unit_label << ")";
@@ -653,8 +647,8 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
for (S32 frame = 1; frame <= frame_count; frame++)
{
Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
- samples += recording.getSampleCount(*it);
- F64 mean = recording.getMean(*it);
+ samples += recording.getSampleCount(it);
+ F64 mean = recording.getMean(it);
if (llisnan(mean))
{
row << ", n/a";
@@ -674,15 +668,13 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
}
typedef StatType<MemAccumulator> trace_mem;
- for (trace_mem::instance_iter it = trace_mem::beginInstances(), end_it = trace_mem::endInstances();
- it != end_it;
- ++it)
+ for (auto& it : trace_mem::instance_snapshot())
{
- os << it->getName() << "(KiB)";
+ os << it.getName() << "(KiB)";
for (S32 frame = 1; frame <= frame_count; frame++)
{
- os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(*it).valueInUnits<LLUnits::Kilobytes>();
+ os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(it).valueInUnits<LLUnits::Kilobytes>();
}
os << '\n';
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 1be1c4ba96..4b65ead236 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -512,9 +512,9 @@ bool idle_startup()
if(!start_messaging_system(
message_template_path,
port,
- LLVersionInfo::getMajor(),
- LLVersionInfo::getMinor(),
- LLVersionInfo::getPatch(),
+ LLVersionInfo::instance().getMajor(),
+ LLVersionInfo::instance().getMinor(),
+ LLVersionInfo::instance().getPatch(),
FALSE,
std::string(),
responder,
@@ -1534,12 +1534,14 @@ bool idle_startup()
{
LLStartUp::setStartupState( STATE_AGENT_SEND );
}
- LLMessageSystem* msg = gMessageSystem;
- while (msg->checkAllMessages(gFrameCount, gServicePump))
{
- display_startup();
+ LockMessageChecker lmc(gMessageSystem);
+ while (lmc.checkAllMessages(gFrameCount, gServicePump))
+ {
+ display_startup();
+ }
+ lmc.processAcks();
}
- msg->processAcks();
display_startup();
return FALSE;
}
@@ -1589,25 +1591,27 @@ bool idle_startup()
//---------------------------------------------------------------------
if (STATE_AGENT_WAIT == LLStartUp::getStartupState())
{
- LLMessageSystem* msg = gMessageSystem;
- while (msg->checkAllMessages(gFrameCount, gServicePump))
{
- if (gAgentMovementCompleted)
- {
- // Sometimes we have more than one message in the
- // queue. break out of this loop and continue
- // processing. If we don't, then this could skip one
- // or more login steps.
- break;
- }
- else
+ LockMessageChecker lmc(gMessageSystem);
+ while (lmc.checkAllMessages(gFrameCount, gServicePump))
{
- LL_DEBUGS("AppInit") << "Awaiting AvatarInitComplete, got "
- << msg->getMessageName() << LL_ENDL;
+ if (gAgentMovementCompleted)
+ {
+ // Sometimes we have more than one message in the
+ // queue. break out of this loop and continue
+ // processing. If we don't, then this could skip one
+ // or more login steps.
+ break;
+ }
+ else
+ {
+ LL_DEBUGS("AppInit") << "Awaiting AvatarInitComplete, got "
+ << gMessageSystem->getMessageName() << LL_ENDL;
+ }
+ display_startup();
}
- display_startup();
+ lmc.processAcks();
}
- msg->processAcks();
display_startup();
@@ -2297,13 +2301,29 @@ void login_callback(S32 option, void *userdata)
void show_release_notes_if_required()
{
static bool release_notes_shown = false;
- if (!release_notes_shown && (LLVersionInfo::getChannelAndVersion() != gLastRunVersion)
- && LLVersionInfo::getViewerMaturity() != LLVersionInfo::TEST_VIEWER // don't show Release Notes for the test builds
+ // We happen to know that instantiating LLVersionInfo implicitly
+ // instantiates the LLEventMailDrop named "relnotes", which we (might) use
+ // below. If viewer release notes stop working, might be because that
+ // LLEventMailDrop got moved out of LLVersionInfo and hasn't yet been
+ // instantiated.
+ if (!release_notes_shown && (LLVersionInfo::instance().getChannelAndVersion() != gLastRunVersion)
+ && LLVersionInfo::instance().getViewerMaturity() != LLVersionInfo::TEST_VIEWER // don't show Release Notes for the test builds
&& gSavedSettings.getBOOL("UpdaterShowReleaseNotes")
&& !gSavedSettings.getBOOL("FirstLoginThisInstall"))
{
- LLSD info(LLAppViewer::instance()->getViewerInfo());
- LLWeb::loadURLInternal(info["VIEWER_RELEASE_NOTES_URL"]);
+ // Instantiate a "relnotes" listener which assumes any arriving event
+ // is the release notes URL string. Since "relnotes" is an
+ // LLEventMailDrop, this listener will be invoked whether or not the
+ // URL has already been posted. If so, it will fire immediately;
+ // otherwise it will fire whenever the URL is (later) posted. Either
+ // way, it will display the release notes as soon as the URL becomes
+ // available.
+ LLEventPumps::instance().obtain("relnotes").listen(
+ "showrelnotes",
+ [](const LLSD& url){
+ LLWeb::loadURLInternal(url.asString());
+ return false;
+ });
release_notes_shown = true;
}
}
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index d7d294e9f4..3ec3ff4133 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -128,6 +128,7 @@ public:
static LLViewerStats::PhaseMap& getPhases() { return *sPhases; }
private:
+ friend class LLStartupListener;
static LLSLURL sStartSLURL;
static std::string startupStateToString(EStartupState state);
diff --git a/indra/newview/llstartuplistener.cpp b/indra/newview/llstartuplistener.cpp
index d9a21f908e..5770b595d0 100644
--- a/indra/newview/llstartuplistener.cpp
+++ b/indra/newview/llstartuplistener.cpp
@@ -35,7 +35,7 @@
// external library headers
// other Linden headers
#include "llstartup.h"
-
+#include "stringize.h"
LLStartupListener::LLStartupListener(/* LLStartUp* instance */):
LLEventAPI("LLStartUp", "Access e.g. LLStartup::postStartupState()") /* ,
@@ -43,9 +43,33 @@ LLStartupListener::LLStartupListener(/* LLStartUp* instance */):
{
add("postStartupState", "Refresh \"StartupState\" listeners with current startup state",
&LLStartupListener::postStartupState);
+ add("getStateTable", "Reply with array of EStartupState string names",
+ &LLStartupListener::getStateTable);
}
void LLStartupListener::postStartupState(const LLSD&) const
{
LLStartUp::postStartupState();
}
+
+void LLStartupListener::getStateTable(const LLSD& event) const
+{
+ Response response(LLSD(), event);
+
+ // This relies on our knowledge that STATE_STARTED is the very last
+ // EStartupState value. If that ever stops being true, we're going to lie
+ // without realizing it. I can think of no reliable way to test whether
+ // the enum has been extended *beyond* STATE_STARTED. We could, of course,
+ // test whether stuff has been inserted before it, by testing its
+ // numerical value against the constant value as of the last time we
+ // looked; but that's pointless, as values inserted before STATE_STARTED
+ // will continue to work fine. The bad case is if new symbols get added
+ // *after* it.
+ LLSD table;
+ // note <= comparison: we want to *include* STATE_STARTED.
+ for (LLSD::Integer istate{0}; istate <= LLSD::Integer(STATE_STARTED); ++istate)
+ {
+ table.append(LLStartUp::startupStateToString(EStartupState(istate)));
+ }
+ response["table"] = table;
+}
diff --git a/indra/newview/llstartuplistener.h b/indra/newview/llstartuplistener.h
index a35e11f6eb..0b4380a568 100644
--- a/indra/newview/llstartuplistener.h
+++ b/indra/newview/llstartuplistener.h
@@ -40,6 +40,7 @@ public:
private:
void postStartupState(const LLSD&) const;
+ void getStateTable(const LLSD&) const;
//LLStartup* mStartup;
};
diff --git a/indra/newview/lltexturestats.cpp b/indra/newview/lltexturestats.cpp
index b55b4d9ca4..8f4b7d000c 100644
--- a/indra/newview/lltexturestats.cpp
+++ b/indra/newview/lltexturestats.cpp
@@ -46,8 +46,8 @@ void send_texture_stats_to_sim(const LLSD &texture_stats)
LLUUID agent_id = gAgent.getID();
texture_stats_report["agent_id"] = agent_id;
texture_stats_report["region_id"] = gAgent.getRegion()->getRegionID();
- texture_stats_report["viewer_channel"] = LLVersionInfo::getChannel();
- texture_stats_report["viewer_version"] = LLVersionInfo::getVersion();
+ texture_stats_report["viewer_channel"] = LLVersionInfo::instance().getChannel();
+ texture_stats_report["viewer_version"] = LLVersionInfo::instance().getVersion();
texture_stats_report["stats_data"] = texture_stats;
std::string texture_cap_url = gAgent.getRegion()->getCapability("TextureStats");
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 870e0d94f0..bf56a10d4d 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -612,11 +612,8 @@ S32 LLToast::notifyParent(const LLSD& info)
//static
void LLToast::updateClass()
{
- for (LLInstanceTracker<LLToast>::instance_iter iter = LLInstanceTracker<LLToast>::beginInstances();
- iter != LLInstanceTracker<LLToast>::endInstances(); )
+ for (auto& toast : LLInstanceTracker<LLToast>::instance_snapshot())
{
- LLToast& toast = *iter++;
-
toast.updateHoveredState();
}
}
@@ -624,22 +621,6 @@ void LLToast::updateClass()
// static
void LLToast::cleanupToasts()
{
- LLToast * toastp = NULL;
-
- while (LLInstanceTracker<LLToast>::instanceCount() > 0)
- {
- { // Need to scope iter to allow deletion
- LLInstanceTracker<LLToast>::instance_iter iter = LLInstanceTracker<LLToast>::beginInstances();
- toastp = &(*iter);
- }
-
- //LL_INFOS() << "Cleaning up toast id " << toastp->getNotificationID() << LL_ENDL;
-
- // LLToast destructor will remove it from the LLInstanceTracker.
- if (!toastp)
- break; // Don't get stuck in the loop if a null pointer somehow got on the list
-
- delete toastp;
- }
+ LLInstanceTracker<LLToast>::instance_snapshot().deleteAll();
}
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index e424983cf8..fa3b44f702 100644
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -134,11 +134,11 @@ void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, std::
std::string user_agent = llformat("%s %d.%d.%d (%d)",
- LLVersionInfo::getChannel().c_str(),
- LLVersionInfo::getMajor(),
- LLVersionInfo::getMinor(),
- LLVersionInfo::getPatch(),
- LLVersionInfo::getBuild());
+ LLVersionInfo::instance().getChannel().c_str(),
+ LLVersionInfo::instance().getMajor(),
+ LLVersionInfo::instance().getMinor(),
+ LLVersionInfo::instance().getPatch(),
+ LLVersionInfo::instance().getBuild());
httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN);
httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
@@ -177,11 +177,11 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s
std::string user_agent = llformat("%s %d.%d.%d (%d)",
- LLVersionInfo::getChannel().c_str(),
- LLVersionInfo::getMajor(),
- LLVersionInfo::getMinor(),
- LLVersionInfo::getPatch(),
- LLVersionInfo::getBuild());
+ LLVersionInfo::instance().getChannel().c_str(),
+ LLVersionInfo::instance().getMajor(),
+ LLVersionInfo::instance().getMinor(),
+ LLVersionInfo::instance().getPatch(),
+ LLVersionInfo::instance().getBuild());
httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN);
httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp
index 4e07223784..4720a989b0 100644
--- a/indra/newview/llversioninfo.cpp
+++ b/indra/newview/llversioninfo.cpp
@@ -26,9 +26,10 @@
*/
#include "llviewerprecompiledheaders.h"
-#include <iostream>
-#include <sstream>
+#include "llevents.h"
+#include "lleventfilter.h"
#include "llversioninfo.h"
+#include "stringize.h"
#include <boost/regex.hpp>
#if ! defined(LL_VIEWER_CHANNEL) \
@@ -43,100 +44,90 @@
// Set the version numbers in indra/VIEWER_VERSION
//
-//static
+LLVersionInfo::LLVersionInfo():
+ short_version(STRINGIZE(LL_VIEWER_VERSION_MAJOR << "."
+ << LL_VIEWER_VERSION_MINOR << "."
+ << LL_VIEWER_VERSION_PATCH)),
+ // LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The
+ // macro expands to the string name of the channel, but without quotes. We
+ // need to turn it into a quoted string. LL_TO_STRING() does that.
+ mWorkingChannelName(LL_TO_STRING(LL_VIEWER_CHANNEL)),
+ build_configuration(LLBUILD_CONFIG), // set in indra/cmake/BuildVersion.cmake
+ // instantiate an LLEventMailDrop with canonical name to listen for news
+ // from SLVersionChecker
+ mPump{new LLEventMailDrop("relnotes")},
+ // immediately listen on mPump, store arriving URL into mReleaseNotes
+ mStore{new LLStoreListener<std::string>(*mPump, mReleaseNotes)}
+{
+}
+
+void LLVersionInfo::initSingleton()
+{
+ // We override initSingleton() not because we have dependencies on other
+ // LLSingletons, but because certain initializations call other member
+ // functions. We should refrain from calling methods until this object is
+ // fully constructed; such calls don't really belong in the constructor.
+
+ // cache the version string
+ version = STRINGIZE(getShortVersion() << "." << getBuild());
+}
+
+LLVersionInfo::~LLVersionInfo()
+{
+}
+
S32 LLVersionInfo::getMajor()
{
return LL_VIEWER_VERSION_MAJOR;
}
-//static
S32 LLVersionInfo::getMinor()
{
return LL_VIEWER_VERSION_MINOR;
}
-//static
S32 LLVersionInfo::getPatch()
{
return LL_VIEWER_VERSION_PATCH;
}
-//static
S32 LLVersionInfo::getBuild()
{
return LL_VIEWER_VERSION_BUILD;
}
-//static
-const std::string &LLVersionInfo::getVersion()
+std::string LLVersionInfo::getVersion()
{
- static std::string version("");
- if (version.empty())
- {
- std::ostringstream stream;
- stream << LLVersionInfo::getShortVersion() << "." << LLVersionInfo::getBuild();
- // cache the version string
- version = stream.str();
- }
return version;
}
-//static
-const std::string &LLVersionInfo::getShortVersion()
+std::string LLVersionInfo::getShortVersion()
{
- static std::string short_version("");
- if(short_version.empty())
- {
- // cache the version string
- std::ostringstream stream;
- stream << LL_VIEWER_VERSION_MAJOR << "."
- << LL_VIEWER_VERSION_MINOR << "."
- << LL_VIEWER_VERSION_PATCH;
- short_version = stream.str();
- }
return short_version;
}
-namespace
-{
- // LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The
- // macro expands to the string name of the channel, but without quotes. We
- // need to turn it into a quoted string. LL_TO_STRING() does that.
- /// Storage of the channel name the viewer is using.
- // The channel name is set by hardcoded constant,
- // or by calling LLVersionInfo::resetChannel()
- std::string sWorkingChannelName(LL_TO_STRING(LL_VIEWER_CHANNEL));
-
- // Storage for the "version and channel" string.
- // This will get reset too.
- std::string sVersionChannel("");
-}
-
-//static
-const std::string &LLVersionInfo::getChannelAndVersion()
+std::string LLVersionInfo::getChannelAndVersion()
{
- if (sVersionChannel.empty())
+ if (mVersionChannel.empty())
{
// cache the version string
- sVersionChannel = LLVersionInfo::getChannel() + " " + LLVersionInfo::getVersion();
+ mVersionChannel = getChannel() + " " + getVersion();
}
- return sVersionChannel;
+ return mVersionChannel;
}
-//static
-const std::string &LLVersionInfo::getChannel()
+std::string LLVersionInfo::getChannel()
{
- return sWorkingChannelName;
+ return mWorkingChannelName;
}
void LLVersionInfo::resetChannel(const std::string& channel)
{
- sWorkingChannelName = channel;
- sVersionChannel.clear(); // Reset version and channel string til next use.
+ mWorkingChannelName = channel;
+ mVersionChannel.clear(); // Reset version and channel string til next use.
}
-//static
LLVersionInfo::ViewerMaturity LLVersionInfo::getViewerMaturity()
{
ViewerMaturity maturity;
@@ -175,8 +166,12 @@ LLVersionInfo::ViewerMaturity LLVersionInfo::getViewerMaturity()
}
-const std::string &LLVersionInfo::getBuildConfig()
+std::string LLVersionInfo::getBuildConfig()
{
- static const std::string build_configuration(LLBUILD_CONFIG); // set in indra/cmake/BuildVersion.cmake
return build_configuration;
}
+
+std::string LLVersionInfo::getReleaseNotes()
+{
+ return mReleaseNotes;
+}
diff --git a/indra/newview/llversioninfo.h b/indra/newview/llversioninfo.h
index b8b4341385..02ff0c094a 100644
--- a/indra/newview/llversioninfo.h
+++ b/indra/newview/llversioninfo.h
@@ -28,8 +28,14 @@
#ifndef LL_LLVERSIONINFO_H
#define LL_LLVERSIONINFO_H
-#include <string>
#include "stdtypes.h"
+#include "llsingleton.h"
+#include <string>
+#include <memory>
+
+class LLEventMailDrop;
+template <typename T>
+class LLStoreListener;
///
/// This API provides version information for the viewer. This
@@ -38,42 +44,46 @@
/// viewer code that wants to query the current version should
/// use this API.
///
-class LLVersionInfo
+class LLVersionInfo: public LLSingleton<LLVersionInfo>
{
+ LLSINGLETON(LLVersionInfo);
+ void initSingleton();
public:
- /// return the major verion number as an integer
- static S32 getMajor();
+ ~LLVersionInfo();
- /// return the minor verion number as an integer
- static S32 getMinor();
+ /// return the major version number as an integer
+ S32 getMajor();
- /// return the patch verion number as an integer
- static S32 getPatch();
+ /// return the minor version number as an integer
+ S32 getMinor();
+
+ /// return the patch version number as an integer
+ S32 getPatch();
/// return the build number as an integer
- static S32 getBuild();
+ S32 getBuild();
/// return the full viewer version as a string like "2.0.0.200030"
- static const std::string &getVersion();
+ std::string getVersion();
/// return the viewer version as a string like "2.0.0"
- static const std::string &getShortVersion();
+ std::string getShortVersion();
/// return the viewer version and channel as a string
/// like "Second Life Release 2.0.0.200030"
- static const std::string &getChannelAndVersion();
+ std::string getChannelAndVersion();
/// return the channel name, e.g. "Second Life"
- static const std::string &getChannel();
+ std::string getChannel();
/// return the CMake build type
- static const std::string &getBuildConfig();
+ std::string getBuildConfig();
/// reset the channel name used by the viewer.
- static void resetChannel(const std::string& channel);
+ void resetChannel(const std::string& channel);
/// return the bit width of an address
- static const S32 getAddressSize() { return ADDRESS_SIZE; }
+ S32 getAddressSize() { return ADDRESS_SIZE; }
typedef enum
{
@@ -82,7 +92,31 @@ public:
BETA_VIEWER,
RELEASE_VIEWER
} ViewerMaturity;
- static ViewerMaturity getViewerMaturity();
+ ViewerMaturity getViewerMaturity();
+
+ /// get the release-notes URL, once it becomes available -- until then,
+ /// return empty string
+ std::string getReleaseNotes();
+
+private:
+ std::string version;
+ std::string short_version;
+ /// Storage of the channel name the viewer is using.
+ // The channel name is set by hardcoded constant,
+ // or by calling resetChannel()
+ std::string mWorkingChannelName;
+ // Storage for the "version and channel" string.
+ // This will get reset too.
+ std::string mVersionChannel;
+ std::string build_configuration;
+ std::string mReleaseNotes;
+ // Store unique_ptrs to the next couple things so we don't have to explain
+ // to every consumer of this header file all the details of each.
+ // mPump is the LLEventMailDrop on which we listen for SLVersionChecker to
+ // post the release-notes URL from the Viewer Version Manager.
+ std::unique_ptr<LLEventMailDrop> mPump;
+ // mStore is an adapter that stores the release-notes URL in mReleaseNotes.
+ std::unique_ptr<LLStoreListener<std::string>> mStore;
};
#endif
diff --git a/indra/newview/llviewercontrollistener.cpp b/indra/newview/llviewercontrollistener.cpp
index d2484b2b23..3443bb644a 100644
--- a/indra/newview/llviewercontrollistener.cpp
+++ b/indra/newview/llviewercontrollistener.cpp
@@ -50,11 +50,9 @@ LLViewerControlListener::LLViewerControlListener()
std::ostringstream groupnames;
groupnames << "[\"group\"] is one of ";
const char* delim = "";
- for (LLControlGroup::key_iter cgki(LLControlGroup::beginKeys()),
- cgkend(LLControlGroup::endKeys());
- cgki != cgkend; ++cgki)
+ for (const auto& key : LLControlGroup::key_snapshot())
{
- groupnames << delim << '"' << *cgki << '"';
+ groupnames << delim << '"' << key << '"';
delim = ", ";
}
groupnames << '\n';
@@ -181,11 +179,9 @@ void LLViewerControlListener::groups(LLSD const & request)
{
// No Info, we're not looking up either a group or a control name.
Response response(LLSD(), request);
- for (LLControlGroup::key_iter cgki(LLControlGroup::beginKeys()),
- cgkend(LLControlGroup::endKeys());
- cgki != cgkend; ++cgki)
+ for (const auto& key : LLControlGroup::key_snapshot())
{
- response["groups"].append(*cgki);
+ response["groups"].append(key);
}
}
diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp
index e44d80b7ce..3d06c95080 100644
--- a/indra/newview/llviewerjoystick.cpp
+++ b/indra/newview/llviewerjoystick.cpp
@@ -62,6 +62,43 @@ F32 LLViewerJoystick::sDelta[] = {0,0,0,0,0,0,0};
#define MAX_SPACENAVIGATOR_INPUT 3000.0f
#define MAX_JOYSTICK_INPUT_VALUE MAX_SPACENAVIGATOR_INPUT
+#if LIB_NDOF
+std::ostream& operator<<(std::ostream& out, NDOF_Device* ptr)
+{
+ if (! ptr)
+ {
+ return out << "nullptr";
+ }
+ out << "NDOF_Device{ ";
+ out << "axes [";
+ const char* delim = "";
+ for (short axis = 0; axis < ptr->axes_count; ++axis)
+ {
+ out << delim << ptr->axes[axis];
+ delim = ", ";
+ }
+ out << "]";
+ out << ", buttons [";
+ delim = "";
+ for (short button = 0; button < ptr->btn_count; ++button)
+ {
+ out << delim << ptr->buttons[button];
+ delim = ", ";
+ }
+ out << "]";
+ out << ", range " << ptr->axes_min << ':' << ptr->axes_max;
+ // If we don't coerce these to unsigned, they're streamed as characters,
+ // e.g. ctrl-A or nul.
+ out << ", absolute " << unsigned(ptr->absolute);
+ out << ", valid " << unsigned(ptr->valid);
+ out << ", manufacturer '" << ptr->manufacturer << "'";
+ out << ", product '" << ptr->product << "'";
+ out << ", private " << ptr->private_data;
+ out << " }";
+ return out;
+}
+#endif // LIB_NDOF
+
// -----------------------------------------------------------------------------
void LLViewerJoystick::updateEnabled(bool autoenable)
{
@@ -107,11 +144,11 @@ NDOF_HotPlugResult LLViewerJoystick::HotPlugAddCallback(NDOF_Device *dev)
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
if (joystick->mDriverState == JDS_UNINITIALIZED)
{
- LL_INFOS() << "HotPlugAddCallback: will use device:" << LL_ENDL;
- ndof_dump(dev);
+ LL_INFOS("joystick") << "HotPlugAddCallback: will use device:" << LL_ENDL;
+ ndof_dump(stderr, dev);
joystick->mNdofDev = dev;
- joystick->mDriverState = JDS_INITIALIZED;
- res = NDOF_KEEP_HOTPLUGGED;
+ joystick->mDriverState = JDS_INITIALIZED;
+ res = NDOF_KEEP_HOTPLUGGED;
}
joystick->updateEnabled(true);
return res;
@@ -125,9 +162,9 @@ void LLViewerJoystick::HotPlugRemovalCallback(NDOF_Device *dev)
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
if (joystick->mNdofDev == dev)
{
- LL_INFOS() << "HotPlugRemovalCallback: joystick->mNdofDev="
+ LL_INFOS("joystick") << "HotPlugRemovalCallback: joystick->mNdofDev="
<< joystick->mNdofDev << "; removed device:" << LL_ENDL;
- ndof_dump(dev);
+ ndof_dump(stderr, dev);
joystick->mDriverState = JDS_UNINITIALIZED;
}
joystick->updateEnabled(true);
@@ -193,6 +230,7 @@ void LLViewerJoystick::init(bool autoenable)
{
if (mNdofDev)
{
+ LL_DEBUGS("joystick") << "ndof_create() returned: " << mNdofDev << LL_ENDL;
// Different joysticks will return different ranges of raw values.
// Since we want to handle every device in the same uniform way,
// we initialize the mNdofDev struct and we set the range
@@ -211,16 +249,19 @@ void LLViewerJoystick::init(bool autoenable)
// just have the absolute values instead.
mNdofDev->absolute = 1;
+ LL_DEBUGS("joystick") << "ndof_init_first() received: " << mNdofDev << LL_ENDL;
// init & use the first suitable NDOF device found on the USB chain
if (ndof_init_first(mNdofDev, NULL))
{
mDriverState = JDS_UNINITIALIZED;
- LL_WARNS() << "ndof_init_first FAILED" << LL_ENDL;
+ LL_WARNS("joystick") << "ndof_init_first FAILED" << LL_ENDL;
+ ndof_dump_list(stderr);
}
else
{
mDriverState = JDS_INITIALIZED;
}
+ LL_DEBUGS("joystick") << "ndof_init_first() left: " << mNdofDev << LL_ENDL;
}
else
{
@@ -258,8 +299,8 @@ void LLViewerJoystick::init(bool autoenable)
{
// No device connected, don't change any settings
}
-
- LL_INFOS() << "ndof: mDriverState=" << mDriverState << "; mNdofDev="
+
+ LL_INFOS("joystick") << "ndof: mDriverState=" << mDriverState << "; mNdofDev="
<< mNdofDev << "; libinit=" << libinit << LL_ENDL;
#endif
}
@@ -270,7 +311,7 @@ void LLViewerJoystick::terminate()
#if LIB_NDOF
ndof_libcleanup();
- LL_INFOS() << "Terminated connection with NDOF device." << LL_ENDL;
+ LL_INFOS("joystick") << "Terminated connection with NDOF device." << LL_ENDL;
mDriverState = JDS_UNINITIALIZED;
#endif
}
@@ -1075,7 +1116,7 @@ std::string LLViewerJoystick::getDescription()
bool LLViewerJoystick::isLikeSpaceNavigator() const
{
-#if LIB_NDOF
+#if LIB_NDOF
return (isJoystickInitialized()
&& (strncmp(mNdofDev->product, "SpaceNavigator", 14) == 0
|| strncmp(mNdofDev->product, "SpaceExplorer", 13) == 0
@@ -1099,10 +1140,10 @@ void LLViewerJoystick::setSNDefaults()
const float platformScaleAvXZ = 2.f;
const bool is_3d_cursor = true;
#endif
-
+
//gViewerWindow->alertXml("CacheWillClear");
- LL_INFOS() << "restoring SpaceNavigator defaults..." << LL_ENDL;
-
+ LL_INFOS("joystick") << "restoring SpaceNavigator defaults..." << LL_ENDL;
+
gSavedSettings.setS32("JoystickAxis0", 1); // z (at)
gSavedSettings.setS32("JoystickAxis1", 0); // x (slide)
gSavedSettings.setS32("JoystickAxis2", 2); // y (up)
@@ -1110,11 +1151,11 @@ void LLViewerJoystick::setSNDefaults()
gSavedSettings.setS32("JoystickAxis4", 3); // roll
gSavedSettings.setS32("JoystickAxis5", 5); // yaw
gSavedSettings.setS32("JoystickAxis6", -1);
-
+
gSavedSettings.setBOOL("Cursor3D", is_3d_cursor);
gSavedSettings.setBOOL("AutoLeveling", true);
gSavedSettings.setBOOL("ZoomDirect", false);
-
+
gSavedSettings.setF32("AvatarAxisScale0", 1.f * platformScaleAvXZ);
gSavedSettings.setF32("AvatarAxisScale1", 1.f * platformScaleAvXZ);
gSavedSettings.setF32("AvatarAxisScale2", 1.f);
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index ed5dff1600..e31dfb29c7 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -412,7 +412,7 @@ std::string LLViewerMedia::getCurrentUserAgent()
// Just in case we need to check browser differences in A/B test
// builds.
- std::string channel = LLVersionInfo::getChannel();
+ std::string channel = LLVersionInfo::instance().getChannel();
// append our magic version number string to the browser user agent id
// See the HTTP 1.0 and 1.1 specifications for allowed formats:
@@ -422,7 +422,7 @@ std::string LLViewerMedia::getCurrentUserAgent()
// http://www.mozilla.org/build/revised-user-agent-strings.html
std::ostringstream codec;
codec << "SecondLife/";
- codec << LLVersionInfo::getVersion();
+ codec << LLVersionInfo::instance().getVersion();
codec << " (" << channel << "; " << skin_name << " skin)";
LL_INFOS() << codec.str() << LL_ENDL;
diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h
index 999d9092bd..bbbacce8fa 100644
--- a/indra/newview/llviewerprecompiledheaders.h
+++ b/indra/newview/llviewerprecompiledheaders.h
@@ -29,6 +29,8 @@
#ifndef LL_LLVIEWERPRECOMPILEDHEADERS_H
#define LL_LLVIEWERPRECOMPILEDHEADERS_H
+#include "llwin32headers.h"
+
// This file MUST be the first one included by each .cpp file
// in viewer.
// It is used to precompile headers for improved build speed.
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 85d87a43af..0f58933005 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -473,7 +473,7 @@ void send_stats()
// send fps only for time app spends in foreground
agent["fps"] = (F32)gForegroundFrameCount / gForegroundTime.getElapsedTimeF32();
- agent["version"] = LLVersionInfo::getChannelAndVersion();
+ agent["version"] = LLVersionInfo::instance().getChannelAndVersion();
std::string language = LLUI::getLanguage();
agent["language"] = language;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 44d02b4224..5dd3270b2e 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2498,7 +2498,7 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
}
else
{
- switch (LLVersionInfo::getViewerMaturity())
+ switch (LLVersionInfo::instance().getViewerMaturity())
{
case LLVersionInfo::TEST_VIEWER:
new_bg_color = LLUIColorTable::instance().getColor( "MenuBarTestBgColor" );
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 530adb8975..42a1cf95a7 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -338,15 +338,15 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
mPlayRequestCount(0),
mAvatarNameCacheConnection(),
- mIsInTuningMode(false),
- mIsInChannel(false),
- mIsJoiningSession(false),
- mIsWaitingForFonts(false),
- mIsLoggingIn(false),
- mIsLoggedIn(false),
- mIsProcessingChannels(false),
- mIsCoroutineActive(false),
- mVivoxPump("vivoxClientPump")
+ mIsInTuningMode(false),
+ mIsInChannel(false),
+ mIsJoiningSession(false),
+ mIsWaitingForFonts(false),
+ mIsLoggingIn(false),
+ mIsLoggedIn(false),
+ mIsProcessingChannels(false),
+ mIsCoroutineActive(false),
+ mVivoxPump("vivoxClientPump")
{
mSpeakerVolume = scale_speaker_volume(0);
@@ -390,7 +390,7 @@ void LLVivoxVoiceClient::init(LLPumpIO *pump)
// constructor will set up LLVoiceClient::getInstance()
LLVivoxVoiceClient::getInstance()->mPump = pump;
-// LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro();",
+// LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro",
// boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance()));
}
@@ -527,7 +527,7 @@ void LLVivoxVoiceClient::connectorCreate()
<< "<FileNameSuffix>.log</FileNameSuffix>"
<< "<LogLevel>" << vivoxLogLevel << "</LogLevel>"
<< "</Logging>"
- << "<Application>" << LLVersionInfo::getChannel().c_str() << " " << LLVersionInfo::getVersion().c_str() << "</Application>"
+ << "<Application>" << LLVersionInfo::instance().getChannel() << " " << LLVersionInfo::instance().getVersion() << "</Application>"
//<< "<Application></Application>" //Name can cause problems per vivox.
<< "<MaxCalls>12</MaxCalls>"
<< "</Request>\n\n\n";
@@ -806,6 +806,21 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
LLProcess::Params params;
params.executable = exe_path;
+ // VOICE-88: Cycle through [portbase..portbase+portrange) on
+ // successive tries because attempting to relaunch (after manually
+ // disabling and then re-enabling voice) with the same port can
+ // cause SLVoice's bind() call to fail with EADDRINUSE. We expect
+ // that eventually the OS will time out previous ports, which is
+ // why we cycle instead of incrementing indefinitely.
+ U32 portbase = gSavedSettings.getU32("VivoxVoicePort");
+ static U32 portoffset = 0;
+ static const U32 portrange = 100;
+ std::string host(gSavedSettings.getString("VivoxVoiceHost"));
+ U32 port = portbase + portoffset;
+ portoffset = (portoffset + 1) % portrange;
+ params.args.add("-i");
+ params.args.add(STRINGIZE(host << ':' << port));
+
std::string loglevel = gSavedSettings.getString("VivoxDebugLevel");
if (loglevel.empty())
{
@@ -862,7 +877,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
sGatewayPtr = LLProcess::create(params);
- mDaemonHost = LLHost(gSavedSettings.getString("VivoxVoiceHost").c_str(), gSavedSettings.getU32("VivoxVoicePort"));
+ mDaemonHost = LLHost(host.c_str(), port);
}
else
{
@@ -1038,8 +1053,6 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
bool LLVivoxVoiceClient::establishVoiceConnection()
{
- LLEventPump &voiceConnectPump = LLEventPumps::instance().obtain("vivoxClientPump");
-
if (!mVoiceEnabled && mIsInitialized)
{
LL_WARNS("Voice") << "cannot establish connection; enabled "<<mVoiceEnabled<<" initialized "<<mIsInitialized<<LL_ENDL;
@@ -1056,7 +1069,7 @@ bool LLVivoxVoiceClient::establishVoiceConnection()
connectorCreate();
do
{
- result = llcoro::suspendUntilEventOn(voiceConnectPump);
+ result = llcoro::suspendUntilEventOn(mVivoxPump);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
if (result.has("connector"))
@@ -1108,7 +1121,6 @@ bool LLVivoxVoiceClient::establishVoiceConnection()
bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait)
{
LL_DEBUGS("Voice") << "( wait=" << corowait << ")" << LL_ENDL;
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
bool retval(true);
mShutdownComplete = false;
@@ -1118,7 +1130,7 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait)
{
LLSD timeoutResult(LLSDMap("connector", "timeout"));
- LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
+ LLSD result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
retval = result.has("connector");
@@ -1140,7 +1152,7 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait)
{
mConnected = false;
LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false)));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
}
mShutdownComplete = true;
}
@@ -1157,8 +1169,6 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait)
bool LLVivoxVoiceClient::loginToVivox()
{
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
-
LLSD timeoutResult(LLSDMap("login", "timeout"));
int loginRetryCount(0);
@@ -1176,7 +1186,7 @@ bool LLVivoxVoiceClient::loginToVivox()
send_login = false;
}
- LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult);
+ LLSD result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
if (result.has("login"))
@@ -1259,17 +1269,23 @@ void LLVivoxVoiceClient::logoutOfVivox(bool wait)
if (wait)
{
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
LLSD timeoutResult(LLSDMap("logout", "timeout"));
+ LLSD result;
- LL_DEBUGS("Voice")
- << "waiting for logout response on "
- << voicePump.getName()
- << LL_ENDL;
-
- LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
-
- LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
+ do
+ {
+ LL_DEBUGS("Voice")
+ << "waiting for logout response on "
+ << mVivoxPump.getName()
+ << LL_ENDL;
+
+ result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
+
+ LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
+ // Don't get confused by prior queued events -- note that it's
+ // very important that mVivoxPump is an LLEventMailDrop, which
+ // does queue events.
+ } while (! result["logout"]);
}
else
{
@@ -1283,8 +1299,6 @@ void LLVivoxVoiceClient::logoutOfVivox(bool wait)
bool LLVivoxVoiceClient::retrieveVoiceFonts()
{
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
-
// Request the set of available voice fonts.
refreshVoiceEffectLists(true);
@@ -1292,7 +1306,7 @@ bool LLVivoxVoiceClient::retrieveVoiceFonts()
LLSD result;
do
{
- result = llcoro::suspendUntilEventOn(voicePump);
+ result = llcoro::suspendUntilEventOn(mVivoxPump);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
if (result.has("voice_fonts"))
@@ -1408,7 +1422,6 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo()
bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
{
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
mIsJoiningSession = true;
sessionStatePtr_t oldSession = mAudioSession;
@@ -1497,7 +1510,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
// We are about to start a whole new session. Anything that MIGHT still be in our
// maildrop is going to be stale and cause us much wailing and gnashing of teeth.
// Just flush it all out and start new.
- voicePump.flush();
+ mVivoxPump.discard();
// It appears that I need to wait for BOTH the SessionGroup.AddSession response and the SessionStateChangeEvent with state 4
// before continuing from this state. They can happen in either order, and if I don't wait for both, things can get stuck.
@@ -1505,7 +1518,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
// This is a cheap way to make sure both have happened before proceeding.
do
{
- result = llcoro::suspendUntilEventOnWithTimeout(voicePump, SESSION_JOIN_TIMEOUT, timeoutResult);
+ result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, SESSION_JOIN_TIMEOUT, timeoutResult);
LL_INFOS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
if (result.has("session"))
@@ -1619,13 +1632,12 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
if (wait)
{
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
LLSD result;
do
{
LLSD timeoutResult(LLSDMap("session", "timeout"));
- result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
+ result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
if (result.has("session"))
@@ -1822,7 +1834,6 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
LLSD timeoutEvent(LLSDMap("timeout", LLSD::Boolean(true)));
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
mIsInChannel = true;
mMuteMicDirty = true;
@@ -1874,7 +1885,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
sendLocalAudioUpdates();
mIsInitialized = true;
- LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, UPDATE_THROTTLE_SECONDS, timeoutEvent);
+ LLSD result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, UPDATE_THROTTLE_SECONDS, timeoutEvent);
if (!result.has("timeout")) // logging the timeout event spams the log
{
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
@@ -1945,14 +1956,13 @@ void LLVivoxVoiceClient::sendCaptureAndRenderDevices()
void LLVivoxVoiceClient::recordingAndPlaybackMode()
{
LL_INFOS("Voice") << "In voice capture/playback mode." << LL_ENDL;
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
while (true)
{
LLSD command;
do
{
- command = llcoro::suspendUntilEventOn(voicePump);
+ command = llcoro::suspendUntilEventOn(mVivoxPump);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(command) << LL_ENDL;
} while (!command.has("recplay"));
@@ -1985,7 +1995,6 @@ int LLVivoxVoiceClient::voiceRecordBuffer()
LL_INFOS("Voice") << "Recording voice buffer" << LL_ENDL;
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
LLSD result;
captureBufferRecordStartSendMessage();
@@ -1993,7 +2002,7 @@ int LLVivoxVoiceClient::voiceRecordBuffer()
do
{
- result = llcoro::suspendUntilEventOnWithTimeout(voicePump, CAPTURE_BUFFER_MAX_TIME, timeoutResult);
+ result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, CAPTURE_BUFFER_MAX_TIME, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
} while (!result.has("recplay"));
@@ -2015,7 +2024,6 @@ int LLVivoxVoiceClient::voicePlaybackBuffer()
LL_INFOS("Voice") << "Playing voice buffer" << LL_ENDL;
- LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump");
LLSD result;
do
@@ -2030,7 +2038,7 @@ int LLVivoxVoiceClient::voicePlaybackBuffer()
// Update UI, should really use a separate callback.
notifyVoiceFontObservers();
- result = llcoro::suspendUntilEventOnWithTimeout(voicePump, CAPTURE_BUFFER_MAX_TIME, timeoutResult);
+ result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, CAPTURE_BUFFER_MAX_TIME, timeoutResult);
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
} while (!result.has("recplay"));
@@ -2551,7 +2559,7 @@ void LLVivoxVoiceClient::tuningStart()
mTuningMode = true;
if (!mIsCoroutineActive)
{
- LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro();",
+ LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro",
boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance()));
}
else if (mIsInChannel)
@@ -3214,7 +3222,7 @@ void LLVivoxVoiceClient::connectorCreateResponse(int statusCode, std::string &st
result["connector"] = LLSD::Boolean(false);
}
- LLEventPumps::instance().post("vivoxClientPump", result);
+ mVivoxPump.post(result);
}
void LLVivoxVoiceClient::loginResponse(int statusCode, std::string &statusString, std::string &accountHandle, int numberOfAliases)
@@ -3244,7 +3252,7 @@ void LLVivoxVoiceClient::loginResponse(int statusCode, std::string &statusString
result["login"] = LLSD::String("response_ok");
}
- LLEventPumps::instance().post("vivoxClientPump", result);
+ mVivoxPump.post(result);
}
@@ -3270,7 +3278,7 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu
("session", "failed")
("reason", LLSD::Integer(statusCode)));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
}
else
{
@@ -3288,7 +3296,7 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu
LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
("session", "created"));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
}
}
@@ -3313,7 +3321,7 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId,
LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
("session", "failed"));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
}
else
{
@@ -3332,7 +3340,7 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId,
LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle))
("session", "added"));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
}
}
@@ -3375,7 +3383,7 @@ void LLVivoxVoiceClient::logoutResponse(int statusCode, std::string &statusStrin
}
LLSD vivoxevent(LLSDMap("logout", LLSD::Boolean(true)));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
}
void LLVivoxVoiceClient::connectorShutdownResponse(int statusCode, std::string &statusString)
@@ -3391,7 +3399,7 @@ void LLVivoxVoiceClient::connectorShutdownResponse(int statusCode, std::string &
LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false)));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
}
void LLVivoxVoiceClient::sessionAddedEvent(
@@ -3500,7 +3508,7 @@ void LLVivoxVoiceClient::joinedAudioSession(const sessionStatePtr_t &session)
LLSD vivoxevent(LLSDMap("handle", LLSD::String(session->mHandle))
("session", "joined"));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
// Add the current user as a participant here.
participantStatePtr_t participant(session->addParticipant(sipURIFromName(mAccountName)));
@@ -3644,7 +3652,7 @@ void LLVivoxVoiceClient::leftAudioSession(const sessionStatePtr_t &session)
LLSD vivoxevent(LLSDMap("handle", LLSD::String(session->mHandle))
("session", "removed"));
- LLEventPumps::instance().post("vivoxClientPump", vivoxevent);
+ mVivoxPump.post(vivoxevent);
}
}
@@ -3672,7 +3680,7 @@ void LLVivoxVoiceClient::accountLoginStateChangeEvent(
case 1:
levent["login"] = LLSD::String("account_login");
- LLEventPumps::instance().post("vivoxClientPump", levent);
+ mVivoxPump.post(levent);
break;
case 2:
break;
@@ -3680,7 +3688,7 @@ void LLVivoxVoiceClient::accountLoginStateChangeEvent(
case 3:
levent["login"] = LLSD::String("account_loggingOut");
- LLEventPumps::instance().post("vivoxClientPump", levent);
+ mVivoxPump.post(levent);
break;
case 4:
@@ -3693,7 +3701,7 @@ void LLVivoxVoiceClient::accountLoginStateChangeEvent(
case 0:
levent["login"] = LLSD::String("account_logout");
- LLEventPumps::instance().post("vivoxClientPump", levent);
+ mVivoxPump.post(levent);
break;
default:
@@ -3728,7 +3736,7 @@ void LLVivoxVoiceClient::mediaCompletionEvent(std::string &sessionGroupHandle, s
}
if (!result.isUndefined())
- LLEventPumps::instance().post("vivoxClientPump", result);
+ mVivoxPump.post(result);
}
void LLVivoxVoiceClient::mediaStreamUpdatedEvent(
@@ -5146,7 +5154,7 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)
if (!mIsCoroutineActive)
{
- LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro();",
+ LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro",
boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance()));
}
else
@@ -6541,7 +6549,7 @@ void LLVivoxVoiceClient::accountGetSessionFontsResponse(int statusCode, const st
// receiving the last one.
LLSD result(LLSDMap("voice_fonts", LLSD::Boolean(true)));
- LLEventPumps::instance().post("vivoxClientPump", result);
+ mVivoxPump.post(result);
}
notifyVoiceFontObservers();
mVoiceFontsReceived = true;
@@ -6692,7 +6700,7 @@ void LLVivoxVoiceClient::enablePreviewBuffer(bool enable)
else
result["recplay"] = "quit";
- LLEventPumps::instance().post("vivoxClientPump", result);
+ mVivoxPump.post(result);
if(mCaptureBufferMode && mIsInChannel)
{
@@ -6713,7 +6721,7 @@ void LLVivoxVoiceClient::recordPreviewBuffer()
mCaptureBufferRecording = true;
LLSD result(LLSDMap("recplay", "record"));
- LLEventPumps::instance().post("vivoxClientPump", result);
+ mVivoxPump.post(result);
}
void LLVivoxVoiceClient::playPreviewBuffer(const LLUUID& effect_id)
@@ -6736,7 +6744,7 @@ void LLVivoxVoiceClient::playPreviewBuffer(const LLUUID& effect_id)
mCaptureBufferPlaying = true;
LLSD result(LLSDMap("recplay", "playback"));
- LLEventPumps::instance().post("vivoxClientPump", result);
+ mVivoxPump.post(result);
}
void LLVivoxVoiceClient::stopPreviewBuffer()
@@ -6745,7 +6753,7 @@ void LLVivoxVoiceClient::stopPreviewBuffer()
mCaptureBufferPlaying = false;
LLSD result(LLSDMap("recplay", "quit"));
- LLEventPumps::instance().post("vivoxClientPump", result);
+ mVivoxPump.post(result);
}
bool LLVivoxVoiceClient::isPreviewRecording()
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 2ffd462ac3..f6669c44e5 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -2063,7 +2063,7 @@ void LLVOVolume::setNumTEs(const U8 num_tes)
}
else if(old_num_tes > num_tes && mMediaImplList.size() > num_tes) //old faces removed
{
- U8 end = mMediaImplList.size() ;
+ U8 end = (U8)(mMediaImplList.size()) ;
for(U8 i = num_tes; i < end ; i++)
{
removeMediaImpl(i) ;
diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp
index dd6c77ca7d..6273f10c69 100644
--- a/indra/newview/llwatchdog.cpp
+++ b/indra/newview/llwatchdog.cpp
@@ -91,7 +91,11 @@ void LLWatchdogEntry::start()
void LLWatchdogEntry::stop()
{
- LLWatchdog::getInstance()->remove(this);
+ // this can happen very late in the shutdown sequence
+ if (! LLWatchdog::wasDeleted())
+ {
+ LLWatchdog::getInstance()->remove(this);
+ }
}
// LLWatchdogTimeout
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index a34c5826ed..63257d6543 100644
--- a/indra/newview/llweb.cpp
+++ b/indra/newview/llweb.cpp
@@ -157,12 +157,12 @@ std::string LLWeb::expandURLSubstitutions(const std::string &url,
const LLSD &default_subs)
{
LLSD substitution = default_subs;
- substitution["VERSION"] = LLVersionInfo::getVersion();
- substitution["VERSION_MAJOR"] = LLVersionInfo::getMajor();
- substitution["VERSION_MINOR"] = LLVersionInfo::getMinor();
- substitution["VERSION_PATCH"] = LLVersionInfo::getPatch();
- substitution["VERSION_BUILD"] = LLVersionInfo::getBuild();
- substitution["CHANNEL"] = LLVersionInfo::getChannel();
+ substitution["VERSION"] = LLVersionInfo::instance().getVersion();
+ substitution["VERSION_MAJOR"] = LLVersionInfo::instance().getMajor();
+ substitution["VERSION_MINOR"] = LLVersionInfo::instance().getMinor();
+ substitution["VERSION_PATCH"] = LLVersionInfo::instance().getPatch();
+ substitution["VERSION_BUILD"] = LLVersionInfo::instance().getBuild();
+ substitution["CHANNEL"] = LLVersionInfo::instance().getChannel();
substitution["GRID"] = LLGridManager::getInstance()->getGridId();
substitution["GRID_LOWERCASE"] = utf8str_tolower(LLGridManager::getInstance()->getGridId());
substitution["OS"] = LLOSInfo::instance().getOSStringSimple();
diff --git a/indra/newview/llwindebug.h b/indra/newview/llwindebug.h
index 7e5818ba1c..524adba652 100644
--- a/indra/newview/llwindebug.h
+++ b/indra/newview/llwindebug.h
@@ -29,7 +29,11 @@
#include "stdtypes.h"
#include "llwin32headerslean.h"
+
+#pragma warning (push)
+#pragma warning (disable:4091) // a microsoft header has warnings. Very nice.
#include <dbghelp.h>
+#pragma warning (pop)
class LLWinDebug:
public LLSingleton<LLWinDebug>
diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp
index 0693d08dfb..663a75156f 100644
--- a/indra/newview/llxmlrpclistener.cpp
+++ b/indra/newview/llxmlrpclistener.cpp
@@ -43,6 +43,7 @@
// other Linden headers
#include "llerror.h"
+#include "lleventcoro.h"
#include "stringize.h"
#include "llxmlrpctransaction.h"
#include "llsecapi.h"
@@ -366,6 +367,8 @@ public:
// whether successful or not, send reply on requested LLEventPump
replyPump.post(data);
+ // need to wake up the loginCoro now
+ llcoro::suspend();
// Because mTransaction is a boost::scoped_ptr, deleting this object
// frees our LLXMLRPCTransaction object.
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 8a91a1f721..05fd1947fe 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4016,6 +4016,8 @@ Finished download of raw terrain file to:
[DOWNLOAD_PATH].
</notification>
+ <!-- RequiredUpdate does not display release notes URL because we don't get
+ that from login.cgi's login failure message. -->
<notification
icon="alertmodal.tga"
name="RequiredUpdate"
@@ -4033,6 +4035,7 @@ Please download from https://secondlife.com/support/downloads/
name="PauseForUpdate"
type="alertmodal">
Version [VERSION] is required for login.
+Release notes: [URL]
Click OK to download and install.
<tag>confirm</tag>
<usetemplate
@@ -4045,6 +4048,7 @@ Click OK to download and install.
name="OptionalUpdateReady"
type="alertmodal">
Version [VERSION] has been downloaded and is ready to install.
+Release notes: [URL]
Click OK to install.
<tag>confirm</tag>
<usetemplate
@@ -4057,6 +4061,7 @@ Click OK to install.
name="PromptOptionalUpdate"
type="alertmodal">
Version [VERSION] has been downloaded and is ready to install.
+Release notes: [URL]
Proceed?
<tag>confirm</tag>
<usetemplate
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index 2edad30493..57f2d31eab 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -202,8 +202,6 @@ void LLUIColorTable::saveUserSettings(void)const {}
//-----------------------------------------------------------------------------
#include "../llversioninfo.h"
-const std::string &LLVersionInfo::getVersion() { return VIEWERLOGIN_VERSION; }
-const std::string &LLVersionInfo::getChannel() { return VIEWERLOGIN_CHANNEL; }
bool llHashedUniqueID(unsigned char* id)
{
diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp
index 58f0469552..51a6f8f113 100644
--- a/indra/newview/tests/llversioninfo_test.cpp
+++ b/indra/newview/tests/llversioninfo_test.cpp
@@ -83,39 +83,39 @@ namespace tut
void versioninfo_object_t::test<1>()
{
std::cout << "What we parsed from CMake: " << LL_VIEWER_VERSION_BUILD << std::endl;
- std::cout << "What we get from llversioninfo: " << LLVersionInfo::getBuild() << std::endl;
+ std::cout << "What we get from llversioninfo: " << LLVersionInfo::instance().getBuild() << std::endl;
ensure_equals("Major version",
- LLVersionInfo::getMajor(),
+ LLVersionInfo::instance().getMajor(),
LL_VIEWER_VERSION_MAJOR);
ensure_equals("Minor version",
- LLVersionInfo::getMinor(),
+ LLVersionInfo::instance().getMinor(),
LL_VIEWER_VERSION_MINOR);
ensure_equals("Patch version",
- LLVersionInfo::getPatch(),
+ LLVersionInfo::instance().getPatch(),
LL_VIEWER_VERSION_PATCH);
ensure_equals("Build version",
- LLVersionInfo::getBuild(),
+ LLVersionInfo::instance().getBuild(),
LL_VIEWER_VERSION_BUILD);
ensure_equals("Channel version",
- LLVersionInfo::getChannel(),
+ LLVersionInfo::instance().getChannel(),
ll_viewer_channel);
ensure_equals("Version String",
- LLVersionInfo::getVersion(),
+ LLVersionInfo::instance().getVersion(),
mVersion);
ensure_equals("Short Version String",
- LLVersionInfo::getShortVersion(),
+ LLVersionInfo::instance().getShortVersion(),
mShortVersion);
ensure_equals("Version and channel String",
- LLVersionInfo::getChannelAndVersion(),
+ LLVersionInfo::instance().getChannelAndVersion(),
mVersionAndChannel);
- LLVersionInfo::resetChannel(mResetChannel);
+ LLVersionInfo::instance().resetChannel(mResetChannel);
ensure_equals("Reset channel version",
- LLVersionInfo::getChannel(),
+ LLVersionInfo::instance().getChannel(),
mResetChannel);
ensure_equals("Reset Version and channel String",
- LLVersionInfo::getChannelAndVersion(),
+ LLVersionInfo::instance().getChannelAndVersion(),
mResetVersionAndChannel);
}
}
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index b385717dbe..f5edde1923 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -528,12 +528,8 @@ class WindowsManifest(ViewerManifest):
# These need to be installed as a SxS assembly, currently a 'private' assembly.
# See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx
- if self.args['configuration'].lower() == 'debug':
- self.path("msvcr120d.dll")
- self.path("msvcp120d.dll")
- else:
- self.path("msvcr120.dll")
- self.path("msvcp120.dll")
+ self.path("msvcp140.dll")
+ self.path("vcruntime140.dll")
# SLVoice executable
with self.prefix(src=os.path.join(pkgdir, 'bin', 'release')):
@@ -605,8 +601,8 @@ class WindowsManifest(ViewerManifest):
# MSVC DLLs needed for CEF and have to be in same directory as plugin
with self.prefix(src=os.path.join(self.args['build'], os.pardir,
'sharedlibs', 'Release')):
- self.path("msvcp120.dll")
- self.path("msvcr120.dll")
+ self.path("msvcp140.dll")
+ self.path("vcruntime140.dll")
# CEF files common to all configurations
with self.prefix(src=os.path.join(pkgdir, 'resources')):
@@ -956,7 +952,7 @@ class DarwinManifest(ViewerManifest):
with self.prefix(src=relpkgdir, dst=""):
self.path("libndofdev.dylib")
- self.path("libhunspell-1.3.a")
+ self.path("libhunspell-*.dylib")
with self.prefix(src_dst="cursors_mac"):
self.path("*.tif")
@@ -1215,11 +1211,6 @@ class DarwinManifest(ViewerManifest):
devfile = re.search("/dev/disk([0-9]+)[^s]", hdi_output).group(0).strip()
volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip()
- if devfile != '/dev/disk1':
- # adding more debugging info based upon nat's hunches to the
- # logs to help track down 'SetFile -a V' failures -brad
- print "WARNING: 'SetFile -a V' command below is probably gonna fail"
-
# Copy everything in to the mounted .dmg
app_name = self.app_name()
@@ -1247,21 +1238,6 @@ class DarwinManifest(ViewerManifest):
# Hide the background image, DS_Store file, and volume icon file (set their "visible" bit)
for f in ".VolumeIcon.icns", "background.jpg", ".DS_Store":
pathname = os.path.join(volpath, f)
- # We've observed mysterious "no such file" failures of the SetFile
- # command, especially on the first file listed above -- yet
- # subsequent inspection of the target directory confirms it's
- # there. Timing problem with copy command? Try to handle.
- for x in xrange(3):
- if os.path.exists(pathname):
- print "Confirmed existence: %r" % pathname
- break
- print "Waiting for %s copy command to complete (%s)..." % (f, x+1)
- sys.stdout.flush()
- time.sleep(1)
- # If we fall out of the loop above without a successful break, oh
- # well, possibly we've mistaken the nature of the problem. In any
- # case, don't hang up the whole build looping indefinitely, let
- # the original problem manifest by executing the desired command.
self.run_command(['SetFile', '-a', 'V', pathname])
# Create the alias file (which is a resource file) from the .r
@@ -1564,6 +1540,11 @@ class Linux_x86_64_Manifest(LinuxManifest):
################################################################
if __name__ == "__main__":
+ # Report our own command line so that, in case of trouble, a developer can
+ # manually rerun the same command.
+ print('%s \\\n%s' %
+ (sys.executable,
+ ' '.join((("'%s'" % arg) if ' ' in arg else arg) for arg in sys.argv)))
extra_arguments = [
dict(name='bugsplat', description="""BugSplat database to which to post crashes,
if BugSplat crash reporting is desired""", default=''),