summaryrefslogtreecommitdiff
path: root/indra/newview/llappviewer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llappviewer.cpp')
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewer.cpp2057
1 files changed, 1287 insertions, 770 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 53c694eaca..6dc71bc94e 100644..100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -30,7 +30,6 @@
// Viewer includes
#include "llversioninfo.h"
-#include "llversionviewer.h"
#include "llfeaturemanager.h"
#include "lluictrlfactory.h"
#include "lltexteditor.h"
@@ -41,6 +40,7 @@
#include "llagent.h"
#include "llagentcamera.h"
#include "llagentlanguage.h"
+#include "llagentui.h"
#include "llagentwearables.h"
#include "llfloaterimcontainer.h"
#include "llwindow.h"
@@ -61,8 +61,10 @@
#include "llcurl.h"
#include "llcalc.h"
#include "llconversationlog.h"
+#include "lldxhardware.h"
#include "lltexturestats.h"
-#include "lltexturestats.h"
+#include "lltrace.h"
+#include "lltracethreadrecorder.h"
#include "llviewerwindow.h"
#include "llviewerdisplay.h"
#include "llviewermedia.h"
@@ -76,10 +78,10 @@
#include "lluicolortable.h"
#include "llurldispatcher.h"
#include "llurlhistory.h"
-//#include "llfirstuse.h"
#include "llrender.h"
#include "llteleporthistory.h"
#include "lltoast.h"
+#include "llsdutil_math.h"
#include "lllocationhistory.h"
#include "llfasttimerview.h"
#include "llvector4a.h"
@@ -93,10 +95,12 @@
#include "llvocache.h"
#include "llvopartgroup.h"
#include "llweb.h"
-#include "llsecondlifeurls.h"
#include "llupdaterservice.h"
#include "llfloatertexturefetchdebugger.h"
#include "llspellcheck.h"
+#include "llscenemonitor.h"
+#include "llavatarrenderinfoaccountant.h"
+#include "lllocalbitmaps.h"
// Linden library includes
#include "llavatarnamecache.h"
@@ -118,17 +122,19 @@
#include "llleap.h"
#include "stringize.h"
+#include "llcoros.h"
// Third party library includes
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <boost/algorithm/string.hpp>
+#include <boost/regex.hpp>
#if LL_WINDOWS
-# include <share.h> // For _SH_DENYWR in initMarkerFile
+# include <share.h> // For _SH_DENYWR in processMarkerFiles
#else
-# include <sys/file.h> // For initMarkerFile support
+# include <sys/file.h> // For processMarkerFiles
#endif
#include "llapr.h"
@@ -221,6 +227,10 @@
#include "llmachineid.h"
#include "llmainlooprepeater.h"
+
+#include "llviewereventrecorder.h"
+
+
// *FIX: These extern globals should be cleaned up.
// The globals either represent state/config/resource-storage of either
// this app, or another 'component' of the viewer. App globals should be
@@ -252,6 +262,7 @@ static LLAppViewerListener sAppViewerListener(LLAppViewer::instance);
// viewer.cpp - these are only used in viewer, should be easily moved.
#if LL_DARWIN
+const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.indra.viewer";
extern void init_apple_menu(const char* product);
#endif // LL_DARWIN
@@ -269,6 +280,20 @@ BOOL gShowObjectUpdates = FALSE;
BOOL gUseQuickTime = TRUE;
eLastExecEvent gLastExecEvent = LAST_EXEC_NORMAL;
+S32 gLastExecDuration = -1; // (<0 indicates unknown)
+
+#if LL_WINDOWS
+# define LL_PLATFORM_KEY "win"
+#elif LL_DARWIN
+# define LL_PLATFORM_KEY "mac"
+#elif LL_LINUX
+# define LL_PLATFORM_KEY "lnx"
+#elif LL_SOLARIS
+# define LL_PLATFORM_KEY "sol"
+#else
+# error "Unknown Platform"
+#endif
+const char* gPlatform = LL_PLATFORM_KEY;
LLSD gDebugInfo;
@@ -276,12 +301,12 @@ U32 gFrameCount = 0;
U32 gForegroundFrameCount = 0; // number of frames that app window was in foreground
LLPumpIO* gServicePump = NULL;
-U64 gFrameTime = 0;
-F32 gFrameTimeSeconds = 0.f;
-F32 gFrameIntervalSeconds = 0.f;
+U64MicrosecondsImplicit gFrameTime = 0;
+F32SecondsImplicit gFrameTimeSeconds = 0.f;
+F32SecondsImplicit gFrameIntervalSeconds = 0.f;
F32 gFPSClamped = 10.f; // Pretend we start at target rate.
F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets
-U64 gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds
+U64MicrosecondsImplicit gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds
U32 gFrameStalls = 0;
const F64 FRAME_STALL_THRESHOLD = 1.0;
@@ -292,6 +317,10 @@ LLTimer gLogoutTimer;
static const F32 LOGOUT_REQUEST_TIME = 6.f; // this will be cut short by the LogoutReply msg.
F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
+
+S32 gPendingMetricsUploads = 0;
+
+
BOOL gDisconnected = FALSE;
// used to restore texture state after a mode switch
@@ -303,7 +332,7 @@ BOOL gUseWireframe = FALSE;
LLVFS* gStaticVFS = NULL;
LLMemoryInfo gSysMemory;
-U64 gMemoryAllocated = 0; // updated in display_stats() in llviewerdisplay.cpp
+U64Bytes gMemoryAllocated(0); // updated in display_stats() in llviewerdisplay.cpp
std::string gLastVersionChannel;
@@ -324,8 +353,9 @@ BOOL gLogoutInProgress = FALSE;
////////////////////////////////////////////////////////////
// Internal globals... that should be removed.
static std::string gArgs;
-
+const int MAX_MARKER_LENGTH = 1024;
const std::string MARKER_FILE_NAME("SecondLife.exec_marker");
+const std::string START_MARKER_FILE_NAME("SecondLife.start_marker");
const std::string ERROR_MARKER_FILE_NAME("SecondLife.error_marker");
const std::string LLERROR_MARKER_FILE_NAME("SecondLife.llerror_marker");
const std::string LOGOUT_MARKER_FILE_NAME("SecondLife.logout_marker");
@@ -549,7 +579,7 @@ static void settings_to_globals()
LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));
LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLCoreProfile");
-
+ LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures");
LLVOVolume::sLODFactor = gSavedSettings.getF32("RenderVolumeLODFactor");
@@ -578,7 +608,8 @@ static void settings_to_globals()
static void settings_modify()
{
LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderDeferred");
- LLPipeline::sRenderDeferred = gSavedSettings.getBOOL("RenderDeferred");
+ LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+ LLPipeline::sRenderDeferred = LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
LLVOAvatar::sUseImpostors = gSavedSettings.getBOOL("RenderUseImpostors");
LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor");
LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4]
@@ -603,7 +634,7 @@ public:
while (!LLAppViewer::instance()->isQuitting())
{
- LLFastTimer::writeLog(os);
+ LLTrace::BlockTimer::writeLog(os);
os.flush();
ms_sleep(32);
}
@@ -636,9 +667,14 @@ LLTextureCache* LLAppViewer::sTextureCache = NULL;
LLImageDecodeThread* LLAppViewer::sImageDecodeThread = NULL;
LLTextureFetch* LLAppViewer::sTextureFetch = NULL;
-LLAppViewer::LLAppViewer() :
- mMarkerFile(),
- mLogoutMarkerFile(NULL),
+std::string getRuntime()
+{
+ return llformat("%.4f", (F32)LLTimer::getElapsedSeconds().value());
+}
+
+LLAppViewer::LLAppViewer()
+: mMarkerFile(),
+ mLogoutMarkerFile(),
mReportedCrash(false),
mNumSessions(0),
mPurgeCache(false),
@@ -646,10 +682,11 @@ LLAppViewer::LLAppViewer() :
mSecondInstance(false),
mSavedFinalSnapshot(false),
mSavePerAccountSettings(false), // don't save settings on logout unless login succeeded.
- mForceGraphicsDetail(false),
mQuitRequested(false),
mLogoutRequestSent(false),
mYieldTime(-1),
+ mLastAgentControlFlags(0),
+ mLastAgentForceUpdate(0),
mMainloopTimeout(NULL),
mAgentRegionLastAlive(false),
mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", FALSE)),
@@ -660,38 +697,79 @@ LLAppViewer::LLAppViewer() :
{
if(NULL != sInstance)
{
- llerrs << "Oh no! An instance of LLAppViewer already exists! LLAppViewer is sort of like a singleton." << llendl;
+ LL_ERRS() << "Oh no! An instance of LLAppViewer already exists! LLAppViewer is sort of like a singleton." << LL_ENDL;
}
- setupErrorHandling();
+ mDumpPath ="";
+
+ // Need to do this initialization before we do anything else, since anything
+ // that touches files should really go through the lldir API
+ gDirUtilp->initAppDirs("SecondLife");
+ //
+ // IMPORTANT! Do NOT put anything that will write
+ // into the log files during normal startup until AFTER
+ // we run the "program crashed last time" error handler below.
+ //
sInstance = this;
+
gLoggedInTime.stop();
+
+ initLoggingAndGetLastDuration();
+
+ processMarkerFiles();
+ //
+ // OK to write stuff to logs now, we've now crash reported if necessary
+ //
LLLoginInstance::instance().setUpdaterService(mUpdater.get());
+ LLLoginInstance::instance().setPlatformInfo(gPlatform, getOSInfo().getOSVersionString());
}
LLAppViewer::~LLAppViewer()
{
delete mSettingsLocationList;
+ LLViewerEventRecorder::instance().~LLViewerEventRecorder();
LLLoginInstance::instance().setUpdaterService(0);
destroyMainloopTimeout();
-
+
// If we got to this destructor somehow, the app didn't hang.
- removeMarkerFile();
+ removeMarkerFiles();
+}
+
+class LLUITranslationBridge : public LLTranslationBridge
+{
+public:
+ virtual std::string getString(const std::string &xml_desc)
+ {
+ return LLTrans::getString(xml_desc);
+ }
+};
+
+namespace {
+// With Xcode 6, _exit() is too magical to use with boost::bind(), so provide
+// this little helper function.
+void fast_exit(int rc)
+{
+ _exit(rc);
+}
}
bool LLAppViewer::init()
{
+ setupErrorHandling(mSecondInstance);
+
//
// Start of the application
//
- // IMPORTANT! Do NOT put anything that will write
- // into the log files during normal startup until AFTER
- // we run the "program crashed last time" error handler below.
- //
- LLFastTimer::reset();
+#ifdef LL_DARWIN
+ mMainLoopInitialized = false;
+#endif
+
+ // initialize LLWearableType translation bridge.
+ // Memory will be cleaned up in ::cleanupClass()
+ LLWearableType::initClass(new LLUITranslationBridge());
// initialize SSE options
LLVector4a::initClass();
@@ -699,19 +777,15 @@ bool LLAppViewer::init()
//initialize particle index pool
LLVOPartGroup::initClass();
- // Need to do this initialization before we do anything else, since anything
- // that touches files should really go through the lldir API
- gDirUtilp->initAppDirs("SecondLife");
// set skin search path to default, will be overridden later
// this allows simple skinned file lookups to work
gDirUtilp->setSkinFolder("default", "en");
- initLogging();
+// initLoggingAndGetLastDuration();
//
// OK to write stuff to logs now, we've now crash reported if necessary
//
-
init_default_trans_args();
if (!initConfiguration())
@@ -721,24 +795,27 @@ bool LLAppViewer::init()
//set the max heap size.
initMaxHeapSize() ;
+ LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize"));
LLPrivateMemoryPoolManager::initClass((BOOL)gSavedSettings.getBOOL("MemoryPrivatePoolEnabled"), (U32)gSavedSettings.getU32("MemoryPrivatePoolSize")*1024*1024) ;
-
- // write Google Breakpad minidump files to our log directory
- std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
- logdir += gDirUtilp->getDirDelimiter();
+ // write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.
+ std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
+ mDumpPath = logdir;
setMiniDumpDir(logdir);
+ logdir += gDirUtilp->getDirDelimiter();
+ setDebugFileNames(logdir);
- // Although initLogging() is the right place to mess with
+
+ // Although initLoggingAndGetLastDuration() is the right place to mess with
// setFatalFunction(), we can't query gSavedSettings until after
// initConfiguration().
S32 rc(gSavedSettings.getS32("QAModeTermCode"));
if (rc >= 0)
{
- // QAModeTermCode set, terminate with that rc on LL_ERRS. Use _exit()
- // rather than exit() because normal cleanup depends too much on
- // successful startup!
- LLError::setFatalFunction(boost::bind(_exit, rc));
+ // QAModeTermCode set, terminate with that rc on LL_ERRS. Use
+ // fast_exit() rather than exit() because normal cleanup depends too
+ // much on successful startup!
+ LLError::setFatalFunction(boost::bind(fast_exit, rc));
}
mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling"));
@@ -786,7 +863,7 @@ bool LLAppViewer::init()
LLUIImageList::getInstance(),
ui_audio_callback,
deferred_ui_audio_callback,
- &LLUI::sGLScaleFactor);
+ &LLUI::getScaleFactor());
LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ;
// NOW LLUI::getLanguage() should work. gDirUtilp must know the language
@@ -1002,9 +1079,8 @@ bool LLAppViewer::init()
// get RAM data from XML
std::stringstream minRAMString(LLNotifications::instance().getGlobalString("UnsupportedRAMAmount"));
- U64 minRAM = 0;
+ U64Bytes minRAM;
minRAMString >> minRAM;
- minRAM = minRAM * 1024 * 1024;
if(!LLFeatureManager::getInstance()->isGPUSupported() && LLFeatureManager::getInstance()->getGPUClass() != GPU_CLASS_UNKNOWN)
{
@@ -1158,7 +1234,7 @@ void LLAppViewer::initMaxHeapSize()
//currently SL is built under 32-bit setting, we set its max heap size no more than 1.6 GB.
//F32 max_heap_size_gb = llmin(1.6f, (F32)gSavedSettings.getF32("MaxHeapSize")) ;
- F32 max_heap_size_gb = gSavedSettings.getF32("MaxHeapSize") ;
+ F32Gigabytes max_heap_size_gb = (F32Gigabytes)gSavedSettings.getF32("MaxHeapSize") ;
BOOL enable_mem_failure_prevention = (BOOL)gSavedSettings.getBOOL("MemoryFailurePreventionEnabled") ;
LLMemory::initMaxHeapSizeGB(max_heap_size_gb, enable_mem_failure_prevention) ;
@@ -1194,67 +1270,90 @@ void LLAppViewer::checkMemory()
}
}
-static LLFastTimer::DeclareTimer FTM_MESSAGES("System Messages");
-static LLFastTimer::DeclareTimer FTM_SLEEP("Sleep");
-static LLFastTimer::DeclareTimer FTM_YIELD("Yield");
-
-static LLFastTimer::DeclareTimer FTM_TEXTURE_CACHE("Texture Cache");
-static LLFastTimer::DeclareTimer FTM_DECODE("Image Decode");
-static LLFastTimer::DeclareTimer FTM_VFS("VFS Thread");
-static LLFastTimer::DeclareTimer FTM_LFS("LFS Thread");
-static LLFastTimer::DeclareTimer FTM_PAUSE_THREADS("Pause Threads");
-static LLFastTimer::DeclareTimer FTM_IDLE("Idle");
-static LLFastTimer::DeclareTimer FTM_PUMP("Pump");
-static LLFastTimer::DeclareTimer FTM_PUMP_ARES("Ares");
-static LLFastTimer::DeclareTimer FTM_PUMP_SERVICE("Service");
-static LLFastTimer::DeclareTimer FTM_SERVICE_CALLBACK("Callback");
-static LLFastTimer::DeclareTimer FTM_AGENT_AUTOPILOT("Autopilot");
-static LLFastTimer::DeclareTimer FTM_AGENT_UPDATE("Update");
-
-LLFastTimer::DeclareTimer FTM_FRAME("Frame", true);
+static LLTrace::BlockTimerStatHandle FTM_MESSAGES("System Messages");
+static LLTrace::BlockTimerStatHandle FTM_SLEEP("Sleep");
+static LLTrace::BlockTimerStatHandle FTM_YIELD("Yield");
+
+static LLTrace::BlockTimerStatHandle FTM_TEXTURE_CACHE("Texture Cache");
+static LLTrace::BlockTimerStatHandle FTM_DECODE("Image Decode");
+static LLTrace::BlockTimerStatHandle FTM_VFS("VFS Thread");
+static LLTrace::BlockTimerStatHandle FTM_LFS("LFS Thread");
+static LLTrace::BlockTimerStatHandle FTM_PAUSE_THREADS("Pause Threads");
+static LLTrace::BlockTimerStatHandle FTM_IDLE("Idle");
+static LLTrace::BlockTimerStatHandle FTM_PUMP("Pump");
+static LLTrace::BlockTimerStatHandle FTM_PUMP_ARES("Ares");
+static LLTrace::BlockTimerStatHandle FTM_PUMP_SERVICE("Service");
+static LLTrace::BlockTimerStatHandle FTM_SERVICE_CALLBACK("Callback");
+static LLTrace::BlockTimerStatHandle FTM_AGENT_AUTOPILOT("Autopilot");
+static LLTrace::BlockTimerStatHandle FTM_AGENT_UPDATE("Update");
+
+// externally visible timers
+LLTrace::BlockTimerStatHandle FTM_FRAME("Frame");
bool LLAppViewer::mainLoop()
{
- mMainloopTimeout = new LLWatchdogTimeout();
+#ifdef LL_DARWIN
+ if (!mMainLoopInitialized)
+#endif
+ {
+ LL_INFOS() << "Entering main_loop" << LL_ENDL;
+ mMainloopTimeout = new LLWatchdogTimeout();
+
+ //-------------------------------------------
+ // Run main loop until time to quit
+ //-------------------------------------------
+
+ // Create IO Pump to use for HTTP Requests.
+ gServicePump = new LLPumpIO(gAPRPoolp);
+ LLHTTPClient::setPump(*gServicePump);
+ LLCurl::setCAFile(gDirUtilp->getCAFile());
+
+ // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
+
+ LLVoiceChannel::initClass();
+ LLVoiceClient::getInstance()->init(gServicePump);
+ LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true);
+
+ joystick = LLViewerJoystick::getInstance();
+ joystick->setNeedsReset(true);
+
+#ifdef LL_DARWIN
+ // Ensure that this section of code never gets called again on OS X.
+ mMainLoopInitialized = true;
+#endif
+ }
+ // As we do not (yet) send data on the mainloop LLEventPump that varies
+ // with each frame, no need to instantiate a new LLSD event object each
+ // time. Obviously, if that changes, just instantiate the LLSD at the
+ // point of posting.
+
+ LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
+
+ LLSD newFrame;
- //-------------------------------------------
- // Run main loop until time to quit
- //-------------------------------------------
-
- // Create IO Pump to use for HTTP Requests.
- gServicePump = new LLPumpIO(gAPRPoolp);
- LLHTTPClient::setPump(*gServicePump);
- LLCurl::setCAFile(gDirUtilp->getCAFile());
-
- // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
-
- LLVoiceChannel::initClass();
- LLVoiceClient::getInstance()->init(gServicePump);
- LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true);
LLTimer frameTimer,idleTimer;
LLTimer debugTime;
- LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
- joystick->setNeedsReset(true);
-
- LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
- // As we do not (yet) send data on the mainloop LLEventPump that varies
- // with each frame, no need to instantiate a new LLSD event object each
- // time. Obviously, if that changes, just instantiate the LLSD at the
- // point of posting.
- LLSD newFrame;
-
+
//LLPrivateMemoryPoolTester::getInstance()->run(false) ;
//LLPrivateMemoryPoolTester::getInstance()->run(true) ;
//LLPrivateMemoryPoolTester::destroy() ;
// Handle messages
+#ifdef LL_DARWIN
+ if (!LLApp::isExiting())
+#else
while (!LLApp::isExiting())
+#endif
{
- LLFastTimer _(FTM_FRAME);
- LLFastTimer::nextFrame();
+ LL_RECORD_BLOCK_TIME(FTM_FRAME);
+ LLTrace::BlockTimer::processTimes();
+ LLTrace::get_frame_recording().nextPeriod();
+ LLTrace::BlockTimer::logStats();
+
+ LLTrace::get_thread_recorder()->pullFromChildren();
//clear call stack records
- llclearcallstacks;
+ LL_CLEAR_CALLSTACKS();
//check memory availability information
checkMemory() ;
@@ -1265,7 +1364,7 @@ bool LLAppViewer::mainLoop()
if (gViewerWindow)
{
- LLFastTimer t2(FTM_MESSAGES);
+ LL_RECORD_BLOCK_TIME(FTM_MESSAGES);
gViewerWindow->getWindow()->processMiscNativeEvents();
}
@@ -1273,10 +1372,10 @@ bool LLAppViewer::mainLoop()
if (gViewerWindow)
{
- LLFastTimer t2(FTM_MESSAGES);
+ LL_RECORD_BLOCK_TIME(FTM_MESSAGES);
if (!restoreErrorTrap())
{
- llwarns << " Someone took over my signal/exception handler (post messagehandling)!" << llendl;
+ LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL;
}
gViewerWindow->getWindow()->gatherInput();
@@ -1323,24 +1422,24 @@ bool LLAppViewer::mainLoop()
{
pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds!
- LLFastTimer t3(FTM_IDLE);
+ LL_RECORD_BLOCK_TIME(FTM_IDLE);
idle();
if (gAres != NULL && gAres->isInitialized())
{
pingMainloopTimeout("Main:ServicePump");
- LLFastTimer t4(FTM_PUMP);
+ LL_RECORD_BLOCK_TIME(FTM_PUMP);
{
- LLFastTimer t(FTM_PUMP_ARES);
+ LL_RECORD_BLOCK_TIME(FTM_PUMP_ARES);
gAres->process();
}
{
- LLFastTimer t(FTM_PUMP_SERVICE);
+ LL_RECORD_BLOCK_TIME(FTM_PUMP_SERVICE);
// this pump is necessary to make the login screen show up
gServicePump->pump();
{
- LLFastTimer t(FTM_SERVICE_CALLBACK);
+ LL_RECORD_BLOCK_TIME(FTM_SERVICE_CALLBACK);
gServicePump->callback();
}
}
@@ -1368,7 +1467,6 @@ bool LLAppViewer::mainLoop()
LLFloaterSnapshot::update(); // take snapshots
gGLActive = FALSE;
}
-
}
pingMainloopTimeout("Main:Sleep");
@@ -1377,12 +1475,12 @@ bool LLAppViewer::mainLoop()
// Sleep and run background threads
{
- LLFastTimer t2(FTM_SLEEP);
+ LL_RECORD_BLOCK_TIME(FTM_SLEEP);
// yield some time to the os based on command line option
if(mYieldTime >= 0)
{
- LLFastTimer t(FTM_YIELD);
+ LL_RECORD_BLOCK_TIME(FTM_YIELD);
ms_sleep(mYieldTime);
}
@@ -1411,11 +1509,11 @@ bool LLAppViewer::mainLoop()
if (mPeriodicSlowFrame
&& (gFrameCount % 10 == 0))
{
- llinfos << "Periodic slow frame - sleeping 500 ms" << llendl;
+ LL_INFOS() << "Periodic slow frame - sleeping 500 ms" << LL_ENDL;
ms_sleep(500);
}
- const F64 max_idle_time = llmin(.005*10.0*gFrameTimeSeconds, 0.005); // 5 ms a second
+ const F64Milliseconds max_idle_time = llmin(.005f*10.f*(F32Milliseconds)gFrameTimeSeconds, F32Milliseconds(5)); // 5 ms a second
idleTimer.reset();
S32 total_work_pending = 0;
S32 total_io_pending = 0;
@@ -1423,27 +1521,16 @@ bool LLAppViewer::mainLoop()
{
S32 work_pending = 0;
S32 io_pending = 0;
- F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f);
+ F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f);
- {
- LLFastTimer ftm(FTM_TEXTURE_CACHE);
- work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
- }
- {
- LLFastTimer ftm(FTM_DECODE);
- work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
- }
- {
- LLFastTimer ftm(FTM_DECODE);
- work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
- }
+ work_pending += updateTextureThreads(max_time);
{
- LLFastTimer ftm(FTM_VFS);
+ LL_RECORD_BLOCK_TIME(FTM_VFS);
io_pending += LLVFSThread::updateClass(1);
}
{
- LLFastTimer ftm(FTM_LFS);
+ LL_RECORD_BLOCK_TIME(FTM_LFS);
io_pending += LLLFSThread::updateClass(1);
}
@@ -1512,46 +1599,67 @@ bool LLAppViewer::mainLoop()
if(mem_leak_instance)
{
mem_leak_instance->stop() ;
- llwarns << "Bad memory allocation in LLAppViewer::mainLoop()!" << llendl ;
+ LL_WARNS() << "Bad memory allocation in LLAppViewer::mainLoop()!" << LL_ENDL ;
}
else
{
//output possible call stacks to log file.
LLError::LLCallStacks::print() ;
- llerrs << "Bad memory allocation in LLAppViewer::mainLoop()!" << llendl ;
+ LL_ERRS() << "Bad memory allocation in LLAppViewer::mainLoop()!" << LL_ENDL ;
}
}
}
- // Save snapshot for next time, if we made it through initialization
- if (STATE_STARTED == LLStartUp::getStartupState())
+ if (LLApp::isExiting())
{
- try
- {
- saveFinalSnapshot();
- }
- catch(std::bad_alloc)
+ // Save snapshot for next time, if we made it through initialization
+ if (STATE_STARTED == LLStartUp::getStartupState())
{
- llwarns << "Bad memory allocation when saveFinalSnapshot() is called!" << llendl ;
-
- //stop memory leaking simulation
- LLFloaterMemLeak* mem_leak_instance =
- LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
- if(mem_leak_instance)
+ try
{
- mem_leak_instance->stop() ;
- }
+ saveFinalSnapshot();
+ }
+ catch(std::bad_alloc)
+ {
+ LL_WARNS() << "Bad memory allocation when saveFinalSnapshot() is called!" << LL_ENDL ;
+
+ //stop memory leaking simulation
+ LLFloaterMemLeak* mem_leak_instance =
+ LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
+ if(mem_leak_instance)
+ {
+ mem_leak_instance->stop() ;
+ }
+ }
}
+
+ delete gServicePump;
+
+ destroyMainloopTimeout();
+
+ LL_INFOS() << "Exiting main_loop" << LL_ENDL;
}
-
- delete gServicePump;
-
- destroyMainloopTimeout();
- llinfos << "Exiting main_loop" << llendflush;
+ return LLApp::isExiting();
+}
- return true;
+S32 LLAppViewer::updateTextureThreads(F32 max_time)
+{
+ S32 work_pending = 0;
+ {
+ LL_RECORD_BLOCK_TIME(FTM_TEXTURE_CACHE);
+ work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
+ }
+ {
+ LL_RECORD_BLOCK_TIME(FTM_DECODE);
+ work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
+ }
+ {
+ LL_RECORD_BLOCK_TIME(FTM_DECODE);
+ work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
+ }
+ return work_pending;
}
void LLAppViewer::flushVFSIO()
@@ -1564,7 +1672,7 @@ void LLAppViewer::flushVFSIO()
{
break;
}
- llinfos << "Waiting for pending IO to finish: " << pending << llendflush;
+ LL_INFOS() << "Waiting for pending IO to finish: " << pending << LL_ENDL;
ms_sleep(100);
}
}
@@ -1574,22 +1682,20 @@ bool LLAppViewer::cleanup()
//ditch LLVOAvatarSelf instance
gAgentAvatarp = NULL;
+ LLNotifications::instance().clear();
+
// workaround for DEV-35406 crash on shutdown
LLEventPumps::instance().reset();
- if (LLFastTimerView::sAnalyzePerformance)
- {
- llinfos << "Analyzing performance" << llendl;
- std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp";
- std::string current_name = LLFastTimer::sLogName + ".slp";
- std::string report_name = LLFastTimer::sLogName + "_report.csv";
+ //dump scene loading monitor results
+ LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"));
- LLFastTimerView::doAnalysis(
- gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baseline_name),
- gDirUtilp->getExpandedFilename(LL_PATH_LOGS, current_name),
- gDirUtilp->getExpandedFilename(LL_PATH_LOGS, report_name));
- }
- LLMetricPerformanceTesterBasic::cleanClass();
+ // There used to be an 'if (LLFastTimerView::sAnalyzePerformance)' block
+ // here, completely redundant with the one that occurs later in this same
+ // function. Presumably the duplication was due to an automated merge gone
+ // bad. Not knowing which instance to prefer, we chose to retain the later
+ // one because it happens just after mFastTimerLogThread is deleted. This
+ // comment is in case we guessed wrong, so we can move it here instead.
// remove any old breakpad minidump files from the log directory
if (! isError())
@@ -1625,7 +1731,7 @@ bool LLAppViewer::cleanup()
disconnectViewer();
- llinfos << "Viewer disconnected" << llendflush;
+ LL_INFOS() << "Viewer disconnected" << LL_ENDL;
display_cleanup();
@@ -1633,7 +1739,7 @@ bool LLAppViewer::cleanup()
LLError::logToFixedBuffer(NULL);
- llinfos << "Cleaning Up" << llendflush;
+ LL_INFOS() << "Cleaning Up" << LL_ENDL;
// shut down mesh streamer
gMeshRepo.shutdown();
@@ -1648,7 +1754,7 @@ bool LLAppViewer::cleanup()
LLHUDObject::updateAll();
LLHUDManager::getInstance()->cleanupEffects();
LLHUDObject::cleanupHUDObjects();
- llinfos << "HUD Objects cleaned up" << llendflush;
+ LL_INFOS() << "HUD Objects cleaned up" << LL_ENDL;
}
LLKeyframeDataCache::clear();
@@ -1657,7 +1763,9 @@ bool LLAppViewer::cleanup()
#if 0 // this seems to get us stuck in an infinite loop...
gTransferManager.cleanup();
#endif
-
+
+ LLLocalBitmapMgr::cleanupClass();
+
// Note: this is where gWorldMap used to be deleted.
// Note: this is where gHUDManager used to be deleted.
@@ -1679,7 +1787,7 @@ bool LLAppViewer::cleanup()
LLCalc::cleanUp();
- llinfos << "Global stuff deleted" << llendflush;
+ LL_INFOS() << "Global stuff deleted" << LL_ENDL;
if (gAudiop)
{
@@ -1690,19 +1798,7 @@ bool LLAppViewer::cleanup()
gAudiop->setStreamingAudioImpl(NULL);
// shut down the audio subsystem
-
- bool want_longname = false;
- if (gAudiop->getDriverName(want_longname) == "FMOD")
- {
- // This hack exists because fmod likes to occasionally
- // crash or hang forever when shutting down, for no
- // apparent reason.
- llwarns << "Hack, skipping FMOD audio engine cleanup" << llendflush;
- }
- else
- {
- gAudiop->shutdown();
- }
+ gAudiop->shutdown();
delete gAudiop;
gAudiop = NULL;
@@ -1715,7 +1811,7 @@ bool LLAppViewer::cleanup()
// such that we can suck rectangle information out of
// it.
cleanupSavedSettings();
- llinfos << "Settings patched up" << llendflush;
+ LL_INFOS() << "Settings patched up" << LL_ENDL;
// delete some of the files left around in the cache.
removeCacheFiles("*.wav");
@@ -1726,29 +1822,29 @@ bool LLAppViewer::cleanup()
removeCacheFiles("*.bodypart");
removeCacheFiles("*.clothing");
- llinfos << "Cache files removed" << llendflush;
+ LL_INFOS() << "Cache files removed" << LL_ENDL;
// Wait for any pending VFS IO
flushVFSIO();
- llinfos << "Shutting down Views" << llendflush;
+ LL_INFOS() << "Shutting down Views" << LL_ENDL;
// Destroy the UI
if( gViewerWindow)
gViewerWindow->shutdownViews();
- llinfos << "Cleaning up Inventory" << llendflush;
+ LL_INFOS() << "Cleaning up Inventory" << LL_ENDL;
// Cleanup Inventory after the UI since it will delete any remaining observers
// (Deleted observers should have already removed themselves)
gInventory.cleanupInventory();
- llinfos << "Cleaning up Selections" << llendflush;
+ LL_INFOS() << "Cleaning up Selections" << LL_ENDL;
// Clean up selection managers after UI is destroyed, as UI may be observing them.
// Clean up before GL is shut down because we might be holding on to objects with texture references
LLSelectMgr::cleanupGlobals();
- llinfos << "Shutting down OpenGL" << llendflush;
+ LL_INFOS() << "Shutting down OpenGL" << LL_ENDL;
// Shut down OpenGL
if( gViewerWindow)
@@ -1760,10 +1856,10 @@ bool LLAppViewer::cleanup()
// Therefore must do this before destroying the message system.
delete gViewerWindow;
gViewerWindow = NULL;
- llinfos << "ViewerWindow deleted" << llendflush;
+ LL_INFOS() << "ViewerWindow deleted" << LL_ENDL;
}
- llinfos << "Cleaning up Keyboard & Joystick" << llendflush;
+ LL_INFOS() << "Cleaning up Keyboard & Joystick" << LL_ENDL;
// viewer UI relies on keyboard so keep it aound until viewer UI isa gone
delete gKeyboard;
@@ -1772,9 +1868,13 @@ bool LLAppViewer::cleanup()
// Turn off Space Navigator and similar devices
LLViewerJoystick::getInstance()->terminate();
- llinfos << "Cleaning up Objects" << llendflush;
+ LL_INFOS() << "Cleaning up Objects" << LL_ENDL;
LLViewerObject::cleanupVOClasses();
+
+ LLAvatarAppearance::cleanupClass();
+
+ LLAvatarAppearance::cleanupClass();
LLPostProcess::cleanupClass();
@@ -1790,11 +1890,11 @@ bool LLAppViewer::cleanup()
LLVolumeMgr* volume_manager = LLPrimitive::getVolumeManager();
if (!volume_manager->cleanup())
{
- llwarns << "Remaining references in the volume manager!" << llendflush;
+ LL_WARNS() << "Remaining references in the volume manager!" << LL_ENDL;
}
LLPrimitive::cleanupVolumeManager();
- llinfos << "Additional Cleanup..." << llendflush;
+ LL_INFOS() << "Additional Cleanup..." << LL_ENDL;
LLViewerParcelMgr::cleanupGlobals();
@@ -1815,10 +1915,10 @@ bool LLAppViewer::cleanup()
// Also after shutting down the messaging system since it has VFS dependencies
//
- llinfos << "Cleaning up VFS" << llendflush;
+ LL_INFOS() << "Cleaning up VFS" << LL_ENDL;
LLVFile::cleanupClass();
- llinfos << "Saving Data" << llendflush;
+ LL_INFOS() << "Saving Data" << LL_ENDL;
// Store the time of our current logoff
gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
@@ -1833,19 +1933,19 @@ bool LLAppViewer::cleanup()
// *FIX:Mani This should get really saved in a "logoff" mode.
if (gSavedSettings.getString("PerAccountSettingsFile").empty())
{
- llinfos << "Not saving per-account settings; don't know the account name yet." << llendl;
+ LL_INFOS() << "Not saving per-account settings; don't know the account name yet." << LL_ENDL;
}
// Only save per account settings if the previous login succeeded, otherwise
// we might end up with a cleared out settings file in case a previous login
// failed after loading per account settings.
else if (!mSavePerAccountSettings)
{
- llinfos << "Not saving per-account settings; last login was not successful." << llendl;
+ LL_INFOS() << "Not saving per-account settings; last login was not successful." << LL_ENDL;
}
else
{
gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
- llinfos << "Saved settings" << llendflush;
+ LL_INFOS() << "Saved settings" << LL_ENDL;
}
std::string warnings_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Warnings"));
@@ -1862,11 +1962,9 @@ bool LLAppViewer::cleanup()
if (mPurgeOnExit)
{
- llinfos << "Purging all cache files on exit" << llendflush;
+ LL_INFOS() << "Purging all cache files on exit" << LL_ENDL;
gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*");
}
-
- removeMarkerFile(); // Any crashes from here on we'll just have to ignore
writeDebugInfo();
@@ -1879,7 +1977,7 @@ bool LLAppViewer::cleanup()
// Stop the plugin read thread if it's running.
LLPluginProcessParent::setUseReadThread(false);
- llinfos << "Shutting down Threads" << llendflush;
+ LL_INFOS() << "Shutting down Threads" << LL_ENDL;
// Let threads finish
LLTimer idleTimer;
@@ -1901,7 +1999,7 @@ bool LLAppViewer::cleanup()
}
else if(idle_time >= max_idle_time)
{
- llwarns << "Quitting with pending background tasks." << llendl;
+ LL_WARNS() << "Quitting with pending background tasks." << LL_ENDL;
break;
}
}
@@ -1917,7 +2015,7 @@ bool LLAppViewer::cleanup()
sTextureFetch->shutDownTextureCacheThread() ;
sTextureFetch->shutDownImageDecodeThread() ;
- llinfos << "Shutting down message system" << llendflush;
+ LL_INFOS() << "Shutting down message system" << LL_ENDL;
end_messaging_system();
// *NOTE:Mani - The following call is not thread safe.
@@ -1928,6 +2026,9 @@ bool LLAppViewer::cleanup()
// Non-LLCurl libcurl library
mAppCoreHttp.cleanup();
+ // NOTE The following call is not thread safe.
+ ll_cleanup_ares();
+
LLFilePickerThread::cleanupClass();
//MUST happen AFTER LLCurl::cleanupClass
@@ -1939,14 +2040,14 @@ bool LLAppViewer::cleanup()
sImageDecodeThread = NULL;
delete mFastTimerLogThread;
mFastTimerLogThread = NULL;
-
+
if (LLFastTimerView::sAnalyzePerformance)
{
- llinfos << "Analyzing performance" << llendl;
+ LL_INFOS() << "Analyzing performance" << LL_ENDL;
- std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp";
- std::string current_name = LLFastTimer::sLogName + ".slp";
- std::string report_name = LLFastTimer::sLogName + "_report.csv";
+ std::string baseline_name = LLTrace::BlockTimer::sLogName + "_baseline.slp";
+ std::string current_name = LLTrace::BlockTimer::sLogName + ".slp";
+ std::string report_name = LLTrace::BlockTimer::sLogName + "_report.csv";
LLFastTimerView::doAnalysis(
gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baseline_name),
@@ -1956,7 +2057,7 @@ bool LLAppViewer::cleanup()
LLMetricPerformanceTesterBasic::cleanClass() ;
- llinfos << "Cleaning up Media and Textures" << llendflush;
+ LL_INFOS() << "Cleaning up Media and Textures" << LL_ENDL;
//Note:
//LLViewerMedia::cleanupClass() has to be put before gTextureList.shutdown()
@@ -1972,14 +2073,14 @@ bool LLAppViewer::cleanup()
LLLFSThread::cleanupClass();
#ifndef LL_RELEASE_FOR_DOWNLOAD
- llinfos << "Auditing VFS" << llendl;
+ LL_INFOS() << "Auditing VFS" << LL_ENDL;
if(gVFS)
{
gVFS->audit();
}
#endif
- llinfos << "Misc Cleanup" << llendflush;
+ LL_INFOS() << "Misc Cleanup" << LL_ENDL;
// For safety, the LLVFS has to be deleted *after* LLVFSThread. This should be cleaned up.
// (LLVFS doesn't know about LLVFSThread so can't kill pending requests) -Steve
@@ -1999,7 +2100,7 @@ bool LLAppViewer::cleanup()
// is at the right resolution before we launch IE.
if (!gLaunchFileOnQuit.empty())
{
- llinfos << "Launch file on quit." << llendflush;
+ LL_INFOS() << "Launch file on quit." << LL_ENDL;
#if LL_WINDOWS
// Indicate an application is starting.
SetCursor(LoadCursor(NULL, IDC_WAIT));
@@ -2009,11 +2110,13 @@ bool LLAppViewer::cleanup()
ms_sleep(1000);
LLWeb::loadURLExternal( gLaunchFileOnQuit, false );
- llinfos << "File launched." << llendflush;
+ LL_INFOS() << "File launched." << LL_ENDL;
}
- llinfos << "Cleaning up LLProxy." << llendl;
+ LL_INFOS() << "Cleaning up LLProxy." << LL_ENDL;
LLProxy::cleanupClass();
+ LLWearableType::cleanupClass();
+
LLMainLoopRepeater::instance().stop();
//release all private memory pools.
@@ -2021,15 +2124,19 @@ bool LLAppViewer::cleanup()
ll_close_fail_log();
- MEM_TRACK_RELEASE
+ LLError::LLCallStacks::cleanup();
- llinfos << "Goodbye!" << llendflush;
+ removeMarkerFiles();
+
+ LL_INFOS() << "Goodbye!" << LL_ENDL;
+
+ removeDumpDir();
// return 0;
return true;
}
-// A callback for llerrs to call during the watchdog error.
+// A callback for LL_ERRS() to call during the watchdog error.
void watchdog_llerrs_callback(const std::string &error_string)
{
gLLErrorActivated = true;
@@ -2045,16 +2152,12 @@ void watchdog_llerrs_callback(const std::string &error_string)
void watchdog_killer_callback()
{
LLError::setFatalFunction(watchdog_llerrs_callback);
- llerrs << "Watchdog killer event" << llendl;
+ LL_ERRS() << "Watchdog killer event" << LL_ENDL;
}
bool LLAppViewer::initThreads()
{
-#if MEM_TRACK_MEM
- static const bool enable_threads = false;
-#else
static const bool enable_threads = true;
-#endif
LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
@@ -2069,10 +2172,10 @@ bool LLAppViewer::initThreads()
enable_threads && true,
app_metrics_qa_mode);
- if (LLFastTimer::sLog || LLFastTimer::sMetricLog)
+ if (LLTrace::BlockTimer::sLog || LLTrace::BlockTimer::sMetricLog)
{
- LLFastTimer::sLogLock = new LLMutex(NULL);
- mFastTimerLogThread = new LLFastTimerLogThread(LLFastTimer::sLogName);
+ LLTrace::BlockTimer::setLogLock(new LLMutex(NULL));
+ mFastTimerLogThread = new LLFastTimerLogThread(LLTrace::BlockTimer::sLogName);
mFastTimerLogThread->start();
}
@@ -2097,7 +2200,7 @@ void errorCallback(const std::string &error_string)
LLError::crashAndLoop(error_string);
}
-bool LLAppViewer::initLogging()
+void LLAppViewer::initLoggingAndGetLastDuration()
{
//
// Set up logging defaults for the viewer
@@ -2105,23 +2208,68 @@ bool LLAppViewer::initLogging()
LLError::initForApplication(
gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
LLError::setFatalFunction(errorCallback);
+ //LLError::setTimeFunction(getRuntime);
// Remove the last ".old" log file.
std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
"SecondLife.old");
LLFile::remove(old_log_file);
- // Rename current log file to ".old"
+ // Get name of the log file
std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
"SecondLife.log");
+ /*
+ * Before touching any log files, compute the duration of the last run
+ * by comparing the ctime of the previous start marker file with the ctime
+ * of the last log file.
+ */
+ std::string start_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, START_MARKER_FILE_NAME);
+ llstat start_marker_stat;
+ llstat log_file_stat;
+ std::ostringstream duration_log_stream; // can't log yet, so save any message for when we can below
+ int start_stat_result = LLFile::stat(start_marker_file_name, &start_marker_stat);
+ int log_stat_result = LLFile::stat(log_file, &log_file_stat);
+ if ( 0 == start_stat_result && 0 == log_stat_result )
+ {
+ int elapsed_seconds = log_file_stat.st_ctime - start_marker_stat.st_ctime;
+ // only report a last run time if the last viewer was the same version
+ // because this stat will be counted against this version
+ if ( markerIsSameVersion(start_marker_file_name) )
+ {
+ gLastExecDuration = elapsed_seconds;
+ }
+ else
+ {
+ duration_log_stream << "start marker from some other version; duration is not reported";
+ gLastExecDuration = -1;
+ }
+ }
+ else
+ {
+ // at least one of the LLFile::stat calls failed, so we can't compute the run time
+ duration_log_stream << "duration stat failure; start: "<< start_stat_result << " log: " << log_stat_result;
+ gLastExecDuration = -1; // unknown
+ }
+ std::string duration_log_msg(duration_log_stream.str());
+
+ // Create a new start marker file for comparison with log file time for the next run
+ LLAPRFile start_marker_file ;
+ start_marker_file.open(start_marker_file_name, LL_APR_WB);
+ if (start_marker_file.getFileHandle())
+ {
+ recordMarkerVersion(start_marker_file);
+ start_marker_file.close();
+ }
+
+ // Rename current log file to ".old"
LLFile::rename(log_file, old_log_file);
// Set the log file to SecondLife.log
-
LLError::logToFile(log_file);
-
- // *FIX:Mani no error handling here!
- return true;
+ if (!duration_log_msg.empty())
+ {
+ LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL;
+ }
}
bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
@@ -2129,7 +2277,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
{
if (!mSettingsLocationList)
{
- llerrs << "Invalid settings location list" << llendl;
+ LL_ERRS() << "Invalid settings location list" << LL_ENDL;
}
BOOST_FOREACH(const SettingsGroup& group, mSettingsLocationList->groups)
@@ -2140,19 +2288,19 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
ELLPath path_index = (ELLPath)group.path_index();
if(path_index <= LL_PATH_NONE || path_index >= LL_PATH_LAST)
{
- llerrs << "Out of range path index in app_settings/settings_files.xml" << llendl;
+ LL_ERRS() << "Out of range path index in app_settings/settings_files.xml" << LL_ENDL;
return false;
}
BOOST_FOREACH(const SettingsFile& file, group.files)
{
- llinfos << "Attempting to load settings for the group " << file.name()
- << " - from location " << location_key << llendl;
+ LL_INFOS("Settings") << "Attempting to load settings for the group " << file.name()
+ << " - from location " << location_key << LL_ENDL;
LLControlGroup* settings_group = LLControlGroup::getInstance(file.name);
if(!settings_group)
{
- llwarns << "No matching settings group for name " << file.name() << llendl;
+ LL_WARNS("Settings") << "No matching settings group for name " << file.name() << LL_ENDL;
continue;
}
@@ -2181,13 +2329,13 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
if(settings_group->loadFromFile(full_settings_path, set_defaults, file.persistent))
{ // success!
- llinfos << "Loaded settings file " << full_settings_path << llendl;
+ LL_INFOS("Settings") << "Loaded settings file " << full_settings_path << LL_ENDL;
}
else
{ // failed to load
if(file.required)
{
- llerrs << "Error: Cannot load required settings file from: " << full_settings_path << llendl;
+ LL_ERRS() << "Error: Cannot load required settings file from: " << full_settings_path << LL_ENDL;
return false;
}
else
@@ -2195,7 +2343,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
// only complain if we actually have a filename at this point
if (!full_settings_path.empty())
{
- llinfos << "Cannot load " << full_settings_path << " - No settings found." << llendl;
+ LL_INFOS("Settings") << "Cannot load " << full_settings_path << " - No settings found." << LL_ENDL;
}
}
}
@@ -2230,22 +2378,29 @@ void LLAppViewer::loadColorSettings()
LLUIColorTable::instance().loadFromSettings();
}
+namespace
+{
+ void handleCommandLineError(LLControlGroupCLP& clp)
+ {
+ LL_WARNS() << "Error parsing command line options. Command Line options ignored." << LL_ENDL;
+
+ LL_INFOS() << "Command line usage:\n" << clp << LL_ENDL;
+
+ OSMessageBox(STRINGIZE(LLTrans::getString("MBCmdLineError") << clp.getErrorMessage()),
+ LLStringUtil::null,
+ OSMB_OK);
+ }
+} // anonymous namespace
+
bool LLAppViewer::initConfiguration()
{
//Load settings files list
std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml");
- //LLControlGroup settings_control("SettingsFiles");
- //llinfos << "Loading settings file list " << settings_file_list << llendl;
- //if (0 == settings_control.loadFromFile(settings_file_list))
- //{
- // llerrs << "Cannot load default configuration file " << settings_file_list << llendl;
- //}
-
LLXMLNodePtr root;
BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL);
if (!success)
{
- llerrs << "Cannot load default configuration file " << settings_file_list << llendl;
+ LL_ERRS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL;
}
mSettingsLocationList = new SettingsFiles();
@@ -2255,7 +2410,7 @@ bool LLAppViewer::initConfiguration()
if (!mSettingsLocationList->validateBlock())
{
- llerrs << "Invalid settings file list " << settings_file_list << llendl;
+ LL_ERRS() << "Invalid settings file list " << settings_file_list << LL_ENDL;
}
// The settings and command line parsing have a fragile
@@ -2284,8 +2439,6 @@ bool LLAppViewer::initConfiguration()
gSavedSettings.setString("ClientSettingsFile",
gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Global")));
- gSavedSettings.setString("VersionChannelName", LLVersionInfo::getChannel());
-
#ifndef LL_RELEASE_FOR_DOWNLOAD
// provide developer build only overrides for these control variables that are not
// persisted to settings.xml
@@ -2299,9 +2452,7 @@ bool LLAppViewer::initConfiguration()
{
c->setValue(true, false);
}
-#endif
-#ifndef LL_RELEASE_FOR_DOWNLOAD
gSavedSettings.setBOOL("QAMode", TRUE );
gSavedSettings.setS32("WatchdogEnabled", 0);
#endif
@@ -2337,13 +2488,7 @@ bool LLAppViewer::initConfiguration()
if(!initParseCommandLine(clp))
{
- llwarns << "Error parsing command line options. Command Line options ignored." << llendl;
-
- llinfos << "Command line usage:\n" << clp << llendl;
-
- std::ostringstream msg;
- msg << LLTrans::getString("MBCmdLineError") << clp.getErrorMessage();
- OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
+ handleCommandLineError(clp);
return false;
}
@@ -2357,8 +2502,8 @@ bool LLAppViewer::initConfiguration()
gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
clp.getOption("settings")[0]);
gSavedSettings.setString("ClientSettingsFile", user_settings_filename);
- llinfos << "Using command line specified settings filename: "
- << user_settings_filename << llendl;
+ LL_INFOS("Settings") << "Using command line specified settings filename: "
+ << user_settings_filename << LL_ENDL;
}
// - load overrides from user_settings
@@ -2374,8 +2519,8 @@ bool LLAppViewer::initConfiguration()
{
std::string session_settings_filename = clp.getOption("sessionsettings")[0];
gSavedSettings.setString("SessionSettingsFile", session_settings_filename);
- llinfos << "Using session settings filename: "
- << session_settings_filename << llendl;
+ LL_INFOS("Settings") << "Using session settings filename: "
+ << session_settings_filename << LL_ENDL;
}
loadSettingsFromDirectory("Session");
@@ -2383,21 +2528,25 @@ bool LLAppViewer::initConfiguration()
{
std::string user_session_settings_filename = clp.getOption("usersessionsettings")[0];
gSavedSettings.setString("UserSessionSettingsFile", user_session_settings_filename);
- llinfos << "Using user session settings filename: "
- << user_session_settings_filename << llendl;
+ LL_INFOS("Settings") << "Using user session settings filename: "
+ << user_session_settings_filename << LL_ENDL;
}
loadSettingsFromDirectory("UserSession");
// - apply command line settings
- clp.notify();
+ if (! clp.notify())
+ {
+ handleCommandLineError(clp);
+ return false;
+ }
// Register the core crash option as soon as we can
// if we want gdb post-mortem on cores we need to be up and running
// ASAP or we might miss init issue etc.
- if(clp.hasOption("disablecrashlogger"))
+ if(gSavedSettings.getBOOL("DisableCrashLogger"))
{
- llwarns << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" << llendl;
+ LL_WARNS() << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" << LL_ENDL;
LLAppViewer::instance()->disableCrashlogger();
}
@@ -2412,7 +2561,7 @@ bool LLAppViewer::initConfiguration()
{
std::ostringstream msg;
msg << LLTrans::getString("MBCmdLineUsg") << "\n" << clp;
- llinfos << msg.str() << llendl;
+ LL_INFOS() << msg.str() << LL_ENDL;
OSMessageBox(
msg.str().c_str(),
@@ -2427,7 +2576,7 @@ bool LLAppViewer::initConfiguration()
const LLCommandLineParser::token_vector_t& set_values = clp.getOption("set");
if(0x1 & set_values.size())
{
- llwarns << "Invalid '--set' parameter count." << llendl;
+ LL_WARNS() << "Invalid '--set' parameter count." << LL_ENDL;
}
else
{
@@ -2446,13 +2595,13 @@ bool LLAppViewer::initConfiguration()
{
group_part = name.substr(0, pos);
name_part = name.substr(pos+1);
- llinfos << "Setting " << group_part << "." << name_part << " to " << value << llendl;
+ LL_INFOS() << "Setting " << group_part << "." << name_part << " to " << value << LL_ENDL;
LLControlGroup* g = LLControlGroup::getInstance(group_part);
if (g) control = g->getControl(name_part);
}
else
{
- llinfos << "Setting Global." << name << " to " << value << llendl;
+ LL_INFOS() << "Setting Global." << name << " to " << value << LL_ENDL;
control = gSavedSettings.getControl(name);
}
@@ -2462,97 +2611,62 @@ bool LLAppViewer::initConfiguration()
}
else
{
- llwarns << "Failed --set " << name << ": setting name unknown." << llendl;
+ LL_WARNS() << "Failed --set " << name << ": setting name unknown." << LL_ENDL;
}
}
}
}
- if(clp.hasOption("channel"))
+ if (clp.hasOption("logevents")) {
+ LLViewerEventRecorder::instance().setEventLoggingOn();
+ }
+
+ std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel"));
+ if(! CmdLineChannel.empty())
{
- LLVersionInfo::resetChannel(clp.getOption("channel")[0]);
+ LLVersionInfo::resetChannel(CmdLineChannel);
}
// If we have specified crash on startup, set the global so we'll trigger the crash at the right time
- if(clp.hasOption("crashonstartup"))
- {
- gCrashOnStartup = TRUE;
- }
+ gCrashOnStartup = gSavedSettings.getBOOL("CrashOnStartup");
- if (clp.hasOption("logperformance"))
+ if (gSavedSettings.getBOOL("LogPerformance"))
{
- LLFastTimer::sLog = TRUE;
- LLFastTimer::sLogName = std::string("performance");
+ LLTrace::BlockTimer::sLog = true;
+ LLTrace::BlockTimer::sLogName = std::string("performance");
}
- if (clp.hasOption("logmetrics"))
+ std::string test_name(gSavedSettings.getString("LogMetrics"));
+ if (! test_name.empty())
{
- LLFastTimer::sMetricLog = TRUE ;
- // '--logmetrics' can be specified with a named test metric argument so the data gathering is done only on that test
- // In the absence of argument, every metric is gathered (makes for a rather slow run and hard to decipher report...)
- std::string test_name = clp.getOption("logmetrics")[0];
- llinfos << "'--logmetrics' argument : " << test_name << llendl;
- if (test_name == "")
- {
- llwarns << "No '--logmetrics' argument given, will output all metrics to " << DEFAULT_METRIC_NAME << llendl;
- LLFastTimer::sLogName = DEFAULT_METRIC_NAME;
- }
- else
- {
- LLFastTimer::sLogName = test_name;
- }
- }
+ LLTrace::BlockTimer::sMetricLog = TRUE;
+ // '--logmetrics' is specified with a named test metric argument so the data gathering is done only on that test
+ // In the absence of argument, every metric would be gathered (makes for a rather slow run and hard to decipher report...)
+ LL_INFOS() << "'--logmetrics' argument : " << test_name << LL_ENDL;
+ LLTrace::BlockTimer::sLogName = test_name;
+ }
if (clp.hasOption("graphicslevel"))
{
- const LLCommandLineParser::token_vector_t& value = clp.getOption("graphicslevel");
- if(value.size() != 1)
+ // User explicitly requested --graphicslevel on the command line. We
+ // expect this switch has already set RenderQualityPerformance. Check
+ // that value for validity.
+ U32 graphicslevel = gSavedSettings.getU32("RenderQualityPerformance");
+ if (LLFeatureManager::instance().isValidGraphicsLevel(graphicslevel))
{
- llwarns << "Usage: -graphicslevel <0-3>" << llendl;
+ // graphicslevel is valid: save it and engage it later. Capture
+ // the requested value separately from the settings variable
+ // because, if this is the first run, LLViewerWindow's constructor
+ // will call LLFeatureManager::applyRecommendedSettings(), which
+ // overwrites this settings variable!
+ mForceGraphicsLevel = graphicslevel;
}
- else
- {
- std::string detail = value.front();
- mForceGraphicsDetail = TRUE;
-
- switch (detail.c_str()[0])
- {
- case '0':
- gSavedSettings.setU32("RenderQualityPerformance", 0);
- break;
- case '1':
- gSavedSettings.setU32("RenderQualityPerformance", 1);
- break;
- case '2':
- gSavedSettings.setU32("RenderQualityPerformance", 2);
- break;
- case '3':
- gSavedSettings.setU32("RenderQualityPerformance", 3);
- break;
- default:
- mForceGraphicsDetail = FALSE;
- llwarns << "Usage: -graphicslevel <0-3>" << llendl;
- break;
- }
- }
- }
-
- if (clp.hasOption("analyzeperformance"))
- {
- LLFastTimerView::sAnalyzePerformance = TRUE;
}
- if (clp.hasOption("replaysession"))
- {
- gAgentPilot.setReplaySession(TRUE);
- }
+ LLFastTimerView::sAnalyzePerformance = gSavedSettings.getBOOL("AnalyzePerformance");
+ gAgentPilot.setReplaySession(gSavedSettings.getBOOL("ReplaySession"));
- if (clp.hasOption("nonotifications"))
- {
- gSavedSettings.getControl("IgnoreAllNotifications")->setValue(true, false);
- }
-
- if (clp.hasOption("debugsession"))
+ if (gSavedSettings.getBOOL("DebugSession"))
{
gDebugSession = TRUE;
gDebugGL = TRUE;
@@ -2577,19 +2691,47 @@ bool LLAppViewer::initConfiguration()
// What can happen is that someone can use IE (or potentially
// other browsers) and do the rough equivalent of command
// injection and steal passwords. Phoenix. SL-55321
- if(clp.hasOption("url"))
- {
- LLStartUp::setStartSLURL(LLSLURL(clp.getOption("url")[0]));
- if(LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION)
- {
- LLGridManager::getInstance()->setGridChoice(LLStartUp::getStartSLURL().getGrid());
-
- }
- }
- else if(clp.hasOption("slurl"))
+
+ std::string starting_location;
+
+ std::string cmd_line_login_location(gSavedSettings.getString("CmdLineLoginLocation"));
+ if(! cmd_line_login_location.empty())
+ {
+ starting_location = cmd_line_login_location;
+ }
+ else
+ {
+ std::string default_login_location(gSavedSettings.getString("DefaultLoginLocation"));
+ if (! default_login_location.empty())
+ {
+ starting_location = default_login_location;
+ }
+ }
+
+ LLSLURL start_slurl;
+ if (! starting_location.empty())
{
- LLSLURL start_slurl(clp.getOption("slurl")[0]);
+ start_slurl = starting_location;
LLStartUp::setStartSLURL(start_slurl);
+ if(start_slurl.getType() == LLSLURL::LOCATION)
+ {
+ LLGridManager::getInstance()->setGridChoice(start_slurl.getGrid());
+ }
+ }
+
+ //RN: if we received a URL, hand it off to the existing instance.
+ // don't call anotherInstanceRunning() when doing URL handoff, as
+ // it relies on checking a marker file which will not work when running
+ // out of different directories
+
+ if (start_slurl.isValid() &&
+ (gSavedSettings.getBOOL("SLURLPassToOtherInstance")))
+ {
+ if (sendURLToOtherInstance(start_slurl.getSLURLString()))
+ {
+ // successfully handed off URL to existing instance, exit
+ return false;
+ }
}
const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
@@ -2617,40 +2759,6 @@ bool LLAppViewer::initConfiguration()
mYieldTime = gSavedSettings.getS32("YieldTime");
- // Read skin/branding settings if specified.
- //if (! gDirUtilp->getSkinDir().empty() )
- //{
- // std::string skin_def_file = gDirUtilp->findSkinnedFilename("skin.xml");
- // LLXmlTree skin_def_tree;
-
- // if (!skin_def_tree.parseFile(skin_def_file))
- // {
- // llerrs << "Failed to parse skin definition." << llendl;
- // }
-
- //}
-
-#if LL_DARWIN
- // Initialize apple menubar and various callbacks
- init_apple_menu(LLTrans::getString("APP_NAME").c_str());
-
-#if __ppc__
- // If the CPU doesn't have Altivec (i.e. it's not at least a G4), don't go any further.
- // Only test PowerPC - all Intel Macs have SSE.
- if(!gSysCPU.hasAltivec())
- {
- std::ostringstream msg;
- msg << LLTrans::getString("MBRequiresAltiVec");
- OSMessageBox(
- msg.str(),
- LLStringUtil::null,
- OSMB_OK);
- removeMarkerFile();
- return false;
- }
-#endif
-
-#endif // LL_DARWIN
// Display splash screen. Must be after above check for previous
// crash as this dialog is always frontmost.
@@ -2696,51 +2804,30 @@ bool LLAppViewer::initConfiguration()
}
}
- if (!gSavedSettings.getBOOL("AllowMultipleViewers"))
+ //
+ // Check for another instance of the app running
+ //
+ if (mSecondInstance && !gSavedSettings.getBOOL("AllowMultipleViewers"))
{
- //
- // Check for another instance of the app running
- //
-
- mSecondInstance = anotherInstanceRunning();
-
- if (mSecondInstance)
- {
- std::ostringstream msg;
- msg << LLTrans::getString("MBAlreadyRunning");
- OSMessageBox(
- msg.str(),
- LLStringUtil::null,
- OSMB_OK);
- return false;
- }
+ std::ostringstream msg;
+ msg << LLTrans::getString("MBAlreadyRunning");
+ OSMessageBox(
+ msg.str(),
+ LLStringUtil::null,
+ OSMB_OK);
+ return false;
+ }
- initMarkerFile();
-
- checkForCrash();
- }
- else
+ if (mSecondInstance)
{
- mSecondInstance = anotherInstanceRunning();
-
- if (mSecondInstance)
+ // This is the second instance of SL. Turn off voice support,
+ // but make sure the setting is *not* persisted.
+ LLControlVariable* disable_voice = gSavedSettings.getControl("CmdLineDisableVoice");
+ if(disable_voice)
{
- // This is the second instance of SL. Turn off voice support,
- // but make sure the setting is *not* persisted.
- LLControlVariable* disable_voice = gSavedSettings.getControl("CmdLineDisableVoice");
- if(disable_voice)
- {
- const BOOL DO_NOT_PERSIST = FALSE;
- disable_voice->setValue(LLSD(TRUE), DO_NOT_PERSIST);
- }
+ const BOOL DO_NOT_PERSIST = FALSE;
+ disable_voice->setValue(LLSD(TRUE), DO_NOT_PERSIST);
}
-
- initMarkerFile();
-
- if(!mSecondInstance)
- {
- checkForCrash();
- }
}
// NextLoginLocation is set from the command line option
@@ -2751,8 +2838,7 @@ bool LLAppViewer::initConfiguration()
LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
}
else if ( ( clp.hasOption("login") || clp.hasOption("autologin"))
- && !clp.hasOption("url")
- && !clp.hasOption("slurl"))
+ && gSavedSettings.getString("CmdLineLoginLocation").empty())
{
// If automatic login from command line with --login switch
// init StartSLURL location.
@@ -2769,6 +2855,16 @@ bool LLAppViewer::initConfiguration()
loadColorSettings();
+ // 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 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));
+ }
+
return true; // Config was successful.
}
@@ -2824,10 +2920,10 @@ namespace {
void apply_update_callback(LLSD const & notification, LLSD const & response)
{
- lldebugs << "LLUpdate user response: " << response << llendl;
+ LL_DEBUGS() << "LLUpdate user response: " << response << LL_ENDL;
if(response["OK_okcancelbuttons"].asBoolean())
{
- llinfos << "LLUpdate restarting viewer" << llendl;
+ LL_INFOS() << "LLUpdate restarting viewer" << LL_ENDL;
static const bool install_if_ready = true;
// *HACK - this lets us launch the installer immediately for now
LLUpdaterService().startChecking(install_if_ready);
@@ -2836,7 +2932,7 @@ namespace {
void apply_update_ok_callback(LLSD const & notification, LLSD const & response)
{
- llinfos << "LLUpdate restarting viewer" << llendl;
+ LL_INFOS() << "LLUpdate restarting viewer" << LL_ENDL;
static const bool install_if_ready = true;
// *HACK - this lets us launch the installer immediately for now
LLUpdaterService().startChecking(install_if_ready);
@@ -2847,25 +2943,46 @@ namespace {
std::string notification_name;
void (*apply_callback)(LLSD const &, LLSD const &) = NULL;
+ /* Build up the notification name...
+ * it can be any of these, which are included here for the sake of grep:
+ * RequiredUpdateDownloadedDialog
+ * RequiredUpdateDownloadedVerboseDialog
+ * OtherChannelRequiredUpdateDownloadedDialog
+ * OtherChannelRequiredUpdateDownloadedVerbose
+ * DownloadBackgroundTip
+ * DownloadBackgroundDialog
+ * OtherChannelDownloadBackgroundTip
+ * OtherChannelDownloadBackgroundDialog
+ */
+ {
+ LL_DEBUGS("UpdaterService") << "data = ";
+ std::ostringstream data_dump;
+ LLSDSerialize::toNotation(data, data_dump);
+ LL_CONT << data_dump.str() << LL_ENDL;
+ }
+ if(data["channel"].asString() != LLVersionInfo::getChannel())
+ {
+ notification_name.append("OtherChannel");
+ }
if(data["required"].asBoolean())
{
if(LLStartUp::getStartupState() <= STATE_LOGIN_WAIT)
{
// The user never saw the progress bar.
apply_callback = &apply_update_ok_callback;
- notification_name = "RequiredUpdateDownloadedVerboseDialog";
+ notification_name += "RequiredUpdateDownloadedVerboseDialog";
}
else if(LLStartUp::getStartupState() < STATE_WORLD_INIT)
{
// The user is logging in but blocked.
apply_callback = &apply_update_ok_callback;
- notification_name = "RequiredUpdateDownloadedDialog";
+ notification_name += "RequiredUpdateDownloadedDialog";
}
else
{
// The user is already logged in; treat like an optional update.
apply_callback = &apply_update_callback;
- notification_name = "DownloadBackgroundTip";
+ notification_name += "DownloadBackgroundTip";
}
}
else
@@ -2875,16 +2992,26 @@ namespace {
{
// CHOP-262 we need to use a different notification
// method prior to login.
- notification_name = "DownloadBackgroundDialog";
+ notification_name += "DownloadBackgroundDialog";
}
else
{
- notification_name = "DownloadBackgroundTip";
+ notification_name += "DownloadBackgroundTip";
}
}
LLSD substitutions;
substitutions["VERSION"] = data["version"];
+ std::string new_channel = data["channel"].asString();
+ substitutions["NEW_CHANNEL"] = new_channel;
+ std::string info_url = data["info_url"].asString();
+ if ( !info_url.empty() )
+ {
+ substitutions["INFO_URL"] = info_url;
+ }
+ else
+ {
+ LL_WARNS("UpdaterService") << "no info url supplied - defaulting to hard coded release notes pattern" << LL_ENDL;
// truncate version at the rightmost '.'
std::string version_short(data["version"]);
@@ -2903,7 +3030,8 @@ namespace {
relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get());
relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL"));
- substitutions["RELEASE_NOTES_FULL_URL"] = relnotes_url.getString();
+ substitutions["INFO_URL"] = relnotes_url.getString();
+ }
LLNotificationsUtil::add(notification_name, substitutions, LLSD(), apply_callback);
}
@@ -2946,22 +3074,50 @@ namespace {
void LLAppViewer::initUpdater()
{
// Initialize the updater service.
- // Generate URL to the udpater service
// Get Channel
// Get Version
- std::string url = gSavedSettings.getString("UpdaterServiceURL");
+
+ /*****************************************************************
+ * Previously, the url was derived from the settings
+ * UpdaterServiceURL
+ * UpdaterServicePath
+ * it is now obtained from the grid manager. The settings above
+ * are no longer used.
+ *****************************************************************/
std::string channel = LLVersionInfo::getChannel();
std::string version = LLVersionInfo::getVersion();
- std::string protocol_version = gSavedSettings.getString("UpdaterServiceProtocolVersion");
- std::string service_path = gSavedSettings.getString("UpdaterServicePath");
+
U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod");
+ bool willing_to_test;
+ LL_DEBUGS("UpdaterService") << "channel " << channel << LL_ENDL;
+ static const boost::regex is_test_channel("\\bTest$");
+ if (boost::regex_search(channel, is_test_channel))
+ {
+ LL_INFOS("UpdaterService") << "Test build: overriding willing_to_test by sending testno" << LL_ENDL;
+ willing_to_test = false;
+ }
+ else
+ {
+ willing_to_test = gSavedSettings.getBOOL("UpdaterWillingToTest");
+ }
+ unsigned char unique_id[MD5HEX_STR_SIZE];
+ if ( ! llHashedUniqueID(unique_id) )
+ {
+ if ( willing_to_test )
+ {
+ LL_WARNS("UpdaterService") << "Unable to provide a unique id; overriding willing_to_test by sending testno" << LL_ENDL;
+ }
+ willing_to_test = false;
+ }
mUpdater->setAppExitCallback(boost::bind(&LLAppViewer::forceQuit, this));
- mUpdater->initialize(protocol_version,
- url,
- service_path,
- channel,
- version);
+ mUpdater->initialize(channel,
+ version,
+ gPlatform,
+ getOSInfo().getOSVersionString(),
+ unique_id,
+ willing_to_test
+ );
mUpdater->setCheckPeriod(check_period);
mUpdater->setBandwidthLimit((int)gSavedSettings.getF32("UpdaterMaximumBandwidth") * (1024/8));
gSavedSettings.getControl("UpdaterMaximumBandwidth")->getSignal()->
@@ -2976,19 +3132,6 @@ void LLAppViewer::initUpdater()
updater_pump.listen("notify_update", &notify_update);
}
-void LLAppViewer::checkForCrash(void)
-{
-#if LL_SEND_CRASH_REPORTS
- if (gLastExecEvent == LAST_EXEC_FROZE)
- {
- llinfos << "Last execution froze, sending a crash report." << llendl;
-
- bool report_freeze = true;
- handleCrashReporting(report_freeze);
- }
-#endif // LL_SEND_CRASH_REPORTS
-}
-
//
// This function decides whether the client machine meets the minimum requirements to
// run in a maximized window, per the consensus of davep, boa and nyx on 3/30/2011.
@@ -2997,8 +3140,7 @@ bool LLAppViewer::meetsRequirementsForMaximizedStart()
{
bool maximizedOk = (LLFeatureManager::getInstance()->getGPUClass() >= GPU_CLASS_2);
- const U32 one_gigabyte_kb = 1024 * 1024;
- maximizedOk &= (gSysMemory.getPhysicalMemoryKB() >= one_gigabyte_kb);
+ maximizedOk &= (gSysMemory.getPhysicalMemoryKB() >= U32Gigabytes(1));
return maximizedOk;
}
@@ -3051,6 +3193,14 @@ bool LLAppViewer::initWindow()
LLNotificationsUI::LLNotificationManager::getInstance();
+
+#ifdef LL_DARWIN
+ //Satisfy both MAINT-3135 (OSX 10.6 and earlier) MAINT-3288 (OSX 10.7 and later)
+ if (getOSInfo().mMajorVer == 10 && getOSInfo().mMinorVer < 7)
+ if ( getOSInfo().mMinorVer == 6 && getOSInfo().mBuild < 8 )
+ gViewerWindow->getWindow()->setOldResize(true);
+#endif
+
if (gSavedSettings.getBOOL("WindowMaximized"))
{
gViewerWindow->getWindow()->maximize();
@@ -3060,9 +3210,10 @@ bool LLAppViewer::initWindow()
// Initialize GL stuff
//
- if (mForceGraphicsDetail)
+ if (mForceGraphicsLevel)
{
- LLFeatureManager::getInstance()->setGraphicsLevel(gSavedSettings.getU32("RenderQualityPerformance"), false);
+ LLFeatureManager::getInstance()->setGraphicsLevel(*mForceGraphicsLevel, false);
+ gSavedSettings.setU32("RenderQualityPerformance", *mForceGraphicsLevel);
}
// Set this flag in case we crash while initializing GL
@@ -3111,18 +3262,209 @@ bool LLAppViewer::initWindow()
//gViewerWindow->getWindow()->show();
LL_INFOS("AppInit") << "Window initialization done." << LL_ENDL;
+
return true;
}
-void LLAppViewer::writeDebugInfo()
+void LLAppViewer::writeDebugInfo(bool isStatic)
{
- std::string debug_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log");
- llinfos << "Opening debug file " << debug_filename << llendl;
- llofstream out_file(debug_filename);
- LLSDSerialize::toPrettyXML(gDebugInfo, out_file);
+ //Try to do the minimum when writing data during a crash.
+ std::string* debug_filename;
+ debug_filename = ( isStatic
+ ? getStaticDebugFile()
+ : getDynamicDebugFile() );
+
+ LL_INFOS() << "Opening debug file " << *debug_filename << LL_ENDL;
+ llofstream out_file(debug_filename->c_str());
+
+ isStatic ? LLSDSerialize::toPrettyXML(gDebugInfo, out_file)
+ : LLSDSerialize::toPrettyXML(gDebugInfo["Dynamic"], out_file);
+
+
out_file.close();
}
+LLSD LLAppViewer::getViewerInfo() const
+{
+ // The point of having one method build an LLSD info block and the other
+ // construct the user-visible About string is to ensure that the same info
+ // 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["BUILD_DATE"] = __DATE__;
+ info["BUILD_TIME"] = __TIME__;
+ info["CHANNEL"] = LLVersionInfo::getChannel();
+
+ // return a URL to the release notes for this viewer, such as:
+ // http://wiki.secondlife.com/wiki/Release_Notes/Second Life Beta Viewer/2.1.0.123456
+ std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL");
+ if (! LLStringUtil::endsWith(url, "/"))
+ url += "/";
+ url += LLURI::escape(LLVersionInfo::getChannel()) + "/";
+ url += LLURI::escape(LLVersionInfo::getVersion());
+
+ info["VIEWER_RELEASE_NOTES_URL"] = url;
+
+#if LL_MSVC
+ info["COMPILER"] = "MSVC";
+ info["COMPILER_VERSION"] = _MSC_VER;
+#elif LL_GNUC
+ info["COMPILER"] = "GCC";
+ info["COMPILER_VERSION"] = GCC_VERSION;
+#endif
+
+ // Position
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ LLVector3d pos = gAgent.getPositionGlobal();
+ info["POSITION"] = ll_sd_from_vector3d(pos);
+ info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos));
+ info["REGION"] = gAgent.getRegion()->getName();
+ info["HOSTNAME"] = gAgent.getRegion()->getHost().getHostName();
+ info["HOSTIP"] = gAgent.getRegion()->getHost().getString();
+ info["SERVER_VERSION"] = gLastVersionChannel;
+ LLSLURL slurl;
+ LLAgentUI::buildSLURL(slurl);
+ info["SLURL"] = slurl.getSLURLString();
+ }
+
+ // CPU
+ info["CPU"] = gSysCPU.getCPUString();
+ info["MEMORY_MB"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB().valueInUnits<LLUnits::Megabytes>());
+ // Moved hack adjustment to Windows memory size into llsys.cpp
+ info["OS_VERSION"] = LLAppViewer::instance()->getOSInfo().getOSString();
+ info["GRAPHICS_CARD_VENDOR"] = (const char*)(glGetString(GL_VENDOR));
+ info["GRAPHICS_CARD"] = (const char*)(glGetString(GL_RENDERER));
+
+#if LL_WINDOWS
+ LLSD driver_info = gDXHardware.getDisplayInfo();
+ if (driver_info.has("DriverVersion"))
+ {
+ info["GRAPHICS_DRIVER_VERSION"] = driver_info["DriverVersion"];
+ }
+#endif
+
+ info["OPENGL_VERSION"] = (const char*)(glGetString(GL_VERSION));
+ info["LIBCURL_VERSION"] = LLCurl::getVersionString();
+ info["J2C_VERSION"] = LLImageJ2C::getEngineInfo();
+ bool want_fullname = true;
+ info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : LLSD();
+ if(LLVoiceClient::getInstance()->voiceEnabled())
+ {
+ LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
+ std::ostringstream version_string;
+ version_string << version.serverType << " " << version.serverVersion << std::endl;
+ info["VOICE_VERSION"] = version_string.str();
+ }
+ else
+ {
+ info["VOICE_VERSION"] = LLTrans::getString("NotConnected");
+ }
+
+ // TODO: Implement media plugin version query
+ info["QT_WEBKIT_VERSION"] = "4.7.1 (version number hard-coded)";
+
+ S32 packets_in = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN);
+ if (packets_in > 0)
+ {
+ info["PACKETS_LOST"] = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_LOST);
+ info["PACKETS_IN"] = packets_in;
+ info["PACKETS_PCT"] = 100.f*info["PACKETS_LOST"].asReal() / info["PACKETS_IN"].asReal();
+ }
+
+ if (mServerReleaseNotesURL.empty())
+ {
+ if (gAgent.getRegion())
+ {
+ info["SERVER_RELEASE_NOTES_URL"] = LLTrans::getString("RetrievingData");
+ }
+ else
+ {
+ info["SERVER_RELEASE_NOTES_URL"] = LLTrans::getString("NotConnected");
+ }
+ }
+ else if (LLStringUtil::startsWith(mServerReleaseNotesURL, "http")) // it's an URL
+ {
+ info["SERVER_RELEASE_NOTES_URL"] = "[" + LLWeb::escapeURL(mServerReleaseNotesURL) + " " + LLTrans::getString("ReleaseNotes") + "]";
+ }
+ else
+ {
+ info["SERVER_RELEASE_NOTES_URL"] = mServerReleaseNotesURL;
+ }
+
+ return info;
+}
+
+std::string LLAppViewer::getViewerInfoString() const
+{
+ std::ostringstream support;
+
+ LLSD info(getViewerInfo());
+
+ // Render the LLSD from getInfo() as a format_map_t
+ LLStringUtil::format_map_t args;
+
+ // allow the "Release Notes" URL label to be localized
+ args["ReleaseNotes"] = LLTrans::getString("ReleaseNotes");
+
+ for (LLSD::map_const_iterator ii(info.beginMap()), iend(info.endMap());
+ ii != iend; ++ii)
+ {
+ if (! ii->second.isArray())
+ {
+ // Scalar value
+ if (ii->second.isUndefined())
+ {
+ args[ii->first] = LLTrans::getString("none_text");
+ }
+ else
+ {
+ // don't forget to render value asString()
+ args[ii->first] = ii->second.asString();
+ }
+ }
+ else
+ {
+ // array value: build KEY_0, KEY_1 etc. entries
+ for (LLSD::Integer n(0), size(ii->second.size()); n < size; ++n)
+ {
+ args[STRINGIZE(ii->first << '_' << n)] = ii->second[n].asString();
+ }
+ }
+ }
+
+ // Now build the various pieces
+ support << LLTrans::getString("AboutHeader", args);
+ if (info.has("REGION"))
+ {
+ support << "\n\n" << LLTrans::getString("AboutPosition", args);
+ }
+ support << "\n\n" << LLTrans::getString("AboutSystem", args);
+ support << "\n";
+ if (info.has("GRAPHICS_DRIVER_VERSION"))
+ {
+ support << "\n" << LLTrans::getString("AboutDriver", args);
+ }
+ support << "\n" << LLTrans::getString("AboutLibs", args);
+ if (info.has("COMPILER"))
+ {
+ support << "\n" << LLTrans::getString("AboutCompiler", args);
+ }
+ if (info.has("PACKETS_IN"))
+ {
+ support << '\n' << LLTrans::getString("AboutTraffic", args);
+ }
+ return support.str();
+}
+
void LLAppViewer::cleanupSavedSettings()
{
gSavedSettings.setBOOL("MouseSun", FALSE);
@@ -3171,7 +3513,16 @@ void LLAppViewer::removeCacheFiles(const std::string& file_mask)
void LLAppViewer::writeSystemInfo()
{
- gDebugInfo["SLLog"] = LLError::logFileName();
+
+ if (! gDebugInfo.has("Dynamic") )
+ gDebugInfo["Dynamic"] = LLSD::emptyMap();
+
+#if LL_WINDOWS
+ gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log");
+#else
+ //Not ideal but sufficient for good reporting.
+ gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.old"); //LLError::logFileName();
+#endif
gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel();
gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
@@ -3188,8 +3539,8 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE();
gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2();
- gDebugInfo["RAMInfo"]["Physical"] = (LLSD::Integer)(gSysMemory.getPhysicalMemoryKB());
- gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer)(gMemoryAllocated>>10); // MB -> KB
+ gDebugInfo["RAMInfo"]["Physical"] = (LLSD::Integer)(gSysMemory.getPhysicalMemoryKB().value());
+ gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer)(gMemoryAllocated.valueInUnits<LLUnits::Kilobytes>());
gDebugInfo["OSInfo"] = getOSInfo().getOSStringSimple();
// The user is not logged on yet, but record the current grid choice login url
@@ -3219,8 +3570,8 @@ void LLAppViewer::writeSystemInfo()
}
// Dump some debugging info
- LL_INFOS("SystemInfo") << LLTrans::getString("APP_NAME")
- << " version " << LLVersionInfo::getShortVersion() << LL_ENDL;
+ LL_INFOS("SystemInfo") << "Application: " << LLTrans::getString("APP_NAME") << LL_ENDL;
+ LL_INFOS("SystemInfo") << "Version: " << LLVersionInfo::getChannelAndVersion() << LL_ENDL;
// Dump the local time and time zone
time_t now;
@@ -3235,14 +3586,60 @@ void LLAppViewer::writeSystemInfo()
LL_INFOS("SystemInfo") << "OS: " << getOSInfo().getOSStringSimple() << LL_ENDL;
LL_INFOS("SystemInfo") << "OS info: " << getOSInfo() << LL_ENDL;
+ gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");
+ gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
+ gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
+ gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin();
+ gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
+ gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
+
writeDebugInfo(); // Save out debug_info.log early, in case of crash.
}
+#ifdef LL_WINDOWS
+//For whatever reason, in Windows when using OOP server for breakpad, the callback to get the
+//name of the dump file is not getting triggered by the breakpad library. Unfortunately they
+//also didn't see fit to provide a simple query request across the pipe to get this name either.
+//Since we are putting our output in a runtime generated directory and we know the header data in
+//the dump format, we can however use the following hack to identify our file.
+// TODO make this a member function.
+void getFileList()
+{
+ std::stringstream filenames;
+
+ typedef std::vector<std::string> vec;
+ std::string pathname = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"");
+ vec file_vec = gDirUtilp->getFilesInDir(pathname);
+ for(vec::const_iterator iter=file_vec.begin(); iter!=file_vec.end(); ++iter)
+ {
+ filenames << *iter << " ";
+ if ( ( iter->length() > 30 ) && (iter->rfind(".dmp") == (iter->length()-4) ) )
+ {
+ std::string fullname = pathname + *iter;
+ std::ifstream fdat( fullname.c_str(), std::ifstream::binary);
+ if (fdat)
+ {
+ char buf[5];
+ fdat.read(buf,4);
+ fdat.close();
+ if (!strncmp(buf,"MDMP",4))
+ {
+ gDebugInfo["Dynamic"]["MinidumpPath"] = fullname;
+ break;
+ }
+ }
+ }
+ }
+ filenames << std::endl;
+ gDebugInfo["Dynamic"]["DumpDirContents"] = filenames.str();
+}
+#endif
+
void LLAppViewer::handleViewerCrash()
{
- llinfos << "Handle viewer crash entry." << llendl;
+ LL_INFOS() << "Handle viewer crash entry." << LL_ENDL;
- llinfos << "Last render pool type: " << LLPipeline::sCurRenderPoolType << llendl ;
+ LL_INFOS() << "Last render pool type: " << LLPipeline::sCurRenderPoolType << LL_ENDL ;
LLMemory::logMemoryInfo(true) ;
@@ -3273,104 +3670,104 @@ void LLAppViewer::handleViewerCrash()
std::string crashHostUrl = gSavedSettings.get<std::string>("CrashHostUrl");
if(crashHostUrl != "")
{
- gDebugInfo["CrashHostUrl"] = crashHostUrl;
+ gDebugInfo["Dynamic"]["CrashHostUrl"] = crashHostUrl;
}
- //We already do this in writeSystemInfo(), but we do it again here to make /sure/ we have a version
- //to check against no matter what
- 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();
-
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if ( parcel && parcel->getMusicURL()[0])
{
- gDebugInfo["ParcelMusicURL"] = parcel->getMusicURL();
+ gDebugInfo["Dynamic"]["ParcelMusicURL"] = parcel->getMusicURL();
}
if ( parcel && parcel->getMediaURL()[0])
{
- gDebugInfo["ParcelMediaURL"] = parcel->getMediaURL();
+ gDebugInfo["Dynamic"]["ParcelMediaURL"] = parcel->getMediaURL();
}
- gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");
- gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
- gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
- gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
- gDebugInfo["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds());
- gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
- gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer) LLMemory::getCurrentRSS() >> 10;
- gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin();
- gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
-
- char *minidump_file = pApp->getMiniDumpFilename();
- if(minidump_file && minidump_file[0] != 0)
- {
- gDebugInfo["MinidumpPath"] = minidump_file;
- }
+ gDebugInfo["Dynamic"]["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds());
+ gDebugInfo["Dynamic"]["RAMInfo"]["Allocated"] = (LLSD::Integer) LLMemory::getCurrentRSS() >> 10;
if(gLogoutInProgress)
{
- gDebugInfo["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH;
+ gDebugInfo["Dynamic"]["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH;
}
else
{
- gDebugInfo["LastExecEvent"] = gLLErrorActivated ? LAST_EXEC_LLERROR_CRASH : LAST_EXEC_OTHER_CRASH;
+ gDebugInfo["Dynamic"]["LastExecEvent"] = gLLErrorActivated ? LAST_EXEC_LLERROR_CRASH : LAST_EXEC_OTHER_CRASH;
}
if(gAgent.getRegion())
{
- gDebugInfo["CurrentSimHost"] = gAgent.getRegionHost().getHostName();
- gDebugInfo["CurrentRegion"] = gAgent.getRegion()->getName();
+ gDebugInfo["Dynamic"]["CurrentSimHost"] = gAgent.getRegionHost().getHostName();
+ gDebugInfo["Dynamic"]["CurrentRegion"] = gAgent.getRegion()->getName();
const LLVector3& loc = gAgent.getPositionAgent();
- gDebugInfo["CurrentLocationX"] = loc.mV[0];
- gDebugInfo["CurrentLocationY"] = loc.mV[1];
- gDebugInfo["CurrentLocationZ"] = loc.mV[2];
+ gDebugInfo["Dynamic"]["CurrentLocationX"] = loc.mV[0];
+ gDebugInfo["Dynamic"]["CurrentLocationY"] = loc.mV[1];
+ gDebugInfo["Dynamic"]["CurrentLocationZ"] = loc.mV[2];
}
if(LLAppViewer::instance()->mMainloopTimeout)
{
- gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState();
+ gDebugInfo["Dynamic"]["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState();
}
// The crash is being handled here so set this value to false.
// Otherwise the crash logger will think this crash was a freeze.
- gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)false;
+ gDebugInfo["Dynamic"]["CrashNotHandled"] = (LLSD::Boolean)false;
//Write out the crash status file
//Use marker file style setup, as that's the simplest, especially since
//we're already in a crash situation
if (gDirUtilp)
{
- std::string crash_file_name;
- if(gLLErrorActivated) crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LLERROR_MARKER_FILE_NAME);
- else crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,ERROR_MARKER_FILE_NAME);
- llinfos << "Creating crash marker file " << crash_file_name << llendl;
-
- LLAPRFile crash_file ;
- crash_file.open(crash_file_name, LL_APR_W);
- if (crash_file.getFileHandle())
+ std::string crash_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
+ gLLErrorActivated
+ ? LLERROR_MARKER_FILE_NAME
+ : ERROR_MARKER_FILE_NAME);
+ LLAPRFile crash_marker_file ;
+ crash_marker_file.open(crash_marker_file_name, LL_APR_WB);
+ if (crash_marker_file.getFileHandle())
{
- LL_INFOS("MarkerFile") << "Created crash marker file " << crash_file_name << LL_ENDL;
+ LL_INFOS("MarkerFile") << "Created crash marker file " << crash_marker_file_name << LL_ENDL;
+ recordMarkerVersion(crash_marker_file);
}
else
{
- LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_file_name << LL_ENDL;
- }
+ LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_marker_file_name << LL_ENDL;
+ }
}
+ else
+ {
+ LL_WARNS("MarkerFile") << "No gDirUtilp with which to create error marker file name" << LL_ENDL;
+ }
+
+#ifdef LL_WINDOWS
+ Sleep(200);
+#endif
+
+ char *minidump_file = pApp->getMiniDumpFilename();
+
+ if(minidump_file && minidump_file[0] != 0)
+ {
+ gDebugInfo["Dynamic"]["MinidumpPath"] = minidump_file;
+ }
+#ifdef LL_WINDOWS
+ else
+ {
+ getFileList();
+ }
+#endif
+ gDebugInfo["Dynamic"]["CrashType"]="crash";
if (gMessageSystem && gDirUtilp)
{
std::string filename;
- filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "stats.log");
- llofstream file(filename, llofstream::binary);
+ filename = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "stats.log");
+ llofstream file(filename.c_str(), std::ios_base::binary);
if(file.good())
{
- llinfos << "Handle viewer crash generating stats log." << llendl;
+ LL_INFOS() << "Handle viewer crash generating stats log." << LL_ENDL;
gMessageSystem->summarizeLogs(file);
file.close();
}
@@ -3382,71 +3779,58 @@ void LLAppViewer::handleViewerCrash()
gMessageSystem->stopLogging();
}
- if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo);
+ if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo["Dynamic"]);
// Close the debug file
- pApp->writeDebugInfo();
-
- LLError::logToFile("");
+ pApp->writeDebugInfo(false); //false answers the isStatic question with the least overhead.
+}
- // Remove the marker file, since otherwise we'll spawn a process that'll keep it locked
- if(gDebugInfo["LastExecEvent"].asInteger() == LAST_EXEC_LOGOUT_CRASH)
- {
- pApp->removeMarkerFile(true);
- }
- else
+// static
+void LLAppViewer::recordMarkerVersion(LLAPRFile& marker_file)
+{
+ std::string marker_version(LLVersionInfo::getChannelAndVersion());
+ if ( marker_version.length() > MAX_MARKER_LENGTH )
{
- pApp->removeMarkerFile(false);
+ LL_WARNS_ONCE("MarkerFile") << "Version length ("<< marker_version.length()<< ")"
+ << " greater than maximum (" << MAX_MARKER_LENGTH << ")"
+ << ": marker matching may be incorrect"
+ << LL_ENDL;
}
-
-#if LL_SEND_CRASH_REPORTS
- // Call to pure virtual, handled by platform specific llappviewer instance.
- pApp->handleCrashReporting();
-#endif
-
- return;
+
+ // record the viewer version in the marker file
+ marker_file.write(marker_version.data(), marker_version.length());
}
-bool LLAppViewer::anotherInstanceRunning()
+bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const
{
- // We create a marker file when the program starts and remove the file when it finishes.
- // If the file is currently locked, that means another process is already running.
+ bool sameVersion = false;
- std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, MARKER_FILE_NAME);
- LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL;
+ std::string my_version(LLVersionInfo::getChannelAndVersion());
+ char marker_version[MAX_MARKER_LENGTH];
+ S32 marker_version_length;
- //Freeze case checks
- if (LLAPRFile::isExist(marker_file, NULL, LL_APR_RB))
+ LLAPRFile marker_file;
+ marker_file.open(marker_name, LL_APR_RB);
+ if (marker_file.getFileHandle())
{
- // File exists, try opening with write permissions
- LLAPRFile outfile ;
- outfile.open(marker_file, LL_APR_WB);
- apr_file_t* fMarker = outfile.getFileHandle() ;
- if (!fMarker)
+ marker_version_length = marker_file.read(marker_version, sizeof(marker_version));
+ std::string marker_string(marker_version, marker_version_length);
+ if ( 0 == my_version.compare( 0, my_version.length(), marker_version, 0, marker_version_length ) )
{
- // Another instance is running. Skip the rest of these operations.
- LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL;
- return true;
+ sameVersion = true;
}
- if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) //flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1)
- {
- LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL;
- return true;
- }
- // No other instances; we'll lock this file now & delete on quit.
- }
- LL_DEBUGS("MarkerFile") << "Marker file isn't locked." << LL_ENDL;
- return false;
+ LL_DEBUGS("MarkerFile") << "Compare markers for '" << marker_name << "': "
+ << "\n mine '" << my_version << "'"
+ << "\n marker '" << marker_string << "'"
+ << "\n " << ( sameVersion ? "same" : "different" ) << " version"
+ << LL_ENDL;
+ marker_file.close();
+ }
+ return sameVersion;
}
-void LLAppViewer::initMarkerFile()
+void LLAppViewer::processMarkerFiles()
{
- //First, check for the existence of other files.
- //There are marker files for two different types of crashes
-
- mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME);
- LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL;
-
//We've got 4 things to test for here
// - Other Process Running (SecondLife.exec_marker present, locked)
// - Freeze (SecondLife.exec_marker present, not locked)
@@ -3454,79 +3838,185 @@ void LLAppViewer::initMarkerFile()
// - Other Crash (SecondLife.error_marker present)
// These checks should also remove these files for the last 2 cases if they currently exist
- //LLError/Error checks. Only one of these should ever happen at a time.
- std::string logout_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME);
- std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);
- std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
+ bool marker_is_same_version = true;
+ // first, look for the marker created at startup and deleted on a clean exit
+ mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME);
+ if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB))
+ {
+ // File exists...
+ // first, read it to see if it was created by the same version (we need this later)
+ marker_is_same_version = markerIsSameVersion(mMarkerFileName);
+
+ // now test to see if this file is locked by a running process (try to open for write)
+ LL_DEBUGS("MarkerFile") << "Checking exec marker file for lock..." << LL_ENDL;
+ mMarkerFile.open(mMarkerFileName, LL_APR_WB);
+ apr_file_t* fMarker = mMarkerFile.getFileHandle() ;
+ if (!fMarker)
+ {
+ LL_INFOS("MarkerFile") << "Exec marker file open failed - assume it is locked." << LL_ENDL;
+ mSecondInstance = true; // lock means that instance is running.
+ }
+ else
+ {
+ // We were able to open it, now try to lock it ourselves...
+ if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS)
+ {
+ LL_WARNS_ONCE("MarkerFile") << "Locking exec marker failed." << LL_ENDL;
+ mSecondInstance = true; // lost a race? be conservative
+ }
+ else
+ {
+ // No other instances; we've locked this file now, so record our version; delete on quit.
+ recordMarkerVersion(mMarkerFile);
+ LL_DEBUGS("MarkerFile") << "Exec marker file existed but was not locked; rewritten." << LL_ENDL;
+ }
+ }
- if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB) && !anotherInstanceRunning())
+ if (mSecondInstance)
+ {
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' owned by another instance" << LL_ENDL;
+ }
+ else if (marker_is_same_version)
+ {
+ // the file existed, is ours, and matched our version, so we can report on what it says
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec FROZE" << LL_ENDL;
+ gLastExecEvent = LAST_EXEC_FROZE;
+
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found, but versions did not match" << LL_ENDL;
+ }
+ }
+ else // marker did not exist... last exec (if any) did not freeze
{
- gLastExecEvent = LAST_EXEC_FROZE;
- LL_INFOS("MarkerFile") << "Exec marker found: program froze on previous execution" << LL_ENDL;
- }
+ // Create the marker file for this execution & lock it; it will be deleted on a clean exit
+ apr_status_t s;
+ s = mMarkerFile.open(mMarkerFileName, LL_APR_WB, TRUE);
+
+ if (s == APR_SUCCESS && mMarkerFile.getFileHandle())
+ {
+ LL_DEBUGS("MarkerFile") << "Exec marker file '"<< mMarkerFileName << "' created." << LL_ENDL;
+ if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE))
+ {
+ recordMarkerVersion(mMarkerFile);
+ LL_DEBUGS("MarkerFile") << "Exec marker file locked." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "Exec marker file cannot be locked." << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "Failed to create exec marker file '"<< mMarkerFileName << "'." << LL_ENDL;
+ }
+ }
+
+ // now check for cases in which the exec marker may have been cleaned up by crash handlers
+
+ // check for any last exec event report based on whether or not it happened during logout
+ // (the logout marker is created when logout begins)
+ std::string logout_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME);
if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB))
{
- gLastExecEvent = LAST_EXEC_LOGOUT_FROZE;
- LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ if (markerIsSameVersion(logout_marker_file))
+ {
+ gLastExecEvent = LAST_EXEC_LOGOUT_FROZE;
+ LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "', changing LastExecEvent to LOGOUT_FROZE" << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "' found, but versions did not match" << LL_ENDL;
+ }
LLAPRFile::remove(logout_marker_file);
}
+ // further refine based on whether or not a marker created during an llerr crash is found
+ std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);
if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))
{
- if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
- else gLastExecEvent = LAST_EXEC_LLERROR_CRASH;
- LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ if (markerIsSameVersion(llerror_marker_file))
+ {
+ if ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE )
+ {
+ gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
+ LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
+ }
+ else
+ {
+ gLastExecEvent = LAST_EXEC_LLERROR_CRASH;
+ LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LLERROR_CRASH" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL;
+ }
LLAPRFile::remove(llerror_marker_file);
}
+ // and last refine based on whether or not a marker created during a non-llerr crash is found
+ std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
{
- if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
- else gLastExecEvent = LAST_EXEC_OTHER_CRASH;
- LL_INFOS("MarkerFile") << "Last exec crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ if (markerIsSameVersion(error_marker_file))
+ {
+ if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE)
+ {
+ gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
+ LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
+ }
+ else
+ {
+ gLastExecEvent = LAST_EXEC_OTHER_CRASH;
+ LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL;
+ }
LLAPRFile::remove(error_marker_file);
}
+}
- // No new markers if another instance is running.
- if(anotherInstanceRunning())
- {
- return;
- }
-
- // Create the marker file for this execution & lock it
- apr_status_t s;
- s = mMarkerFile.open(mMarkerFileName, LL_APR_W, TRUE);
+void LLAppViewer::removeMarkerFiles()
+{
+ if (!mSecondInstance)
+ {
+ if (mMarkerFile.getFileHandle())
+ {
+ mMarkerFile.close() ;
+ LLAPRFile::remove( mMarkerFileName );
+ LL_DEBUGS("MarkerFile") << "removed exec marker '"<<mMarkerFileName<<"'"<< LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL;
+ }
- if (s == APR_SUCCESS && mMarkerFile.getFileHandle())
- {
- LL_DEBUGS("MarkerFile") << "Marker file created." << LL_ENDL;
+ if (mLogoutMarkerFile.getFileHandle())
+ {
+ mLogoutMarkerFile.close();
+ LLAPRFile::remove( mLogoutMarkerFileName );
+ LL_DEBUGS("MarkerFile") << "removed logout marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "logout marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL;
+ }
}
else
{
- LL_INFOS("MarkerFile") << "Failed to create marker file." << LL_ENDL;
- return;
- }
- if (apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS)
- {
- mMarkerFile.close() ;
- LL_INFOS("MarkerFile") << "Marker file cannot be locked." << LL_ENDL;
- return;
+ LL_WARNS("MarkerFile") << "leaving markers because this is a second instance" << LL_ENDL;
}
-
- LL_DEBUGS("MarkerFile") << "Marker file locked." << LL_ENDL;
}
-void LLAppViewer::removeMarkerFile(bool leave_logout_marker)
+void LLAppViewer::removeDumpDir()
{
- LL_DEBUGS("MarkerFile") << "removeMarkerFile()" << LL_ENDL;
- if (mMarkerFile.getFileHandle())
- {
- mMarkerFile.close() ;
- LLAPRFile::remove( mMarkerFileName );
- }
- if (mLogoutMarkerFile != NULL && !leave_logout_marker)
- {
- LLAPRFile::remove( mLogoutMarkerFileName );
- mLogoutMarkerFile = NULL;
- }
+ //Call this routine only on clean exit. Crash reporter will clean up
+ //its locking table for us.
+ std::string dump_dir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
+ gDirUtilp->deleteDirAndContents(dump_dir);
}
void LLAppViewer::forceQuit()
@@ -3546,14 +4036,14 @@ void LLAppViewer::fastQuit(S32 error_code)
// figure out the error code
S32 final_error_code = error_code ? error_code : (S32)isError();
// this isn't a crash
- removeMarkerFile();
+ removeMarkerFiles();
// get outta here
_exit(final_error_code);
}
void LLAppViewer::requestQuit()
{
- llinfos << "requestQuit" << llendl;
+ LL_INFOS() << "requestQuit" << LL_ENDL;
LLViewerRegion* region = gAgent.getRegion();
@@ -3573,6 +4063,18 @@ void LLAppViewer::requestQuit()
// Try to send metrics back to the grid
metricsSend(!gDisconnected);
+
+ // Try to send last batch of avatar rez metrics.
+ if (!gDisconnected && isAgentAvatarValid())
+ {
+ gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent.
+ }
+
+ // Try to send last batch of avatar rez metrics.
+ if (!gDisconnected && isAgentAvatarValid())
+ {
+ gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent.
+ }
LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
effectp->setPositionGlobal(gAgent.getPositionGlobal());
@@ -3626,7 +4128,7 @@ static bool finish_early_exit(const LLSD& notification, const LLSD& response)
void LLAppViewer::earlyExit(const std::string& name, const LLSD& substitutions)
{
- llwarns << "app_early_exit: " << name << llendl;
+ LL_WARNS() << "app_early_exit: " << name << LL_ENDL;
gDoDisconnect = TRUE;
LLNotificationsUtil::add(name, substitutions, LLSD(), finish_early_exit);
}
@@ -3634,14 +4136,14 @@ void LLAppViewer::earlyExit(const std::string& name, const LLSD& substitutions)
// case where we need the viewer to exit without any need for notifications
void LLAppViewer::earlyExitNoNotify()
{
- llwarns << "app_early_exit with no notification: " << llendl;
+ LL_WARNS() << "app_early_exit with no notification: " << LL_ENDL;
gDoDisconnect = TRUE;
finish_early_exit( LLSD(), LLSD() );
}
void LLAppViewer::abortQuit()
{
- llinfos << "abortQuit()" << llendl;
+ LL_INFOS() << "abortQuit()" << LL_ENDL;
mQuitRequested = false;
}
@@ -3673,7 +4175,7 @@ void LLAppViewer::migrateCacheDirectory()
if (gDirUtilp->fileExists(old_cache_dir))
{
- llinfos << "Migrating cache from " << old_cache_dir << " to " << new_cache_dir << llendl;
+ LL_INFOS() << "Migrating cache from " << old_cache_dir << " to " << new_cache_dir << LL_ENDL;
// Migrate inventory cache to avoid pain to inventory database after mass update
S32 file_count = 0;
@@ -3691,7 +4193,7 @@ void LLAppViewer::migrateCacheDirectory()
file_count++;
}
}
- llinfos << "Moved " << file_count << " files" << llendl;
+ LL_INFOS() << "Moved " << file_count << " files" << LL_ENDL;
// Nuke the old cache
gDirUtilp->setCacheDir(old_cache_dir);
@@ -3708,7 +4210,7 @@ void LLAppViewer::migrateCacheDirectory()
#endif
if (LLFile::rmdir(old_cache_dir) != 0)
{
- llwarns << "could not delete old cache directory " << old_cache_dir << llendl;
+ LL_WARNS() << "could not delete old cache directory " << old_cache_dir << LL_ENDL;
}
}
}
@@ -3717,10 +4219,10 @@ void LLAppViewer::migrateCacheDirectory()
void dumpVFSCaches()
{
- llinfos << "======= Static VFS ========" << llendl;
+ LL_INFOS() << "======= Static VFS ========" << LL_ENDL;
gStaticVFS->listFiles();
#if LL_WINDOWS
- llinfos << "======= Dumping static VFS to StaticVFSDump ========" << llendl;
+ LL_INFOS() << "======= Dumping static VFS to StaticVFSDump ========" << LL_ENDL;
WCHAR w_str[MAX_PATH];
GetCurrentDirectory(MAX_PATH, w_str);
S32 res = LLFile::mkdir("StaticVFSDump");
@@ -3728,7 +4230,7 @@ void dumpVFSCaches()
{
if (errno != EEXIST)
{
- llwarns << "Couldn't create dir StaticVFSDump" << llendl;
+ LL_WARNS() << "Couldn't create dir StaticVFSDump" << LL_ENDL;
}
}
SetCurrentDirectory(utf8str_to_utf16str("StaticVFSDump").c_str());
@@ -3736,16 +4238,16 @@ void dumpVFSCaches()
SetCurrentDirectory(w_str);
#endif
- llinfos << "========= Dynamic VFS ====" << llendl;
+ LL_INFOS() << "========= Dynamic VFS ====" << LL_ENDL;
gVFS->listFiles();
#if LL_WINDOWS
- llinfos << "========= Dumping dynamic VFS to VFSDump ====" << llendl;
+ LL_INFOS() << "========= Dumping dynamic VFS to VFSDump ====" << LL_ENDL;
res = LLFile::mkdir("VFSDump");
if (res == -1)
{
if (errno != EEXIST)
{
- llwarns << "Couldn't create dir VFSDump" << llendl;
+ LL_WARNS() << "Couldn't create dir VFSDump" << LL_ENDL;
}
}
SetCurrentDirectory(utf8str_to_utf16str("VFSDump").c_str());
@@ -3923,7 +4425,7 @@ bool LLAppViewer::initCache()
{
sscanf(found_file.substr(start_pos+1).c_str(), "%d", &old_salt);
}
- LL_DEBUGS("AppCache") << "Default vfs data file not present, found: " << old_vfs_data_file << " Old salt: " << old_salt << llendl;
+ LL_DEBUGS("AppCache") << "Default vfs data file not present, found: " << old_vfs_data_file << " Old salt: " << old_salt << LL_ENDL;
}
}
@@ -4025,6 +4527,14 @@ void LLAppViewer::purgeCache()
gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*.*");
}
+//purge cache immediately, do not wait until the next login.
+void LLAppViewer::purgeCacheImmediate()
+{
+ LL_INFOS("AppCache") << "Purging Object Cache and Texture Cache immediately..." << LL_ENDL;
+ LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE, false);
+ LLVOCache::getInstance()->removeCache(LL_PATH_CACHE, true);
+}
+
std::string LLAppViewer::getSecondLifeTitle() const
{
return LLTrans::getString("APP_NAME");
@@ -4142,17 +4652,22 @@ void LLAppViewer::loadNameCache()
std::string filename =
gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml");
LL_INFOS("AvNameCache") << filename << LL_ENDL;
- llifstream name_cache_stream(filename);
+ llifstream name_cache_stream(filename.c_str());
if(name_cache_stream.is_open())
{
- LLAvatarNameCache::importFile(name_cache_stream);
+ if ( ! LLAvatarNameCache::importFile(name_cache_stream))
+ {
+ LL_WARNS("AppInit") << "removing invalid '" << filename << "'" << LL_ENDL;
+ name_cache_stream.close();
+ LLFile::remove(filename);
+ }
}
if (!gCacheName) return;
std::string name_cache;
name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache");
- llifstream cache_file(name_cache);
+ llifstream cache_file(name_cache.c_str());
if(cache_file.is_open())
{
if(gCacheName->importFile(cache_file)) return;
@@ -4160,24 +4675,26 @@ void LLAppViewer::loadNameCache()
}
void LLAppViewer::saveNameCache()
- {
+{
// display names cache
std::string filename =
gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml");
- llofstream name_cache_stream(filename);
+ llofstream name_cache_stream(filename.c_str());
if(name_cache_stream.is_open())
{
LLAvatarNameCache::exportFile(name_cache_stream);
-}
-
- if (!gCacheName) return;
-
- std::string name_cache;
- name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache");
- llofstream cache_file(name_cache);
- if(cache_file.is_open())
- {
- gCacheName->exportFile(cache_file);
+ }
+
+ // real names cache
+ if (gCacheName)
+ {
+ std::string name_cache;
+ name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache");
+ llofstream cache_file(name_cache.c_str());
+ if(cache_file.is_open())
+ {
+ gCacheName->exportFile(cache_file);
+ }
}
}
@@ -4197,18 +4714,20 @@ public:
}
};
-static LLFastTimer::DeclareTimer FTM_AUDIO_UPDATE("Update Audio");
-static LLFastTimer::DeclareTimer FTM_CLEANUP("Cleanup");
-static LLFastTimer::DeclareTimer FTM_CLEANUP_DRAWABLES("Drawables");
-static LLFastTimer::DeclareTimer FTM_CLEANUP_OBJECTS("Objects");
-static LLFastTimer::DeclareTimer FTM_IDLE_CB("Idle Callbacks");
-static LLFastTimer::DeclareTimer FTM_LOD_UPDATE("Update LOD");
-static LLFastTimer::DeclareTimer FTM_OBJECTLIST_UPDATE("Update Objectlist");
-static LLFastTimer::DeclareTimer FTM_REGION_UPDATE("Update Region");
-static LLFastTimer::DeclareTimer FTM_WORLD_UPDATE("Update World");
-static LLFastTimer::DeclareTimer FTM_NETWORK("Network");
-static LLFastTimer::DeclareTimer FTM_AGENT_NETWORK("Agent Network");
-static LLFastTimer::DeclareTimer FTM_VLMANAGER("VL Manager");
+static LLTrace::BlockTimerStatHandle FTM_AUDIO_UPDATE("Update Audio");
+static LLTrace::BlockTimerStatHandle FTM_CLEANUP("Cleanup");
+static LLTrace::BlockTimerStatHandle FTM_CLEANUP_DRAWABLES("Drawables");
+static LLTrace::BlockTimerStatHandle FTM_CLEANUP_OBJECTS("Objects");
+static LLTrace::BlockTimerStatHandle FTM_IDLE_CB("Idle Callbacks");
+static LLTrace::BlockTimerStatHandle FTM_LOD_UPDATE("Update LOD");
+static LLTrace::BlockTimerStatHandle FTM_OBJECTLIST_UPDATE("Update Objectlist");
+static LLTrace::BlockTimerStatHandle FTM_REGION_UPDATE("Update Region");
+static LLTrace::BlockTimerStatHandle FTM_WORLD_UPDATE("Update World");
+static LLTrace::BlockTimerStatHandle FTM_NETWORK("Network");
+static LLTrace::BlockTimerStatHandle FTM_AGENT_NETWORK("Agent Network");
+static LLTrace::BlockTimerStatHandle FTM_VLMANAGER("VL Manager");
+static LLTrace::BlockTimerStatHandle FTM_AGENT_POSITION("Agent Position");
+static LLTrace::BlockTimerStatHandle FTM_HUD_EFFECTS("HUD Effects");
///////////////////////////////////////////////////////
// idle()
@@ -4227,7 +4746,7 @@ void LLAppViewer::idle()
LLFrameTimer::updateFrameCount();
LLEventTimer::updateClass();
LLNotificationsUI::LLToast::updateClass();
- LLCriticalDamp::updateInterpolants();
+ LLSmoothInterpolation::updateInterpolants();
LLMortician::updateClass();
LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify()
@@ -4252,6 +4771,7 @@ void LLAppViewer::idle()
{
if (gRenderStartTime.getElapsedTimeF32() > qas)
{
+ LL_INFOS() << "Quitting after " << qas << " seconds. See setting \"QuitAfterSeconds\"." << LL_ENDL;
LLAppViewer::instance()->forceQuit();
}
}
@@ -4281,9 +4801,9 @@ void LLAppViewer::idle()
if (!gDisconnected)
{
- LLFastTimer t(FTM_NETWORK);
+ LL_RECORD_BLOCK_TIME(FTM_NETWORK);
// Update spaceserver timeinfo
- LLWorld::getInstance()->setSpaceTimeUSec(LLWorld::getInstance()->getSpaceTimeUSec() + (U32)(dt_raw * SEC_TO_MICROSEC));
+ LLWorld::getInstance()->setSpaceTimeUSec(LLWorld::getInstance()->getSpaceTimeUSec() + LLUnits::Seconds::fromValue(dt_raw));
//////////////////////////////////////
@@ -4297,27 +4817,29 @@ void LLAppViewer::idle()
}
{
- LLFastTimer t(FTM_AGENT_AUTOPILOT);
+ LL_RECORD_BLOCK_TIME(FTM_AGENT_AUTOPILOT);
// Handle automatic walking towards points
gAgentPilot.updateTarget();
gAgent.autoPilot(&yaw);
}
-
- static LLFrameTimer agent_update_timer;
- static U32 last_control_flags;
-
- // When appropriate, update agent location to the simulator.
- F32 agent_update_time = agent_update_timer.getElapsedTimeF32();
- BOOL flags_changed = gAgent.controlFlagsDirty() || (last_control_flags != gAgent.getControlFlags());
-
- if (flags_changed || (agent_update_time > (1.0f / (F32) AGENT_UPDATES_PER_SECOND)))
- {
- LLFastTimer t(FTM_AGENT_UPDATE);
- // Send avatar and camera info
- last_control_flags = gAgent.getControlFlags();
- send_agent_update(TRUE);
- agent_update_timer.reset();
- }
+
+ static LLFrameTimer agent_update_timer;
+
+ // When appropriate, update agent location to the simulator.
+ F32 agent_update_time = agent_update_timer.getElapsedTimeF32();
+ F32 agent_force_update_time = mLastAgentForceUpdate + agent_update_time;
+ BOOL force_update = gAgent.controlFlagsDirty()
+ || (mLastAgentControlFlags != gAgent.getControlFlags())
+ || (agent_force_update_time > (1.0f / (F32) AGENT_FORCE_UPDATES_PER_SECOND));
+ if (force_update || (agent_update_time > (1.0f / (F32) AGENT_UPDATES_PER_SECOND)))
+ {
+ LL_RECORD_BLOCK_TIME(FTM_AGENT_UPDATE);
+ // Send avatar and camera info
+ mLastAgentControlFlags = gAgent.getControlFlags();
+ mLastAgentForceUpdate = force_update ? 0 : agent_force_update_time;
+ send_agent_update(force_update);
+ agent_update_timer.reset();
+ }
}
//////////////////////////////////////
@@ -4332,10 +4854,10 @@ void LLAppViewer::idle()
static LLFrameStatsTimer viewer_stats_timer(SEND_STATS_PERIOD);
// Update session stats every large chunk of time
- // *FIX: (???) SAMANTHA
+ // *FIX: (?) SAMANTHA
if (viewer_stats_timer.getElapsedTimeF32() >= SEND_STATS_PERIOD && !gDisconnected)
{
- llinfos << "Transmitting sessions stats" << llendl;
+ LL_INFOS() << "Transmitting sessions stats" << LL_ENDL;
send_stats();
viewer_stats_timer.reset();
}
@@ -4347,31 +4869,21 @@ void LLAppViewer::idle()
object_debug_timer.reset();
if (gObjectList.mNumDeadObjectUpdates)
{
- llinfos << "Dead object updates: " << gObjectList.mNumDeadObjectUpdates << llendl;
+ LL_INFOS() << "Dead object updates: " << gObjectList.mNumDeadObjectUpdates << LL_ENDL;
gObjectList.mNumDeadObjectUpdates = 0;
}
- if (gObjectList.mNumUnknownKills)
- {
- llinfos << "Kills on unknown objects: " << gObjectList.mNumUnknownKills << llendl;
- gObjectList.mNumUnknownKills = 0;
- }
if (gObjectList.mNumUnknownUpdates)
{
- llinfos << "Unknown object updates: " << gObjectList.mNumUnknownUpdates << llendl;
+ LL_INFOS() << "Unknown object updates: " << gObjectList.mNumUnknownUpdates << LL_ENDL;
gObjectList.mNumUnknownUpdates = 0;
}
- // ViewerMetrics FPS piggy-backing on the debug timer.
- // The 5-second interval is nice for this purpose. If the object debug
- // bit moves or is disabled, please give this a suitable home.
- LLViewerAssetStatsFF::record_fps_main(gFPSClamped);
- LLViewerAssetStatsFF::record_avatar_stats();
}
}
if (!gDisconnected)
{
- LLFastTimer t(FTM_NETWORK);
+ LL_RECORD_BLOCK_TIME(FTM_NETWORK);
////////////////////////////////////////////////
//
@@ -4397,9 +4909,12 @@ void LLAppViewer::idle()
// Handle the regular UI idle callbacks as well as
// hover callbacks
//
-
+
+#ifdef LL_DARWIN
+ if (!mQuitRequested) //MAINT-4243
+#endif
{
-// LLFastTimer t(FTM_IDLE_CB);
+// LL_RECORD_BLOCK_TIME(FTM_IDLE_CB);
// Do event notifications if necessary. Yes, we may want to move this elsewhere.
gEventNotifier.update();
@@ -4446,19 +4961,18 @@ void LLAppViewer::idle()
{
// Handle pending gesture processing
- static LLFastTimer::DeclareTimer ftm("Agent Position");
- LLFastTimer t(ftm);
+ LL_RECORD_BLOCK_TIME(FTM_AGENT_POSITION);
LLGestureMgr::instance().update();
gAgent.updateAgentPosition(gFrameDTClamped, yaw, current_mouse.mX, current_mouse.mY);
}
{
- LLFastTimer t(FTM_OBJECTLIST_UPDATE);
+ LL_RECORD_BLOCK_TIME(FTM_OBJECTLIST_UPDATE);
if (!(logoutRequestSent() && hasSavedFinalSnapshot()))
{
- gObjectList.update(gAgent, *LLWorld::getInstance());
+ gObjectList.update(gAgent);
}
}
@@ -4469,13 +4983,13 @@ void LLAppViewer::idle()
//
{
- LLFastTimer t(FTM_CLEANUP);
+ LL_RECORD_BLOCK_TIME(FTM_CLEANUP);
{
- LLFastTimer t(FTM_CLEANUP_OBJECTS);
+ LL_RECORD_BLOCK_TIME(FTM_CLEANUP_OBJECTS);
gObjectList.cleanDeadObjects();
}
{
- LLFastTimer t(FTM_CLEANUP_DRAWABLES);
+ LL_RECORD_BLOCK_TIME(FTM_CLEANUP_DRAWABLES);
LLDrawable::cleanupDeadDrawables();
}
}
@@ -4494,8 +5008,7 @@ void LLAppViewer::idle()
//
{
- static LLFastTimer::DeclareTimer ftm("HUD Effects");
- LLFastTimer t(ftm);
+ LL_RECORD_BLOCK_TIME(FTM_HUD_EFFECTS);
LLSelectMgr::getInstance()->updateEffects();
LLHUDManager::getInstance()->cleanupEffects();
LLHUDManager::getInstance()->sendEffects();
@@ -4507,7 +5020,7 @@ void LLAppViewer::idle()
//
{
- LLFastTimer t(FTM_NETWORK);
+ LL_RECORD_BLOCK_TIME(FTM_NETWORK);
gVLManager.unpackData();
}
@@ -4519,7 +5032,7 @@ void LLAppViewer::idle()
LLWorld::getInstance()->updateVisibilities();
{
const F32 max_region_update_time = .001f; // 1ms
- LLFastTimer t(FTM_REGION_UPDATE);
+ LL_RECORD_BLOCK_TIME(FTM_REGION_UPDATE);
LLWorld::getInstance()->updateRegions(max_region_update_time);
}
@@ -4556,7 +5069,7 @@ void LLAppViewer::idle()
// Here, particles are updated and drawables are moved.
//
- LLFastTimer t(FTM_WORLD_UPDATE);
+ LL_RECORD_BLOCK_TIME(FTM_WORLD_UPDATE);
gPipeline.updateMove();
LLWorld::getInstance()->updateParticles();
@@ -4588,12 +5101,15 @@ void LLAppViewer::idle()
// objects and camera should be in sync, do LOD calculations now
{
- LLFastTimer t(FTM_LOD_UPDATE);
+ LL_RECORD_BLOCK_TIME(FTM_LOD_UPDATE);
gObjectList.updateApparentAngles(gAgent);
}
+ // Update AV render info
+ LLAvatarRenderInfoAccountant::idle();
+
{
- LLFastTimer t(FTM_AUDIO_UPDATE);
+ LL_RECORD_BLOCK_TIME(FTM_AUDIO_UPDATE);
if (gAudiop)
{
@@ -4681,6 +5197,13 @@ void LLAppViewer::idleShutdown()
return;
}
+ if (gPendingMetricsUploads > 0
+ && gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME
+ && !logoutRequestSent())
+ {
+ return;
+ }
+
// All floaters are closed. Tell server we want to quit.
if( !logoutRequestSent() )
{
@@ -4706,6 +5229,28 @@ void LLAppViewer::sendLogoutRequest()
{
if(!mLogoutRequestSent && gMessageSystem)
{
+ //Set internal status variables and marker files before actually starting the logout process
+ gLogoutInProgress = TRUE;
+ if (!mSecondInstance)
+ {
+ mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
+
+ mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB);
+ if (mLogoutMarkerFile.getFileHandle())
+ {
+ LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL;
+ recordMarkerVersion(mLogoutMarkerFile);
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Did not logout marker file because this is a second instance" << LL_ENDL;
+ }
+
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_LogoutRequest);
msg->nextBlockFast(_PREHASH_AgentData);
@@ -4721,23 +5266,6 @@ void LLAppViewer::sendLogoutRequest()
{
LLVoiceClient::getInstance()->leaveChannel();
}
-
- //Set internal status variables and marker files
- gLogoutInProgress = TRUE;
- mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
-
- LLAPRFile outfile ;
- outfile.open(mLogoutMarkerFileName, LL_APR_W);
- mLogoutMarkerFile = outfile.getFileHandle() ;
- if (mLogoutMarkerFile)
- {
- llinfos << "Created logout marker file " << mLogoutMarkerFileName << llendl;
- apr_file_close(mLogoutMarkerFile);
- }
- else
- {
- llwarns << "Cannot create logout marker file " << mLogoutMarkerFileName << llendl;
- }
}
}
@@ -4806,12 +5334,12 @@ void LLAppViewer::idleNameCache()
static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
#endif
-static LLFastTimer::DeclareTimer FTM_IDLE_NETWORK("Idle Network");
-static LLFastTimer::DeclareTimer FTM_MESSAGE_ACKS("Message Acks");
-static LLFastTimer::DeclareTimer FTM_RETRANSMIT("Retransmit");
-static LLFastTimer::DeclareTimer FTM_TIMEOUT_CHECK("Timeout Check");
-static LLFastTimer::DeclareTimer FTM_DYNAMIC_THROTTLE("Dynamic Throttle");
-static LLFastTimer::DeclareTimer FTM_CHECK_REGION_CIRCUIT("Check Region Circuit");
+static LLTrace::BlockTimerStatHandle FTM_IDLE_NETWORK("Idle Network");
+static LLTrace::BlockTimerStatHandle FTM_MESSAGE_ACKS("Message Acks");
+static LLTrace::BlockTimerStatHandle FTM_RETRANSMIT("Retransmit");
+static LLTrace::BlockTimerStatHandle FTM_TIMEOUT_CHECK("Timeout Check");
+static LLTrace::BlockTimerStatHandle FTM_DYNAMIC_THROTTLE("Dynamic Throttle");
+static LLTrace::BlockTimerStatHandle FTM_CHECK_REGION_CIRCUIT("Check Region Circuit");
void LLAppViewer::idleNetwork()
{
@@ -4822,7 +5350,7 @@ void LLAppViewer::idleNetwork()
if (!gSavedSettings.getBOOL("SpeedTest"))
{
- LLFastTimer t(FTM_IDLE_NETWORK); // decode
+ LL_RECORD_BLOCK_TIME(FTM_IDLE_NETWORK); // decode
LLTimer check_message_timer;
// Read all available packets from network
@@ -4859,7 +5387,7 @@ void LLAppViewer::idleNetwork()
}
// Handle per-frame message system processing.
- gMessageSystem->processAcks();
+ gMessageSystem->processAcks(gSavedSettings.getF32("AckCollectTime"));
#ifdef TIME_THROTTLE_MESSAGES
if (total_time >= CheckMessagesMaxTime)
@@ -4884,16 +5412,16 @@ void LLAppViewer::idleNetwork()
if( remaining_possible_decodes <= 0 )
{
- llinfos << "Maxed out number of messages per frame at " << MESSAGE_MAX_PER_FRAME << llendl;
+ LL_INFOS() << "Maxed out number of messages per frame at " << MESSAGE_MAX_PER_FRAME << LL_ENDL;
}
if (gPrintMessagesThisFrame)
{
- llinfos << "Decoded " << total_decoded << " msgs this frame!" << llendl;
+ LL_INFOS() << "Decoded " << total_decoded << " msgs this frame!" << LL_ENDL;
gPrintMessagesThisFrame = FALSE;
}
}
- LLViewerStats::getInstance()->mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects);
+ add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects);
// Retransmit unacknowledged packets.
gXferManager->retransmitUnackedPackets();
@@ -4928,7 +5456,7 @@ void LLAppViewer::disconnectViewer()
//
// Save snapshot for next time, if we made it through initialization
- llinfos << "Disconnecting viewer!" << llendl;
+ LL_INFOS() << "Disconnecting viewer!" << LL_ENDL;
// Dump our frame statistics
@@ -4972,6 +5500,7 @@ void LLAppViewer::disconnectViewer()
{
LLWorld::getInstance()->destroyClass();
}
+ LLVOCache::deleteSingleton();
// call all self-registered classes
LLDestroyClassList::instance().fireCallbacks();
@@ -4986,11 +5515,12 @@ void LLAppViewer::disconnectViewer()
void LLAppViewer::forceErrorLLError()
{
- llerrs << "This is an llerror" << llendl;
+ LL_ERRS() << "This is a deliberate llerror" << LL_ENDL;
}
void LLAppViewer::forceErrorBreakpoint()
{
+ LL_WARNS() << "Forcing a deliberate breakpoint" << LL_ENDL;
#ifdef LL_WINDOWS
DebugBreak();
#endif
@@ -4999,6 +5529,7 @@ void LLAppViewer::forceErrorBreakpoint()
void LLAppViewer::forceErrorBadMemoryAccess()
{
+ LL_WARNS() << "Forcing a deliberate bad memory access" << LL_ENDL;
S32* crash = NULL;
*crash = 0xDEADBEEF;
return;
@@ -5006,6 +5537,7 @@ void LLAppViewer::forceErrorBadMemoryAccess()
void LLAppViewer::forceErrorInfiniteLoop()
{
+ LL_WARNS() << "Forcing a deliberate infinite loop" << LL_ENDL;
while(true)
{
;
@@ -5015,12 +5547,14 @@ void LLAppViewer::forceErrorInfiniteLoop()
void LLAppViewer::forceErrorSoftwareException()
{
+ LL_WARNS() << "Forcing a deliberate exception" << LL_ENDL;
// *FIX: Any way to insure it won't be handled?
throw;
}
void LLAppViewer::forceErrorDriverCrash()
{
+ LL_WARNS() << "Forcing a deliberate driver crash" << LL_ENDL;
glDeleteTextures(1, NULL);
}
@@ -5068,7 +5602,7 @@ void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs)
{
// if(!restoreErrorTrap())
// {
-// llwarns << "!!!!!!!!!!!!! Its an error trap!!!!" << state << llendl;
+// LL_WARNS() << "!!!!!!!!!!!!! Its an error trap!!!!" << state << LL_ENDL;
// }
if(mMainloopTimeout)
@@ -5127,23 +5661,15 @@ void LLAppViewer::handleLoginComplete()
writeDebugInfo();
// we logged in successfully, so save settings on logout
- llinfos << "Login successful, per account settings will be saved on log out." << llendl;
+ LL_INFOS() << "Login successful, per account settings will be saved on log out." << LL_ENDL;
mSavePerAccountSettings=true;
}
void LLAppViewer::launchUpdater()
{
LLSD query_map = LLSD::emptyMap();
- // *TODO place os string in a global constant
-#if LL_WINDOWS
- query_map["os"] = "win";
-#elif LL_DARWIN
- query_map["os"] = "mac";
-#elif LL_LINUX
- query_map["os"] = "lnx";
-#elif LL_SOLARIS
- query_map["os"] = "sol";
-#endif
+ query_map["os"] = gPlatform;
+
// *TODO change userserver to be grid on both viewer and sim, since
// userserver no longer exists.
query_map["userserver"] = LLGridManager::getInstance()->getGridId();
@@ -5203,7 +5729,7 @@ void LLAppViewer::launchUpdater()
LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << " " << LLAppViewer::sUpdaterInfo->mParams.str() << LL_ENDL;
//Explicitly remove the marker file, otherwise we pass the lock onto the child process and things get weird.
- LLAppViewer::instance()->removeMarkerFile(); // In case updater fails
+ LLAppViewer::instance()->removeMarkerFiles(); // In case updater fails
// *NOTE:Mani The updater is spawned as the last thing before the WinMain exit.
// see LLAppViewerWin32.cpp
@@ -5238,7 +5764,7 @@ void LLAppViewer::launchUpdater()
// Although we already have the full set of paths with the filename
// appended, the linux-updater.bin command-line switches require us to
// snip the filename OFF and pass it as a separate switch argument. :-P
- llinfos << "Got a XUI path: " << this_skin_path << llendl;
+ LL_INFOS() << "Got a XUI path: " << this_skin_path << LL_ENDL;
xml_search_paths.append(delim);
xml_search_paths.append(gDirUtilp->getDirName(this_skin_path));
delim = ",";
@@ -5260,9 +5786,9 @@ void LLAppViewer::launchUpdater()
GError *error = NULL;
if (!g_spawn_command_line_async(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), &error))
{
- llerrs << "Failed to launch updater: "
+ LL_ERRS() << "Failed to launch updater: "
<< error->message
- << llendl;
+ << LL_ENDL;
}
if (error) {
g_error_free(error);
@@ -5303,17 +5829,7 @@ void LLAppViewer::metricsUpdateRegion(U64 region_handle)
{
if (0 != region_handle)
{
- LLViewerAssetStatsFF::set_region_main(region_handle);
- if (LLAppViewer::sTextureFetch)
- {
- // Send a region update message into 'thread1' to get the new region.
- LLAppViewer::sTextureFetch->commandSetRegion(region_handle);
- }
- else
- {
- // No 'thread1', a.k.a. TextureFetch, so update directly
- LLViewerAssetStatsFF::set_region_thread1(region_handle);
- }
+ LLViewerAssetStatsFF::set_region(region_handle);
}
}
@@ -5324,7 +5840,7 @@ void LLAppViewer::metricsUpdateRegion(U64 region_handle)
*/
void LLAppViewer::metricsSend(bool enable_reporting)
{
- if (! gViewerAssetStatsMain)
+ if (! gViewerAssetStats)
return;
if (LLAppViewer::sTextureFetch)
@@ -5337,7 +5853,8 @@ void LLAppViewer::metricsSend(bool enable_reporting)
// Make a copy of the main stats to send into another thread.
// Receiving thread takes ownership.
- LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStatsMain));
+ LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStats));
+ main_stats->stop();
// Send a report request into 'thread1' to get the rest of the data
// and provide some additional parameters while here.
@@ -5356,6 +5873,6 @@ void LLAppViewer::metricsSend(bool enable_reporting)
// Reset even if we can't report. Rather than gather up a huge chunk of
// data, we'll keep to our sampling interval and retain the data
// resolution in time.
- gViewerAssetStatsMain->reset();
+ gViewerAssetStats->restart();
}