diff options
author | Armin Weatherwax | 2009-06-26 09:39:58 +0200 |
---|---|---|
committer | Armin Weatherwax | 2009-07-11 13:42:35 +0200 |
commit | 7067b31a6114089217e482bfecc58fd56bed4272 (patch) | |
tree | e0bb99a42c64cdb75e9ca15a38bc1171377c7739 /linden/indra/newview/llappviewer.cpp | |
parent | Updated URL for Mac OpenAL libs package. (diff) | |
download | meta-impy-7067b31a6114089217e482bfecc58fd56bed4272.zip meta-impy-7067b31a6114089217e482bfecc58fd56bed4272.tar.gz meta-impy-7067b31a6114089217e482bfecc58fd56bed4272.tar.bz2 meta-impy-7067b31a6114089217e482bfecc58fd56bed4272.tar.xz |
BROKEN logoff/relog crashing inconsistently on various startup states.
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llappviewer.cpp | 162 |
1 files changed, 135 insertions, 27 deletions
diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 4d53c88..60faaf2 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. |
200 | extern void disable_win_error_reporting(); | ||
195 | 201 | ||
196 | #if LL_DARWIN | 202 | #if LL_DARWIN |
203 | #include <Carbon/Carbon.h> | ||
197 | extern void init_apple_menu(const char* product); | 204 | extern void init_apple_menu(const char* product); |
205 | extern OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn); | ||
206 | extern OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn); | ||
207 | extern OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata); | ||
208 | #include <boost/tokenizer.hpp> | ||
198 | #endif // LL_DARWIN | 209 | #endif // LL_DARWIN |
199 | 210 | ||
211 | |||
200 | extern BOOL gRandomizeFramerate; | 212 | extern BOOL gRandomizeFramerate; |
201 | extern BOOL gPeriodicSlowFrame; | 213 | extern BOOL gPeriodicSlowFrame; |
202 | extern BOOL gDebugGL; | 214 | extern BOOL gDebugGL; |
203 | 215 | ||
204 | //////////////////////////////////////////////////////////// | 216 | //////////////////////////////////////////////////////////// |
205 | // All from the last globals push... | 217 | // All from the last globals push... |
218 | |||
219 | |||
206 | const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user flagged as Away From Keyboard | 220 | const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user flagged as Away From Keyboard |
207 | 221 | ||
208 | F32 gSimLastTime; // Used in LLAppViewer::init and send_stats() | 222 | F32 gSimLastTime; // Used in LLAppViewer::init and send_stats() |
209 | F32 gSimFrames; | 223 | F32 gSimFrames; |
210 | 224 | ||
225 | std::string gDisabledMessage; // Set in LLAppViewer::initConfiguration used in idle_startup | ||
226 | |||
227 | BOOL gHideLinks = FALSE; // Set in LLAppViewer::initConfiguration, used externally | ||
228 | |||
211 | BOOL gAllowIdleAFK = TRUE; | 229 | BOOL gAllowIdleAFK = TRUE; |
212 | BOOL gAllowTapTapHoldRun = TRUE; | 230 | BOOL gAllowTapTapHoldRun = TRUE; |
213 | BOOL gShowObjectUpdates = FALSE; | 231 | BOOL gShowObjectUpdates = FALSE; |
@@ -233,7 +251,7 @@ F32 gFPSClamped = 10.f; // Pretend we start at target rate. | |||
233 | F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets | 251 | F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets |
234 | U64 gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds | 252 | U64 gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds |
235 | U32 gFrameStalls = 0; | 253 | U32 gFrameStalls = 0; |
236 | const F64 FRAME_STALL_THRESHOLD = 1.0; | 254 | const F64 FRAME_STALL_THRESHOLD = 5.0; |
237 | 255 | ||
238 | LLTimer gRenderStartTime; | 256 | LLTimer gRenderStartTime; |
239 | LLFrameTimer gForegroundTime; | 257 | LLFrameTimer gForegroundTime; |
@@ -302,7 +320,8 @@ std::string gLoginPage; | |||
302 | std::vector<std::string> gLoginURIs; | 320 | std::vector<std::string> gLoginURIs; |
303 | static std::string gHelperURI; | 321 | static std::string gHelperURI; |
304 | 322 | ||
305 | LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ; | 323 | //FIXME |
324 | //LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ; | ||
306 | 325 | ||
307 | void idle_afk_check() | 326 | void 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 | /* | |
457 | void LLAppViewer::initGridChoice() | 476 | void 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 |
487 | bool LLAppViewer::initSLURLHandler() | 507 | bool 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 | ||
2545 | void LLAppViewer::forceQuit() | 2613 | void 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 | ||
2550 | void LLAppViewer::requestQuit() | 2632 | void 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 | ||
2582 | static void finish_quit(S32 option, void *userdata) | 2670 | static 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 | ||
2684 | void LLAppViewer::userLogout(void *userdata) | ||
2685 | { | ||
2686 | LLAppViewer::instance()->requestLogout(false); | ||
2687 | } | ||
2688 | |||
2595 | static void finish_early_exit(S32 option, void* userdata) | 2689 | static 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 | ||
2624 | bool LLAppViewer::initCache() | 2719 | bool LLAppViewer::initCache() |
@@ -2895,7 +2990,7 @@ void finish_forced_disconnect(S32 /* option */, void* /* userdata */) | |||
2895 | 2990 | ||
2896 | void LLAppViewer::forceDisconnect(const std::string& mesg) | 2991 | void 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. |
@@ -3198,9 +3293,12 @@ void LLAppViewer::idle() | |||
3198 | // Check for away from keyboard, kick idle agents. | 3293 | // Check for away from keyboard, kick idle agents. |
3199 | idle_afk_check(); | 3294 | idle_afk_check(); |
3200 | 3295 | ||
3296 | if (!gDisconnected) //check again | ||
3297 | { | ||
3201 | // Update statistics for this frame | 3298 | // Update statistics for this frame |
3202 | update_statistics(gFrameCount); | 3299 | update_statistics(gFrameCount); |
3203 | } | 3300 | } |
3301 | } | ||
3204 | 3302 | ||
3205 | //////////////////////////////////////// | 3303 | //////////////////////////////////////// |
3206 | // | 3304 | // |
@@ -3401,7 +3499,7 @@ void LLAppViewer::idle() | |||
3401 | // Handle shutdown process, for example, | 3499 | // Handle shutdown process, for example, |
3402 | // wait for floaters to close, send quit message, | 3500 | // wait for floaters to close, send quit message, |
3403 | // forcibly quit if it has taken too long | 3501 | // forcibly quit if it has taken too long |
3404 | if (mQuitRequested) | 3502 | if (mQuitRequested || mLogoutRequested) |
3405 | { | 3503 | { |
3406 | idleShutdown(); | 3504 | idleShutdown(); |
3407 | } | 3505 | } |
@@ -3501,12 +3599,12 @@ void LLAppViewer::sendLogoutRequest() | |||
3501 | if (mLogoutMarkerFile) | 3599 | if (mLogoutMarkerFile) |
3502 | { | 3600 | { |
3503 | llinfos << "Created logout marker file " << mLogoutMarkerFileName << llendl; | 3601 | llinfos << "Created logout marker file " << mLogoutMarkerFileName << llendl; |
3504 | apr_file_close(mLogoutMarkerFile); | ||
3505 | } | 3602 | } |
3506 | else | 3603 | else |
3507 | { | 3604 | { |
3508 | llwarns << "Cannot create logout marker file " << mLogoutMarkerFileName << llendl; | 3605 | llwarns << "Cannot create logout marker file " << mLogoutMarkerFileName << llendl; |
3509 | } | 3606 | } |
3607 | apr_file_close(mLogoutMarkerFile); | ||
3510 | } | 3608 | } |
3511 | } | 3609 | } |
3512 | 3610 | ||
@@ -3523,6 +3621,9 @@ static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; | |||
3523 | 3621 | ||
3524 | void LLAppViewer::idleNetwork() | 3622 | void LLAppViewer::idleNetwork() |
3525 | { | 3623 | { |
3624 | if (gDisconnected) | ||
3625 | return; | ||
3626 | |||
3526 | pingMainloopTimeout("idleNetwork"); | 3627 | pingMainloopTimeout("idleNetwork"); |
3527 | 3628 | ||
3528 | gObjectList.mNumNewObjects = 0; | 3629 | gObjectList.mNumNewObjects = 0; |
@@ -3609,7 +3710,11 @@ void LLAppViewer::idleNetwork() | |||
3609 | 3710 | ||
3610 | gObjectList.mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects); | 3711 | gObjectList.mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects); |
3611 | 3712 | ||
3713 | if (gDisconnected) | ||
3714 | return; | ||
3715 | |||
3612 | // Retransmit unacknowledged packets. | 3716 | // Retransmit unacknowledged packets. |
3717 | if (gXferManager) | ||
3613 | gXferManager->retransmitUnackedPackets(); | 3718 | gXferManager->retransmitUnackedPackets(); |
3614 | gAssetStorage->checkForTimeouts(); | 3719 | gAssetStorage->checkForTimeouts(); |
3615 | 3720 | ||
@@ -3619,7 +3724,7 @@ void LLAppViewer::idleNetwork() | |||
3619 | // Check that the circuit between the viewer and the agent's current | 3724 | // Check that the circuit between the viewer and the agent's current |
3620 | // region is still alive | 3725 | // region is still alive |
3621 | LLViewerRegion *agent_region = gAgent.getRegion(); | 3726 | LLViewerRegion *agent_region = gAgent.getRegion(); |
3622 | if (agent_region) | 3727 | if ((agent_region)&&(LLStartUp::getStartupState() == STATE_STARTED)) |
3623 | { | 3728 | { |
3624 | LLUUID this_region_id = agent_region->getRegionID(); | 3729 | LLUUID this_region_id = agent_region->getRegionID(); |
3625 | bool this_region_alive = agent_region->isAlive(); | 3730 | bool this_region_alive = agent_region->isAlive(); |
@@ -3639,6 +3744,9 @@ void LLAppViewer::disconnectViewer() | |||
3639 | { | 3744 | { |
3640 | return; | 3745 | return; |
3641 | } | 3746 | } |
3747 | |||
3748 | //set this true now, to prevent things from trying to access the network we are destroying | ||
3749 | gDisconnected = TRUE; | ||
3642 | // | 3750 | // |
3643 | // Cleanup after quitting. | 3751 | // Cleanup after quitting. |
3644 | // | 3752 | // |
@@ -3688,8 +3796,8 @@ void LLAppViewer::disconnectViewer() | |||
3688 | // Now we just ask the LLWorld singleton to cleanly shut down. | 3796 | // Now we just ask the LLWorld singleton to cleanly shut down. |
3689 | LLWorld::getInstance()->destroyClass(); | 3797 | LLWorld::getInstance()->destroyClass(); |
3690 | 3798 | ||
3799 | if (mQuitRequested) | ||
3691 | cleanup_xfer_manager(); | 3800 | cleanup_xfer_manager(); |
3692 | gDisconnected = TRUE; | ||
3693 | } | 3801 | } |
3694 | 3802 | ||
3695 | void LLAppViewer::forceErrorLLError() | 3803 | void LLAppViewer::forceErrorLLError() |