diff options
Diffstat (limited to 'indra/newview/llappviewer.cpp')
-rw-r--r-- | indra/newview/llappviewer.cpp | 402 |
1 files changed, 203 insertions, 199 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a6173f45df..2b5691ffe8 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -64,7 +64,7 @@ #include "llurldispatcher.h" #include "llurlhistory.h" #include "llfirstuse.h" -#include "llglimmediate.h" +#include "llrender.h" #include "llweb.h" #include "llsecondlifeurls.h" @@ -192,24 +192,6 @@ // viewer.cpp - these are only used in viewer, should be easily moved. extern void disable_win_error_reporting(); -//#define APPLE_PREVIEW // Define this if you're doing a preview build on the Mac -#if LL_RELEASE_FOR_DOWNLOAD -// Default userserver for production builds is agni -#ifndef APPLE_PREVIEW -static EGridInfo GridDefaultChoice = GRID_INFO_AGNI; -#else -static EGridInfo GridDefaultChoice = GRID_INFO_ADITI; -#endif -#else -// Default userserver for development builds is none -static EGridInfo GridDefaultChoice = GRID_INFO_NONE; -#endif - -#if LL_WINDOWS -extern void create_console(); -#endif - - #if LL_DARWIN #include <Carbon/Carbon.h> extern void init_apple_menu(const char* product); @@ -287,6 +269,7 @@ BOOL gUseWireframe = FALSE; LLVFS* gStaticVFS = NULL; LLMemoryInfo gSysMemory; +U64 gMemoryAllocated = 0; // updated in display_stats() in llviewerdisplay.cpp LLString gLastVersionChannel; @@ -303,6 +286,7 @@ BOOL gPeriodicSlowFrame = FALSE; BOOL gCrashOnStartup = FALSE; BOOL gLLErrorActivated = FALSE; BOOL gLogoutInProgress = FALSE; + //////////////////////////////////////////////////////////// // Internal globals... that should be removed. static LLString gArgs; @@ -338,6 +322,48 @@ void idle_afk_check() } } +//this function checks if the system can allocate (num_chunk)MB memory successfully. +//if this check fails, the allocated memory is NOT freed. +void idle_mem_check(S32 num_chunk) +{ + //this flag signals if memory allocation check is necessary + static BOOL check = TRUE ; + + if(!check) //if memory check fails before, do not repeat it. + { + return ; + } + check = FALSE ; //before memory check for this frame, turn off check signal for the next frame. + + S32 i = 0 ; + char**p = new char*[num_chunk] ; + if(!p) + { + return ; + } + for(i = 0 ; i < num_chunk ; i++) + { + //1MB per chunk + //if the allocation fails, the system should catch it. + p[i] = new char[1024 * 1024] ; + + if(!p[i]) //in case that system try-catch is turned off + { + return ; + } + } + + //release memory if the allocation check does not fail. + for(i = 0 ; i < num_chunk ; i++) + { + delete[] p[i] ; + } + delete[] p ; + + //memory check for this frame succeeds, turn on next frame check. + check = TRUE ; +} + // A callback set in LLAppViewer::init() static void ui_audio_callback(const LLUUID& uuid) { @@ -369,6 +395,24 @@ void request_initial_instant_messages() } } +// A settings system callback for CrashSubmitBehavior +bool handleCrashSubmitBehaviorChanged(const LLSD& newvalue) +{ + S32 cb = newvalue.asInteger(); + const S32 NEVER_SUBMIT_REPORT = 2; + if(cb == NEVER_SUBMIT_REPORT) + { +// LLWatchdog::getInstance()->cleanup(); // SJB: cleaning up a running watchdog is unsafe + LLAppViewer::instance()->destroyMainloopTimeout(); + } + else if(gSavedSettings.getBOOL("WatchdogEnabled") == TRUE) + { +// LLWatchdog::getInstance()->init(); +// LLAppViewer::instance()->initMainloopTimeout("Mainloop Resume"); + } + return true; +} + // Use these strictly for things that are constructed at startup, // or for things that are performance critical. JC static void settings_to_globals() @@ -464,72 +508,32 @@ static void settings_modify() gSavedSettings.setBOOL("PTTCurrentlyEnabled", TRUE); //gSavedSettings.getBOOL("EnablePushToTalk")); } -void initGridChoice() +void LLAppViewer::initGridChoice() { - LLString gridChoice = gSavedSettings.getString("GridChoice"); - if(!gridChoice.empty()) - // Used to show first chunk of each argument passed in the - // window title. - { - // find the grid choice from the user setting. - int gridIndex = GRID_INFO_NONE; - for(;gridIndex < GRID_INFO_OTHER; ++gridIndex ) - { - if(0 == LLString::compareInsensitive(gGridInfo[gridIndex].mLabel, gridChoice.c_str())) - { - gGridChoice = (EGridInfo)gridIndex; - - if(GRID_INFO_LOCAL == gGridChoice) - { - gGridName = LOOPBACK_ADDRESS_STRING; - break; - } - else - { - gGridName = gGridInfo[gGridChoice].mName; - break; - } - } - } - - if(GRID_INFO_OTHER == gridIndex) - { - // *FIX:MEP Can and should we validate that this is an IP address? - gGridChoice = (EGridInfo)gridIndex; - gGridName = llformat("%s", gSavedSettings.getString("GridChoice").c_str()); - - } - } - - -#if !LL_RELEASE_FOR_DOWNLOAD - if (gGridChoice == GRID_INFO_NONE) - { - // Development version: load last server choice by default (overridden by cmd line args) - S32 server = gSavedSettings.getS32("ServerChoice"); - if (server != 0) - gGridChoice = (EGridInfo)llclamp(server, 0, (S32)GRID_INFO_COUNT - 1); - if (server == GRID_INFO_OTHER) + // Load up the initial grid choice from: + // - hard coded defaults... + // - command line settings... + // - if dev build, persisted settings... + + // Set the "grid choice", this is specified by command line. + std::string grid_choice = gSavedSettings.getString("CmdLineGridChoice"); + LLViewerLogin::getInstance()->setGridChoice(grid_choice); + + // Load last server choice by default + // ignored if the command line grid choice has been set + if(grid_choice.empty()) + { + S32 server = gSavedSettings.getS32("ServerChoice"); + server = llclamp(server, 0, (S32)GRID_INFO_COUNT - 1); + if(server == GRID_INFO_OTHER) { LLString custom_server = gSavedSettings.getString("CustomServer"); - if (custom_server.empty()) - { - gGridName = "none"; - } - else - { - gGridName = custom_server.c_str(); - } + LLViewerLogin::getInstance()->setGridChoice(custom_server); + } + else if(server != 0) + { + LLViewerLogin::getInstance()->setGridChoice((EGridInfo)server); } - - gSavedSettings.setString("GridChoice", gGridInfo[gGridChoice].mLabel); - } -#endif - - if (gGridChoice == GRID_INFO_NONE) - { - gGridChoice = GridDefaultChoice; - gSavedSettings.setString("GridChoice", gGridInfo[gGridChoice].mLabel); } } @@ -577,7 +581,6 @@ LLTextureFetch* LLAppViewer::sTextureFetch = NULL; LLAppViewer::LLAppViewer() : mMarkerFile(NULL), - mCrashBehavior(CRASH_BEHAVIOR_ASK), mReportedCrash(false), mNumSessions(0), mPurgeCache(false), @@ -586,7 +589,8 @@ LLAppViewer::LLAppViewer() : mSavedFinalSnapshot(false), mQuitRequested(false), mLogoutRequestSent(false), - mYieldTime(-1) + mYieldTime(-1), + mMainloopTimeout(NULL) { if(NULL != sInstance) { @@ -594,15 +598,11 @@ LLAppViewer::LLAppViewer() : } sInstance = this; - - // Initialize the mainloop timeout. - mMainloopTimeout = new LLWatchdogTimeout(); } LLAppViewer::~LLAppViewer() { - // Initialize the mainloop timeout. - delete mMainloopTimeout; + destroyMainloopTimeout(); // If we got to this destructor somehow, the app didn't hang. removeMarkerFile(); @@ -610,13 +610,6 @@ LLAppViewer::~LLAppViewer() bool LLAppViewer::init() { - // *NOTE:Mani - LLCurl::initClass is not thread safe. - // Called before threads are created. - LLCurl::initClass(); - - initThreads(); - - // // Start of the application // @@ -629,7 +622,6 @@ bool LLAppViewer::init() // that touches files should really go through the lldir API gDirUtilp->initAppDirs("SecondLife"); - initLogging(); // @@ -638,6 +630,12 @@ bool LLAppViewer::init() if (!initConfiguration()) return false; + // *NOTE:Mani - LLCurl::initClass is not thread safe. + // Called before threads are created. + LLCurl::initClass(); + + initThreads(); + writeSystemInfo(); // Build a string representing the current version number. @@ -888,10 +886,6 @@ bool LLAppViewer::init() bool LLAppViewer::mainLoop() { - mMainloopTimeout = new LLWatchdogTimeout(); - // *FIX:Mani - Make this a setting, once new settings exist in this branch. - mMainloopTimeout->setTimeout(5); - //------------------------------------------- // Run main loop until time to quit //------------------------------------------- @@ -920,6 +914,8 @@ bool LLAppViewer::mainLoop() { LLFastTimer t(LLFastTimer::FTM_FRAME); + pingMainloopTimeout("Main:GatherInput"); + { LLFastTimer t2(LLFastTimer::FTM_MESSAGES); #if LL_WINDOWS @@ -940,8 +936,13 @@ bool LLAppViewer::mainLoop() } #endif + //at the beginning of every frame, check if the system can successfully allocate 10 * 1 MB memory. + idle_mem_check(10) ; + if (!LLApp::isExiting()) { + pingMainloopTimeout("Main:JoystickKeyboard"); + // Scan keyboard for movement keys. Command keys and typing // are handled by windows callbacks. Don't do this until we're // done initializing. JC @@ -956,6 +957,8 @@ bool LLAppViewer::mainLoop() gKeyboard->scanKeyboard(); } + pingMainloopTimeout("Main:Messages"); + // Update state based on messages, user input, object idle. { LLFastTimer t3(LLFastTimer::FTM_IDLE); @@ -972,25 +975,34 @@ bool LLAppViewer::mainLoop() if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) { + pauseMainloopTimeout(); saveFinalSnapshot(); disconnectViewer(); + resumeMainloopTimeout(); } // Render scene. if (!LLApp::isExiting()) { + pingMainloopTimeout("Main:Display"); display(); + pingMainloopTimeout("Main:Snapshot"); LLFloaterSnapshot::update(); // take snapshots #if LL_LCD_COMPILE // update LCD Screen + pingMainloopTimeout("Main:LCD"); gLcdScreen->UpdateDisplay(); #endif } } + pingMainloopTimeout("Main:Sleep"); + + pauseMainloopTimeout(); + // Sleep and run background threads { LLFastTimer t2(LLFastTimer::FTM_SLEEP); @@ -1073,7 +1085,9 @@ bool LLAppViewer::mainLoop() //LLVFSThread::sLocal->pause(); // Prevent the VFS thread from running while rendering. //LLLFSThread::sLocal->pause(); // Prevent the LFS thread from running while rendering. - mMainloopTimeout->ping(); + resumeMainloopTimeout(); + + pingMainloopTimeout("Main:End"); } } @@ -1098,7 +1112,7 @@ bool LLAppViewer::mainLoop() delete gServicePump; - mMainloopTimeout->stop(); + destroyMainloopTimeout(); llinfos << "Exiting main_loop" << llendflush; @@ -1400,7 +1414,12 @@ bool LLAppViewer::initThreads() static const bool enable_threads = true; #endif - LLWatchdog::getInstance()->init(); + const S32 NEVER_SUBMIT_REPORT = 2; + if(TRUE == gSavedSettings.getBOOL("WatchdogEnabled") + && (gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING) != NEVER_SUBMIT_REPORT)) + { + LLWatchdog::getInstance()->init(); + } LLVFSThread::initClass(enable_threads && true); LLLFSThread::initClass(enable_threads && true); @@ -1556,6 +1575,19 @@ bool LLAppViewer::initConfiguration() LLWindow::getFontListSans()); #endif + //*FIX:Mani - Set default to disabling watchdog mainloop + // timeout for mac and linux. There is no call stack info + // on these platform to help debug. +#ifndef LL_RELEASE_FOR_DOWNLOAD + gSavedSettings.setBOOL("WatchdogEnabled", FALSE); +#endif + +#ifndef LL_WINDOWS + gSavedSettings.setBOOL("WatchdogEnabled", FALSE); +#endif + + gCrashSettings.getControl(CRASH_BEHAVIOR_SETTING)->getSignal()->connect(boost::bind(&handleCrashSubmitBehaviorChanged, _1)); + // These are warnings that appear on the first experience of that condition. // They are already set in the settings_default.xml file, but still need to be added to LLFirstUse // for disable/reset ability @@ -1787,18 +1819,6 @@ bool LLAppViewer::initConfiguration() } } - const LLControlVariable* loginuri = gSavedSettings.getControl("LoginURI"); - if(loginuri && LLString::null != loginuri->getValue().asString()) - { - addLoginURI(loginuri->getValue().asString()); - } - - const LLControlVariable* helperuri = gSavedSettings.getControl("HelperURI"); - if(helperuri && LLString::null != helperuri->getValue().asString()) - { - setHelperURI(helperuri->getValue().asString()); - } - const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinFolder"); if(skinfolder && LLString::null != skinfolder->getValue().asString()) { @@ -2180,10 +2200,6 @@ void LLAppViewer::cleanupSavedSettings() { gSavedSettings.setF32("RenderFarClip", gAgent.mDrawDistance); } - - // *REMOVE: This is now done via LLAppViewer::setCrashBehavior() - // Left vestigially in case I borked it. - // gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, gCrashBehavior); } void LLAppViewer::removeCacheFiles(const char* file_mask) @@ -2210,8 +2226,15 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE(); gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2(); - gDebugInfo["RAMInfo"] = llformat("%u", gSysMemory.getPhysicalMemoryKB()); + gDebugInfo["RAMInfo"]["Physical"] = (LLSD::Integer)(gSysMemory.getPhysicalMemoryKB()); + gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer)(gMemoryAllocated>>10); // MB -> KB gDebugInfo["OSInfo"] = getOSInfo().getOSStringSimple(); + + // *FIX:Mani - move this ddown in llappviewerwin32 +#ifdef LL_WINDOWS + DWORD thread_id = GetCurrentThreadId(); + gDebugInfo["MainloopThreadID"] = (S32)thread_id; +#endif // Dump some debugging info LL_INFOS("SystemInfo") << gSecondLife @@ -2242,7 +2265,10 @@ void LLAppViewer::handleSyncViewerCrash() void LLAppViewer::handleViewerCrash() { llinfos << "Handle viewer crash entry." << llendl; - + + // Make sure the watchdog gets turned off... +// LLWatchdog::getInstance()->cleanup(); // SJB: This causes the Watchdog to hang for an extra 20-40s?! + LLAppViewer* pApp = LLAppViewer::instance(); if (pApp->beingDebugged()) { @@ -2297,6 +2323,12 @@ void LLAppViewer::handleViewerCrash() gDebugInfo["CurrentRegion"] = gAgent.getRegion()->getName(); } + if(LLAppViewer::instance()->mMainloopTimeout) + { + gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); + } + + //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 @@ -2360,12 +2392,6 @@ void LLAppViewer::handleViewerCrash() return; } -void LLAppViewer::setCrashBehavior(S32 cb) -{ - mCrashBehavior = cb; - gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, mCrashBehavior); -} - bool LLAppViewer::anotherInstanceRunning() { // We create a marker file when the program starts and remove the file when it finishes. @@ -2822,61 +2848,6 @@ const LLString& LLAppViewer::getWindowTitle() const return gWindowTitle; } -void LLAppViewer::resetURIs() const -{ - // Clear URIs when picking a new server - gLoginURIs.clear(); - gHelperURI.clear(); -} - -const std::vector<std::string>& LLAppViewer::getLoginURIs() const -{ - if (gLoginURIs.empty()) - { - // not specified on the command line, use value from table - gLoginURIs.push_back(gGridInfo[gGridChoice].mLoginURI); - } - return gLoginURIs; -} - -const std::string& LLAppViewer::getHelperURI() const -{ - if (gHelperURI.empty()) - { - // not specified on the command line, use value from table - gHelperURI = gGridInfo[gGridChoice].mHelperURI; - } - return gHelperURI; -} - -void LLAppViewer::addLoginURI(const std::string& uri) -{ - // *NOTE:Mani - login uri trumps the --grid (gGridChoice) setting. - // Update gGridChoice to reflect the loginURI setting. - gLoginURIs.push_back(uri); - - const std::string& top_uri = getLoginURIs()[0]; - int i = 0; - for(; i < GRID_INFO_COUNT; ++i) - { - if(top_uri == gGridInfo[i].mLoginURI) - { - gGridChoice = (EGridInfo)i; - break; - } - } - - if(GRID_INFO_COUNT == i) - { - gGridChoice = GRID_INFO_OTHER; - } -} - -void LLAppViewer::setHelperURI(const std::string& uri) -{ - gHelperURI = uri; -} - // Callback from a dialog indicating user was logged out. void finish_disconnect(S32 option, void* userdata) { @@ -3014,15 +2985,6 @@ void LLAppViewer::saveNameCache() } } -bool LLAppViewer::isInProductionGrid() -{ - // *NOTE:Mani This used to compare GRID_INFO_AGNI to gGridChoice, - // but it seems that loginURI trumps that. - const std::string& loginURI = getLoginURIs()[0]; - return (loginURI == gGridInfo[GRID_INFO_AGNI].mLoginURI); -} - - /*! @brief This class is an LLFrameTimer that can be created with an elapsed time that starts counting up from the given value rather than 0.0. @@ -3531,6 +3493,8 @@ static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; void LLAppViewer::idleNetwork() { + pingMainloopTimeout("idleNetwork"); + gObjectList.mNumNewObjects = 0; S32 total_decoded = 0; @@ -3716,18 +3680,58 @@ void LLAppViewer::forceErrorSoftwareException() throw; } -void LLAppViewer::startMainloopTimeout(F32 secs) +void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs) { - if(secs < 0.0f) + if(!mMainloopTimeout) { - secs = gSavedSettings.getF32("MainloopTimeoutDefault"); + mMainloopTimeout = new LLWatchdogTimeout(); + resumeMainloopTimeout(state, secs); + } +} + +void LLAppViewer::destroyMainloopTimeout() +{ + if(mMainloopTimeout) + { + delete mMainloopTimeout; + mMainloopTimeout = NULL; + } +} + +void LLAppViewer::resumeMainloopTimeout(const std::string& state, F32 secs) +{ + if(mMainloopTimeout) + { + if(secs < 0.0f) + { + secs = gSavedSettings.getF32("MainloopTimeoutDefault"); + } + + mMainloopTimeout->setTimeout(secs); + mMainloopTimeout->start(state); + } +} + +void LLAppViewer::pauseMainloopTimeout() +{ + if(mMainloopTimeout) + { + mMainloopTimeout->stop(); } - - mMainloopTimeout->setTimeout(secs); - mMainloopTimeout->start(); } -void LLAppViewer::stopMainloopTimeout() +void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs) { - mMainloopTimeout->stop(); + if(mMainloopTimeout) + { + if(secs < 0.0f) + { + secs = gSavedSettings.getF32("MainloopTimeoutDefault"); + } + + mMainloopTimeout->setTimeout(secs); + mMainloopTimeout->ping(state); + } } + + |