diff options
| author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2020-07-20 22:24:10 +0300 | 
|---|---|---|
| committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2020-07-20 22:24:10 +0300 | 
| commit | 7bbf3f5f7f37330281d36ca087fe7091c2492ebe (patch) | |
| tree | c926a151f950e24207c75e9764280b58daccf017 /indra/newview | |
| parent | bbee0658c3a7837e47d171dacfda55cac803e3ed (diff) | |
| parent | 72423372d6cd7f763a5567ad75752fa4e7131d60 (diff) | |
Merge branch 'master' into DRTVWR-501-maint
# Conflicts:
#	autobuild.xml
#	indra/newview/llimprocessing.cpp
Diffstat (limited to 'indra/newview')
40 files changed, 591 insertions, 505 deletions
| diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 33fa186a2e..88667bdc11 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) @@ -1583,20 +1582,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 @@ -1783,6 +1774,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. @@ -1801,12 +1797,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 @@ -1990,6 +1980,7 @@ endif (WINDOWS)  # modern version.  target_link_libraries(${VIEWER_BINARY_NAME} +    ${LEGACY_STDIO_LIBS}      ${PNG_PRELOAD_ARCHIVES}      ${ZLIB_PRELOAD_ARCHIVES}      ${URIPARSER_PRELOAD_ARCHIVES} @@ -2016,7 +2007,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} @@ -2450,6 +2441,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}"    ) @@ -2499,7 +2491,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 d2b7c9d85e..d9cc026c52 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; @@ -1168,7 +1168,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 @@ -1432,6 +1432,8 @@ bool LLAppViewer::doFrame()  		// canonical per-frame event  		mainloop.post(newFrame); +		// give listeners a chance to run +		llcoro::suspend();  		if (!LLApp::isExiting())  		{ @@ -1693,24 +1695,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 @@ -2131,25 +2118,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(); @@ -2662,7 +2643,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 @@ -2883,12 +2864,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. @@ -3108,16 +3088,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; @@ -3125,12 +3101,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(); @@ -3423,12 +3395,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(); @@ -3471,7 +3443,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; @@ -3693,7 +3665,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()<< ")" @@ -3710,7 +3682,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; @@ -4671,6 +4643,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(); @@ -5283,37 +5258,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) @@ -5571,12 +5549,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 722523830b..431a8c60be 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -1356,10 +1356,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 e038faecc9..702d612343 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 79cf49ddb1..e1b58dde51 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -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())                  { @@ -1619,6 +1617,7 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url)              from_group = message_data["from_group"].asString() == "Y";          } +          LLIMProcessing::processNewMessage(              message_data["from_agent_id"].asUUID(),              from_group, 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 602654971a..da21d5e69a 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -337,10 +337,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); @@ -946,9 +946,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 4c54d44ac5..3cd0932d9c 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -511,9 +511,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, @@ -1537,12 +1537,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;  	} @@ -1592,25 +1594,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(); @@ -2300,13 +2304,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 79081f3e02..c36d877a59 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 04172adde9..f7ded00318 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -472,7 +472,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 1fbb32ac5e..0cc1e0df06 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 a6500d1399..98eb2d3cdc 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2066,7 +2066,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 0daf3e761d..bae615232e 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 32ae56e3af..7e405cf0d0 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=''), | 
