aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llappviewer.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llappviewer.cpp164
1 files changed, 136 insertions, 28 deletions
diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp
index ab4d8a9..52aa1eb 100644
--- a/linden/indra/newview/llappviewer.cpp
+++ b/linden/indra/newview/llappviewer.cpp
@@ -125,6 +125,7 @@
125#include "llvectorperfoptions.h" 125#include "llvectorperfoptions.h"
126#include "llurlsimstring.h" 126#include "llurlsimstring.h"
127#include "llwatchdog.h" 127#include "llwatchdog.h"
128#include "llcallingcard.h"
128 129
129// Included so that constants/settings might be initialized 130// Included so that constants/settings might be initialized
130// in save_settings_to_globals() 131// in save_settings_to_globals()
@@ -164,6 +165,10 @@
164 165
165#include "llcommandlineparser.h" 166#include "llcommandlineparser.h"
166 167
168#include "hippoGridManager.h"
169#include "hippoLimits.h"
170#include "hippoUpdate.h"
171
167// annoying detail to determine whether font prefs are over-ridden 172// annoying detail to determine whether font prefs are over-ridden
168#if LL_LINUX 173#if LL_LINUX
169# define LL_DYNAMIC_FONT_DISCOVERY 1 174# define LL_DYNAMIC_FONT_DISCOVERY 1
@@ -192,22 +197,35 @@
192 197
193//---------------------------------------------------------------------------- 198//----------------------------------------------------------------------------
194// viewer.cpp - these are only used in viewer, should be easily moved. 199// viewer.cpp - these are only used in viewer, should be easily moved.
200extern void disable_win_error_reporting();
195 201
196#if LL_DARWIN 202#if LL_DARWIN
203#include <Carbon/Carbon.h>
197extern void init_apple_menu(const char* product); 204extern void init_apple_menu(const char* product);
205extern OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn);
206extern OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn);
207extern OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata);
208#include <boost/tokenizer.hpp>
198#endif // LL_DARWIN 209#endif // LL_DARWIN
199 210
211
200extern BOOL gRandomizeFramerate; 212extern BOOL gRandomizeFramerate;
201extern BOOL gPeriodicSlowFrame; 213extern BOOL gPeriodicSlowFrame;
202extern BOOL gDebugGL; 214extern BOOL gDebugGL;
203 215
204//////////////////////////////////////////////////////////// 216////////////////////////////////////////////////////////////
205// All from the last globals push... 217// All from the last globals push...
218
219
206const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user flagged as Away From Keyboard 220const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user flagged as Away From Keyboard
207 221
208F32 gSimLastTime; // Used in LLAppViewer::init and send_stats() 222F32 gSimLastTime; // Used in LLAppViewer::init and send_stats()
209F32 gSimFrames; 223F32 gSimFrames;
210 224
225std::string gDisabledMessage; // Set in LLAppViewer::initConfiguration used in idle_startup
226
227BOOL gHideLinks = FALSE; // Set in LLAppViewer::initConfiguration, used externally
228
211BOOL gAllowIdleAFK = TRUE; 229BOOL gAllowIdleAFK = TRUE;
212BOOL gAllowTapTapHoldRun = TRUE; 230BOOL gAllowTapTapHoldRun = TRUE;
213BOOL gShowObjectUpdates = FALSE; 231BOOL gShowObjectUpdates = FALSE;
@@ -233,7 +251,7 @@ F32 gFPSClamped = 10.f; // Pretend we start at target rate.
233F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets 251F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets
234U64 gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds 252U64 gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds
235U32 gFrameStalls = 0; 253U32 gFrameStalls = 0;
236const F64 FRAME_STALL_THRESHOLD = 1.0; 254const F64 FRAME_STALL_THRESHOLD = 5.0;
237 255
238LLTimer gRenderStartTime; 256LLTimer gRenderStartTime;
239LLFrameTimer gForegroundTime; 257LLFrameTimer gForegroundTime;
@@ -302,7 +320,8 @@ std::string gLoginPage;
302std::vector<std::string> gLoginURIs; 320std::vector<std::string> gLoginURIs;
303static std::string gHelperURI; 321static std::string gHelperURI;
304 322
305LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ; 323//FIXME
324//LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ;
306 325
307void idle_afk_check() 326void idle_afk_check()
308{ 327{
@@ -453,7 +472,7 @@ static void settings_modify()
453 gSavedSettings.setBOOL("VectorizeSkin", FALSE); 472 gSavedSettings.setBOOL("VectorizeSkin", FALSE);
454#endif 473#endif
455} 474}
456 475/*
457void LLAppViewer::initGridChoice() 476void LLAppViewer::initGridChoice()
458{ 477{
459 // Load up the initial grid choice from: 478 // Load up the initial grid choice from:
@@ -470,7 +489,7 @@ void LLAppViewer::initGridChoice()
470 if(grid_choice.empty()) 489 if(grid_choice.empty())
471 { 490 {
472 S32 server = gSavedSettings.getS32("ServerChoice"); 491 S32 server = gSavedSettings.getS32("ServerChoice");
473 server = llclamp(server, 0, (S32)GRID_INFO_COUNT - 1); 492 //server = llclamp(server, 0, (S32)GRID_INFO_COUNT - 1);
474 if(server == GRID_INFO_OTHER) 493 if(server == GRID_INFO_OTHER)
475 { 494 {
476 std::string custom_server = gSavedSettings.getString("CustomServer"); 495 std::string custom_server = gSavedSettings.getString("CustomServer");
@@ -478,11 +497,12 @@ void LLAppViewer::initGridChoice()
478 } 497 }
479 else if(server != (S32)GRID_INFO_NONE) 498 else if(server != (S32)GRID_INFO_NONE)
480 { 499 {
481 LLViewerLogin::getInstance()->setGridChoice((EGridInfo)server); 500 llwarns << "setgridchoice = " << server << llendl;
501 LLViewerLogin::getInstance()->setGridChoice(server);
482 } 502 }
483 } 503 }
484} 504}
485 505*/
486//virtual 506//virtual
487bool LLAppViewer::initSLURLHandler() 507bool LLAppViewer::initSLURLHandler()
488{ 508{
@@ -521,6 +541,7 @@ LLAppViewer::LLAppViewer() :
521 mSecondInstance(false), 541 mSecondInstance(false),
522 mSavedFinalSnapshot(false), 542 mSavedFinalSnapshot(false),
523 mQuitRequested(false), 543 mQuitRequested(false),
544 mLogoutRequested(false),
524 mLogoutRequestSent(false), 545 mLogoutRequestSent(false),
525 mYieldTime(-1), 546 mYieldTime(-1),
526 mMainloopTimeout(NULL), 547 mMainloopTimeout(NULL),
@@ -662,7 +683,6 @@ bool LLAppViewer::init()
662 ui_audio_callback, 683 ui_audio_callback,
663 &LLUI::sGLScaleFactor); 684 &LLUI::sGLScaleFactor);
664 LLWeb::initClass(); // do this after LLUI 685 LLWeb::initClass(); // do this after LLUI
665
666 LLTextEditor::setURLCallbacks(&LLWeb::loadURL, 686 LLTextEditor::setURLCallbacks(&LLWeb::loadURL,
667 &LLURLDispatcher::dispatchFromTextEditor, 687 &LLURLDispatcher::dispatchFromTextEditor,
668 &LLURLDispatcher::dispatchFromTextEditor); 688 &LLURLDispatcher::dispatchFromTextEditor);
@@ -683,6 +703,7 @@ bool LLAppViewer::init()
683 // load MIME type -> media impl mappings 703 // load MIME type -> media impl mappings
684 LLMIMETypes::parseMIMETypes( std::string("mime_types.xml") ); 704 LLMIMETypes::parseMIMETypes( std::string("mime_types.xml") );
685 705
706
686 // Copy settings to globals. *TODO: Remove or move to appropriage class initializers 707 // Copy settings to globals. *TODO: Remove or move to appropriage class initializers
687 settings_to_globals(); 708 settings_to_globals();
688 // Setup settings listeners 709 // Setup settings listeners
@@ -1117,12 +1138,21 @@ bool LLAppViewer::cleanup()
1117 // to ensure shutdown order 1138 // to ensure shutdown order
1118 LLMortician::setZealous(TRUE); 1139 LLMortician::setZealous(TRUE);
1119 1140
1141 if (mQuitRequested)
1120 LLVoiceClient::terminate(); 1142 LLVoiceClient::terminate();
1121 1143
1122 disconnectViewer(); 1144 disconnectViewer();
1123 1145
1124 llinfos << "Viewer disconnected" << llendflush; 1146 llinfos << "Viewer disconnected" << llendflush;
1125 1147
1148
1149
1150
1151
1152 //this deletes all your buddies
1153 LLAvatarTracker::instance().reset();
1154
1155 if (mQuitRequested)
1126 display_cleanup(); 1156 display_cleanup();
1127 1157
1128 release_start_screen(); // just in case 1158 release_start_screen(); // just in case
@@ -1137,6 +1167,13 @@ bool LLAppViewer::cleanup()
1137 1167
1138 LLKeyframeDataCache::clear(); 1168 LLKeyframeDataCache::clear();
1139 1169
1170 //clear all the chat off the screen
1171 gConsole->clear();
1172
1173 if (!mQuitRequested) //if we are doing a soft cleanup, bail here
1174 {
1175 return true;
1176 }
1140 // End TransferManager before deleting systems it depends on (Audio, VFS, AssetStorage) 1177 // End TransferManager before deleting systems it depends on (Audio, VFS, AssetStorage)
1141#if 0 // this seems to get us stuck in an infinite loop... 1178#if 0 // this seems to get us stuck in an infinite loop...
1142 gTransferManager.cleanup(); 1179 gTransferManager.cleanup();
@@ -1242,6 +1279,9 @@ bool LLAppViewer::cleanup()
1242 // viewer UI relies on keyboard so keep it aound until viewer UI isa gone 1279 // viewer UI relies on keyboard so keep it aound until viewer UI isa gone
1243 delete gKeyboard; 1280 delete gKeyboard;
1244 gKeyboard = NULL; 1281 gKeyboard = NULL;
1282 // Clean up selection managers after UI is destroyed, as UI
1283 // may be observing them.
1284 LLSelectMgr::cleanupGlobals();
1245 1285
1246 LLViewerObject::cleanupVOClasses(); 1286 LLViewerObject::cleanupVOClasses();
1247 1287
@@ -1251,6 +1291,7 @@ bool LLAppViewer::cleanup()
1251 1291
1252 LLTracker::cleanupInstance(); 1292 LLTracker::cleanupInstance();
1253 1293
1294
1254 // *FIX: This is handled in LLAppViewerWin32::cleanup(). 1295 // *FIX: This is handled in LLAppViewerWin32::cleanup().
1255 // I'm keeping the comment to remember its order in cleanup, 1296 // I'm keeping the comment to remember its order in cleanup,
1256 // in case of unforseen dependency. 1297 // in case of unforseen dependency.
@@ -1319,6 +1360,7 @@ bool LLAppViewer::cleanup()
1319 // save mute list. gMuteList used to also be deleted here too. 1360 // save mute list. gMuteList used to also be deleted here too.
1320 LLMuteList::getInstance()->cache(gAgent.getID()); 1361 LLMuteList::getInstance()->cache(gAgent.getID());
1321 1362
1363
1322 if (mPurgeOnExit) 1364 if (mPurgeOnExit)
1323 { 1365 {
1324 llinfos << "Purging all cache files on exit" << llendflush; 1366 llinfos << "Purging all cache files on exit" << llendflush;
@@ -1819,7 +1861,14 @@ bool LLAppViewer::initConfiguration()
1819 } 1861 }
1820 } 1862 }
1821 1863
1822 initGridChoice(); 1864 //init Hippo grid manager
1865 if (!gHippoGridManager) {
1866 gHippoGridManager = new HippoGridManager();
1867 gHippoGridManager->init();
1868 }
1869
1870
1871 //initGridChoice();
1823 1872
1824 // If we have specified crash on startup, set the global so we'll trigger the crash at the right time 1873 // If we have specified crash on startup, set the global so we'll trigger the crash at the right time
1825 if(clp.hasOption("crashonstartup")) 1874 if(clp.hasOption("crashonstartup"))
@@ -1836,7 +1885,6 @@ bool LLAppViewer::initConfiguration()
1836 // achieve this. For now... 1885 // achieve this. For now...
1837 1886
1838 // *NOTE:Mani The command line parser parses tokens and is 1887 // *NOTE:Mani The command line parser parses tokens and is
1839 // setup to bail after parsing the '--url' option or the
1840 // first option specified without a '--option' flag (or 1888 // first option specified without a '--option' flag (or
1841 // any other option that uses the 'last_option' setting - 1889 // any other option that uses the 'last_option' setting -
1842 // see LLControlGroupCLP::configure()) 1890 // see LLControlGroupCLP::configure())
@@ -1894,6 +1942,22 @@ bool LLAppViewer::initConfiguration()
1894 // llerrs << "Failed to parse skin definition." << llendl; 1942 // llerrs << "Failed to parse skin definition." << llendl;
1895 // } 1943 // }
1896 1944
1945 // LLXmlTreeNode* rootp = skin_def_tree.getRoot();
1946 // LLXmlTreeNode* disabled_message_node = rootp->getChildByName("disabled_message");
1947 // if (disabled_message_node)
1948 // {
1949 // gDisabledMessage = disabled_message_node->getContents();
1950 // }
1951
1952 // static LLStdStringHandle hide_links_string = LLXmlTree::addAttributeString("hide_links");
1953 // rootp->getFastAttributeBOOL(hide_links_string, gHideLinks);
1954
1955 // // Legacy string. This flag really meant we didn't want to expose references to "Second Life".
1956 // // Just set gHideLinks instead.
1957 // static LLStdStringHandle silent_string = LLXmlTree::addAttributeString("silent_update");
1958 // BOOL silent_update;
1959 // rootp->getFastAttributeBOOL(silent_string, silent_update);
1960 // gHideLinks = (gHideLinks || silent_update);
1897 //} 1961 //}
1898 1962
1899#if LL_DARWIN 1963#if LL_DARWIN
@@ -2315,7 +2379,7 @@ void LLAppViewer::handleViewerCrash()
2315 gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); 2379 gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
2316 gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); 2380 gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
2317 gDebugInfo["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds()); 2381 gDebugInfo["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds());
2318 gDebugInfo["StartupState"] = LLStartUp::getStartupStateString(); 2382//FIXME gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
2319 gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer) getCurrentRSS() >> 10; 2383 gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer) getCurrentRSS() >> 10;
2320 2384
2321 if(gLogoutInProgress) 2385 if(gLogoutInProgress)
@@ -2542,28 +2606,55 @@ void LLAppViewer::removeMarkerFile(bool leave_logout_marker)
2542 } 2606 }
2543} 2607}
2544 2608
2609
2610//this gets called after we get a packet back from the
2611//server saying we are logged out, or if the packet times
2612//out
2545void LLAppViewer::forceQuit() 2613void LLAppViewer::forceQuit()
2546{ 2614{
2615
2616 LL_INFOS("forceQuit") << "Destroying the entire world" << LL_ENDL;
2617 if (mQuitRequested)
2547 LLApp::setQuitting(); 2618 LLApp::setQuitting();
2619 else
2620 {
2621 if (mLogoutRequested) //we just finished a logout request
2622 {
2623 //LLStartUp::setStartupState( STATE_LOGIN_SHOW );
2624 LLStartUp::resetLogin();
2625 cleanup();
2626 mLogoutRequested=false;
2627 mLogoutRequestSent=false;
2628 }
2629 }
2548} 2630}
2549 2631
2550void LLAppViewer::requestQuit() 2632void LLAppViewer::requestLogout(bool quit_after)
2551{ 2633{
2552 llinfos << "requestQuit" << llendl; 2634
2635 mLogoutRequested=true;
2636 if(quit_after)
2637 mQuitRequested=true;
2638 else
2639 mQuitRequested=false;
2640
2641 llinfos << "requestLogout" << llendl;
2553 2642
2554 LLViewerRegion* region = gAgent.getRegion(); 2643 LLViewerRegion* region = gAgent.getRegion();
2555 2644
2556 if( (LLStartUp::getStartupState() < STATE_STARTED) || !region ) 2645 if( (LLStartUp::getStartupState() >= STATE_STARTED) && region )
2557 { 2646 {
2558 // Quit immediately
2559 forceQuit();
2560 return;
2561 }
2562
2563 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); 2647 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
2564 effectp->setPositionGlobal(gAgent.getPositionGlobal()); 2648 effectp->setPositionGlobal(gAgent.getPositionGlobal());
2565 effectp->setColor(LLColor4U(gAgent.getEffectColor())); 2649 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
2566 LLHUDManager::getInstance()->sendEffects(); 2650 LLHUDManager::getInstance()->sendEffects();
2651 send_stats();
2652 }
2653 else
2654 {
2655 mQuitRequested=true;
2656 LLAppViewer::instance()->forceQuit();
2657 }
2567 2658
2568 // Attempt to close all floaters that might be 2659 // Attempt to close all floaters that might be
2569 // editing things. 2660 // editing things.
@@ -2573,17 +2664,14 @@ void LLAppViewer::requestQuit()
2573 gFloaterView->closeAllChildren(true); 2664 gFloaterView->closeAllChildren(true);
2574 } 2665 }
2575 2666
2576 send_stats();
2577
2578 gLogoutTimer.reset(); 2667 gLogoutTimer.reset();
2579 mQuitRequested = true;
2580} 2668}
2581 2669
2582static void finish_quit(S32 option, void *userdata) 2670static void finish_quit(S32 option, void *userdata)
2583{ 2671{
2584 if (option == 0) 2672 if (option == 0)
2585 { 2673 {
2586 LLAppViewer::instance()->requestQuit(); 2674 LLAppViewer::instance()->requestLogout(true);
2587 } 2675 }
2588} 2676}
2589 2677
@@ -2592,6 +2680,12 @@ void LLAppViewer::userQuit()
2592 gViewerWindow->alertXml("ConfirmQuit", finish_quit, NULL); 2680 gViewerWindow->alertXml("ConfirmQuit", finish_quit, NULL);
2593} 2681}
2594 2682
2683//static
2684void LLAppViewer::userLogout(void *userdata)
2685{
2686 LLAppViewer::instance()->requestLogout(false);
2687}
2688
2595static void finish_early_exit(S32 option, void* userdata) 2689static void finish_early_exit(S32 option, void* userdata)
2596{ 2690{
2597 LLAppViewer::instance()->forceQuit(); 2691 LLAppViewer::instance()->forceQuit();
@@ -2619,6 +2713,7 @@ void LLAppViewer::abortQuit()
2619{ 2713{
2620 llinfos << "abortQuit()" << llendl; 2714 llinfos << "abortQuit()" << llendl;
2621 mQuitRequested = false; 2715 mQuitRequested = false;
2716 mLogoutRequested = false;
2622} 2717}
2623 2718
2624bool LLAppViewer::initCache() 2719bool LLAppViewer::initCache()
@@ -2895,7 +2990,7 @@ void finish_forced_disconnect(S32 /* option */, void* /* userdata */)
2895 2990
2896void LLAppViewer::forceDisconnect(const std::string& mesg) 2991void LLAppViewer::forceDisconnect(const std::string& mesg)
2897{ 2992{
2898 if (gDoDisconnect) 2993 if (gDoDisconnect||mQuitRequested||mLogoutRequested)
2899 { 2994 {
2900 // Already popped up one of these dialogs, don't 2995 // Already popped up one of these dialogs, don't
2901 // do this again. 2996 // do this again.
@@ -3203,9 +3298,12 @@ void LLAppViewer::idle()
3203 // Check for away from keyboard, kick idle agents. 3298 // Check for away from keyboard, kick idle agents.
3204 idle_afk_check(); 3299 idle_afk_check();
3205 3300
3301 if (!gDisconnected) //check again
3302 {
3206 // Update statistics for this frame 3303 // Update statistics for this frame
3207 update_statistics(gFrameCount); 3304 update_statistics(gFrameCount);
3208 } 3305 }
3306 }
3209 3307
3210 //////////////////////////////////////// 3308 ////////////////////////////////////////
3211 // 3309 //
@@ -3406,7 +3504,7 @@ void LLAppViewer::idle()
3406 // Handle shutdown process, for example, 3504 // Handle shutdown process, for example,
3407 // wait for floaters to close, send quit message, 3505 // wait for floaters to close, send quit message,
3408 // forcibly quit if it has taken too long 3506 // forcibly quit if it has taken too long
3409 if (mQuitRequested) 3507 if (mQuitRequested || mLogoutRequested)
3410 { 3508 {
3411 idleShutdown(); 3509 idleShutdown();
3412 } 3510 }
@@ -3506,12 +3604,12 @@ void LLAppViewer::sendLogoutRequest()
3506 if (mLogoutMarkerFile) 3604 if (mLogoutMarkerFile)
3507 { 3605 {
3508 llinfos << "Created logout marker file " << mLogoutMarkerFileName << llendl; 3606 llinfos << "Created logout marker file " << mLogoutMarkerFileName << llendl;
3509 apr_file_close(mLogoutMarkerFile);
3510 } 3607 }
3511 else 3608 else
3512 { 3609 {
3513 llwarns << "Cannot create logout marker file " << mLogoutMarkerFileName << llendl; 3610 llwarns << "Cannot create logout marker file " << mLogoutMarkerFileName << llendl;
3514 } 3611 }
3612 apr_file_close(mLogoutMarkerFile);
3515 } 3613 }
3516} 3614}
3517 3615
@@ -3528,6 +3626,9 @@ static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
3528 3626
3529void LLAppViewer::idleNetwork() 3627void LLAppViewer::idleNetwork()
3530{ 3628{
3629 if (gDisconnected)
3630 return;
3631
3531 pingMainloopTimeout("idleNetwork"); 3632 pingMainloopTimeout("idleNetwork");
3532 3633
3533 gObjectList.mNumNewObjects = 0; 3634 gObjectList.mNumNewObjects = 0;
@@ -3614,7 +3715,11 @@ void LLAppViewer::idleNetwork()
3614 3715
3615 gObjectList.mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects); 3716 gObjectList.mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects);
3616 3717
3718 if (gDisconnected)
3719 return;
3720
3617 // Retransmit unacknowledged packets. 3721 // Retransmit unacknowledged packets.
3722 if (gXferManager)
3618 gXferManager->retransmitUnackedPackets(); 3723 gXferManager->retransmitUnackedPackets();
3619 gAssetStorage->checkForTimeouts(); 3724 gAssetStorage->checkForTimeouts();
3620 3725
@@ -3624,7 +3729,7 @@ void LLAppViewer::idleNetwork()
3624 // Check that the circuit between the viewer and the agent's current 3729 // Check that the circuit between the viewer and the agent's current
3625 // region is still alive 3730 // region is still alive
3626 LLViewerRegion *agent_region = gAgent.getRegion(); 3731 LLViewerRegion *agent_region = gAgent.getRegion();
3627 if (agent_region) 3732 if ((agent_region)&&(LLStartUp::getStartupState() == STATE_STARTED))
3628 { 3733 {
3629 LLUUID this_region_id = agent_region->getRegionID(); 3734 LLUUID this_region_id = agent_region->getRegionID();
3630 bool this_region_alive = agent_region->isAlive(); 3735 bool this_region_alive = agent_region->isAlive();
@@ -3644,6 +3749,9 @@ void LLAppViewer::disconnectViewer()
3644 { 3749 {
3645 return; 3750 return;
3646 } 3751 }
3752
3753 //set this true now, to prevent things from trying to access the network we are destroying
3754 gDisconnected = TRUE;
3647 // 3755 //
3648 // Cleanup after quitting. 3756 // Cleanup after quitting.
3649 // 3757 //
@@ -3693,8 +3801,8 @@ void LLAppViewer::disconnectViewer()
3693 // Now we just ask the LLWorld singleton to cleanly shut down. 3801 // Now we just ask the LLWorld singleton to cleanly shut down.
3694 LLWorld::getInstance()->destroyClass(); 3802 LLWorld::getInstance()->destroyClass();
3695 3803
3696 cleanup_xfer_manager(); 3804 if (mQuitRequested)
3697 gDisconnected = TRUE; 3805 cleanup_xfer_manager();
3698} 3806}
3699 3807
3700void LLAppViewer::forceErrorLLError() 3808void LLAppViewer::forceErrorLLError()