diff options
Diffstat (limited to 'linden/indra/newview/llappviewer.cpp')
-rw-r--r-- | linden/indra/newview/llappviewer.cpp | 295 |
1 files changed, 154 insertions, 141 deletions
diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index b2bfccf..4ab5d8d 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp | |||
@@ -4,7 +4,7 @@ | |||
4 | * | 4 | * |
5 | * $LicenseInfo:firstyear=2007&license=viewergpl$ | 5 | * $LicenseInfo:firstyear=2007&license=viewergpl$ |
6 | * | 6 | * |
7 | * Copyright (c) 2007-2008, Linden Research, Inc. | 7 | * Copyright (c) 2007-2009, Linden Research, Inc. |
8 | * | 8 | * |
9 | * Second Life Viewer Source Code | 9 | * Second Life Viewer Source Code |
10 | * The source code in this file ("Source Code") is provided by Linden Lab | 10 | * The source code in this file ("Source Code") is provided by Linden Lab |
@@ -192,35 +192,22 @@ | |||
192 | 192 | ||
193 | //---------------------------------------------------------------------------- | 193 | //---------------------------------------------------------------------------- |
194 | // viewer.cpp - these are only used in viewer, should be easily moved. | 194 | // viewer.cpp - these are only used in viewer, should be easily moved. |
195 | extern void disable_win_error_reporting(); | ||
196 | 195 | ||
197 | #if LL_DARWIN | 196 | #if LL_DARWIN |
198 | #include <Carbon/Carbon.h> | ||
199 | extern void init_apple_menu(const char* product); | 197 | extern void init_apple_menu(const char* product); |
200 | extern OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn); | ||
201 | extern OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn); | ||
202 | extern OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata); | ||
203 | #include <boost/tokenizer.hpp> | ||
204 | #endif // LL_DARWIN | 198 | #endif // LL_DARWIN |
205 | 199 | ||
206 | |||
207 | extern BOOL gRandomizeFramerate; | 200 | extern BOOL gRandomizeFramerate; |
208 | extern BOOL gPeriodicSlowFrame; | 201 | extern BOOL gPeriodicSlowFrame; |
209 | extern BOOL gDebugGL; | 202 | extern BOOL gDebugGL; |
210 | 203 | ||
211 | //////////////////////////////////////////////////////////// | 204 | //////////////////////////////////////////////////////////// |
212 | // All from the last globals push... | 205 | // All from the last globals push... |
213 | BOOL gHandleKeysAsync = FALSE; | ||
214 | |||
215 | const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user flagged as Away From Keyboard | 206 | const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user flagged as Away From Keyboard |
216 | 207 | ||
217 | F32 gSimLastTime; // Used in LLAppViewer::init and send_stats() | 208 | F32 gSimLastTime; // Used in LLAppViewer::init and send_stats() |
218 | F32 gSimFrames; | 209 | F32 gSimFrames; |
219 | 210 | ||
220 | std::string gDisabledMessage; // Set in LLAppViewer::initConfiguration used in idle_startup | ||
221 | |||
222 | BOOL gHideLinks = FALSE; // Set in LLAppViewer::initConfiguration, used externally | ||
223 | |||
224 | BOOL gAllowIdleAFK = TRUE; | 211 | BOOL gAllowIdleAFK = TRUE; |
225 | BOOL gAllowTapTapHoldRun = TRUE; | 212 | BOOL gAllowTapTapHoldRun = TRUE; |
226 | BOOL gShowObjectUpdates = FALSE; | 213 | BOOL gShowObjectUpdates = FALSE; |
@@ -246,7 +233,7 @@ F32 gFPSClamped = 10.f; // Pretend we start at target rate. | |||
246 | F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets | 233 | F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets |
247 | U64 gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds | 234 | U64 gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds |
248 | U32 gFrameStalls = 0; | 235 | U32 gFrameStalls = 0; |
249 | const F64 FRAME_STALL_THRESHOLD = 5.0; | 236 | const F64 FRAME_STALL_THRESHOLD = 1.0; |
250 | 237 | ||
251 | LLTimer gRenderStartTime; | 238 | LLTimer gRenderStartTime; |
252 | LLFrameTimer gForegroundTime; | 239 | LLFrameTimer gForegroundTime; |
@@ -316,6 +303,7 @@ std::string gLoginPage; | |||
316 | std::vector<std::string> gLoginURIs; | 303 | std::vector<std::string> gLoginURIs; |
317 | static std::string gHelperURI; | 304 | static std::string gHelperURI; |
318 | 305 | ||
306 | LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ; | ||
319 | 307 | ||
320 | void idle_afk_check() | 308 | void idle_afk_check() |
321 | { | 309 | { |
@@ -331,8 +319,7 @@ static void ui_audio_callback(const LLUUID& uuid) | |||
331 | { | 319 | { |
332 | if (gAudiop) | 320 | if (gAudiop) |
333 | { | 321 | { |
334 | F32 volume = gSavedSettings.getBOOL("MuteUI") ? 0.f : gSavedSettings.getF32("AudioLevelUI"); | 322 | gAudiop->triggerSound(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI); |
335 | gAudiop->triggerSound(uuid, gAgent.getID(), volume); | ||
336 | } | 323 | } |
337 | } | 324 | } |
338 | 325 | ||
@@ -419,7 +406,6 @@ static void settings_to_globals() | |||
419 | gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); | 406 | gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); |
420 | gMapScale = gSavedSettings.getF32("MapScale"); | 407 | gMapScale = gSavedSettings.getF32("MapScale"); |
421 | gMiniMapScale = gSavedSettings.getF32("MiniMapScale"); | 408 | gMiniMapScale = gSavedSettings.getF32("MiniMapScale"); |
422 | gHandleKeysAsync = gSavedSettings.getBOOL("AsyncKeyboard"); | ||
423 | LLHoverView::sShowHoverTips = gSavedSettings.getBOOL("ShowHoverTips"); | 409 | LLHoverView::sShowHoverTips = gSavedSettings.getBOOL("ShowHoverTips"); |
424 | 410 | ||
425 | LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap"); | 411 | LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap"); |
@@ -498,30 +484,17 @@ void LLAppViewer::initGridChoice() | |||
498 | } | 484 | } |
499 | } | 485 | } |
500 | 486 | ||
501 | bool send_url_to_other_instance(const std::string& url) | 487 | //virtual |
488 | bool LLAppViewer::initSLURLHandler() | ||
502 | { | 489 | { |
503 | #if LL_WINDOWS | 490 | // does nothing unless subclassed |
504 | wchar_t window_class[256]; /* Flawfinder: ignore */ // Assume max length < 255 chars. | 491 | return false; |
505 | mbstowcs(window_class, sWindowClass, 255); | 492 | } |
506 | window_class[255] = 0; | 493 | |
507 | // Use the class instead of the window name. | 494 | //virtual |
508 | HWND other_window = FindWindow(window_class, NULL); | 495 | bool LLAppViewer::sendURLToOtherInstance(const std::string& url) |
509 | 496 | { | |
510 | if (other_window != NULL) | 497 | // does nothing unless subclassed |
511 | { | ||
512 | lldebugs << "Found other window with the name '" << gWindowTitle << "'" << llendl; | ||
513 | COPYDATASTRUCT cds; | ||
514 | const S32 SLURL_MESSAGE_TYPE = 0; | ||
515 | cds.dwData = SLURL_MESSAGE_TYPE; | ||
516 | cds.cbData = url.length() + 1; | ||
517 | cds.lpData = (void*)url.c_str(); | ||
518 | |||
519 | LRESULT msg_result = SendMessage(other_window, WM_COPYDATA, NULL, (LPARAM)&cds); | ||
520 | lldebugs << "SendMessage(WM_COPYDATA) to other window '" | ||
521 | << gWindowTitle << "' returned " << msg_result << llendl; | ||
522 | return true; | ||
523 | } | ||
524 | #endif | ||
525 | return false; | 498 | return false; |
526 | } | 499 | } |
527 | 500 | ||
@@ -690,6 +663,7 @@ bool LLAppViewer::init() | |||
690 | ui_audio_callback, | 663 | ui_audio_callback, |
691 | &LLUI::sGLScaleFactor); | 664 | &LLUI::sGLScaleFactor); |
692 | LLWeb::initClass(); // do this after LLUI | 665 | LLWeb::initClass(); // do this after LLUI |
666 | |||
693 | LLTextEditor::setURLCallbacks(&LLWeb::loadURL, | 667 | LLTextEditor::setURLCallbacks(&LLWeb::loadURL, |
694 | &LLURLDispatcher::dispatchFromTextEditor, | 668 | &LLURLDispatcher::dispatchFromTextEditor, |
695 | &LLURLDispatcher::dispatchFromTextEditor); | 669 | &LLURLDispatcher::dispatchFromTextEditor); |
@@ -710,7 +684,6 @@ bool LLAppViewer::init() | |||
710 | // load MIME type -> media impl mappings | 684 | // load MIME type -> media impl mappings |
711 | LLMIMETypes::parseMIMETypes( std::string("mime_types.xml") ); | 685 | LLMIMETypes::parseMIMETypes( std::string("mime_types.xml") ); |
712 | 686 | ||
713 | |||
714 | // Copy settings to globals. *TODO: Remove or move to appropriage class initializers | 687 | // Copy settings to globals. *TODO: Remove or move to appropriage class initializers |
715 | settings_to_globals(); | 688 | settings_to_globals(); |
716 | // Setup settings listeners | 689 | // Setup settings listeners |
@@ -721,6 +694,9 @@ bool LLAppViewer::init() | |||
721 | // Find partition serial number (Windows) or hardware serial (Mac) | 694 | // Find partition serial number (Windows) or hardware serial (Mac) |
722 | mSerialNumber = generateSerialNumber(); | 695 | mSerialNumber = generateSerialNumber(); |
723 | 696 | ||
697 | // do any necessary set-up for accepting incoming SLURLs from apps | ||
698 | initSLURLHandler(); | ||
699 | |||
724 | if(false == initHardwareTest()) | 700 | if(false == initHardwareTest()) |
725 | { | 701 | { |
726 | // Early out from user choice. | 702 | // Early out from user choice. |
@@ -851,7 +827,10 @@ bool LLAppViewer::init() | |||
851 | } | 827 | } |
852 | 828 | ||
853 | } | 829 | } |
854 | 830 | ||
831 | // save the graphics card | ||
832 | gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString(); | ||
833 | |||
855 | // Save the current version to the prefs file | 834 | // Save the current version to the prefs file |
856 | gSavedSettings.setString("LastRunVersion", gCurrentVersion); | 835 | gSavedSettings.setString("LastRunVersion", gCurrentVersion); |
857 | 836 | ||
@@ -896,16 +875,21 @@ bool LLAppViewer::mainLoop() | |||
896 | { | 875 | { |
897 | LLFastTimer t(LLFastTimer::FTM_FRAME); | 876 | LLFastTimer t(LLFastTimer::FTM_FRAME); |
898 | 877 | ||
878 | pingMainloopTimeout("Main:MiscNativeWindowEvents"); | ||
879 | |||
880 | { | ||
881 | LLFastTimer t2(LLFastTimer::FTM_MESSAGES); | ||
882 | gViewerWindow->mWindow->processMiscNativeEvents(); | ||
883 | } | ||
884 | |||
899 | pingMainloopTimeout("Main:GatherInput"); | 885 | pingMainloopTimeout("Main:GatherInput"); |
900 | 886 | ||
901 | { | 887 | { |
902 | LLFastTimer t2(LLFastTimer::FTM_MESSAGES); | 888 | LLFastTimer t2(LLFastTimer::FTM_MESSAGES); |
903 | #if LL_WINDOWS | 889 | if (!restoreErrorTrap()) |
904 | if (!LLWinDebug::checkExceptionHandler()) | ||
905 | { | 890 | { |
906 | llwarns << " Someone took over my exception handler (post messagehandling)!" << llendl; | 891 | llwarns << " Someone took over my signal/exception handler (post messagehandling)!" << llendl; |
907 | } | 892 | } |
908 | #endif | ||
909 | 893 | ||
910 | gViewerWindow->mWindow->gatherInput(); | 894 | gViewerWindow->mWindow->gatherInput(); |
911 | } | 895 | } |
@@ -961,7 +945,7 @@ bool LLAppViewer::mainLoop() | |||
961 | 945 | ||
962 | resumeMainloopTimeout(); | 946 | resumeMainloopTimeout(); |
963 | } | 947 | } |
964 | 948 | ||
965 | if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) | 949 | if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) |
966 | { | 950 | { |
967 | pauseMainloopTimeout(); | 951 | pauseMainloopTimeout(); |
@@ -1183,17 +1167,24 @@ bool LLAppViewer::cleanup() | |||
1183 | 1167 | ||
1184 | llinfos << "Global stuff deleted" << llendflush; | 1168 | llinfos << "Global stuff deleted" << llendflush; |
1185 | 1169 | ||
1186 | #if (!defined(LL_FMOD)) || (!LL_RELEASE_FOR_DOWNLOAD) | ||
1187 | // OpenAL likes to crash on exit if we *don't* explicitly shut it down. | ||
1188 | if (gAudiop) | 1170 | if (gAudiop) |
1189 | { | 1171 | { |
1190 | gAudiop->shutdown(); | 1172 | bool want_longname = false; |
1173 | if (gAudiop->getDriverName(want_longname) == "FMOD") | ||
1174 | { | ||
1175 | // This hack exists because fmod likes to occasionally | ||
1176 | // hang forever when shutting down, for no apparent | ||
1177 | // reason. | ||
1178 | llwarns << "Hack, skipping FMOD audio engine cleanup" << llendflush; | ||
1179 | } | ||
1180 | else | ||
1181 | { | ||
1182 | gAudiop->shutdown(); | ||
1183 | } | ||
1184 | |||
1185 | delete gAudiop; | ||
1186 | gAudiop = NULL; | ||
1191 | } | 1187 | } |
1192 | #else | ||
1193 | // This hack exists because fmod likes to occasionally hang forever | ||
1194 | // when shutting down for no apparent reason. | ||
1195 | llwarns << "Hack, skipping audio engine cleanup" << llendflush; | ||
1196 | #endif | ||
1197 | 1188 | ||
1198 | // Note: this is where LLFeatureManager::getInstance()-> used to be deleted. | 1189 | // Note: this is where LLFeatureManager::getInstance()-> used to be deleted. |
1199 | 1190 | ||
@@ -1204,9 +1195,6 @@ bool LLAppViewer::cleanup() | |||
1204 | cleanupSavedSettings(); | 1195 | cleanupSavedSettings(); |
1205 | llinfos << "Settings patched up" << llendflush; | 1196 | llinfos << "Settings patched up" << llendflush; |
1206 | 1197 | ||
1207 | delete gAudiop; | ||
1208 | gAudiop = NULL; | ||
1209 | |||
1210 | // delete some of the files left around in the cache. | 1198 | // delete some of the files left around in the cache. |
1211 | removeCacheFiles("*.wav"); | 1199 | removeCacheFiles("*.wav"); |
1212 | removeCacheFiles("*.tmp"); | 1200 | removeCacheFiles("*.tmp"); |
@@ -1375,12 +1363,15 @@ bool LLAppViewer::cleanup() | |||
1375 | delete sImageDecodeThread; | 1363 | delete sImageDecodeThread; |
1376 | sImageDecodeThread = NULL; | 1364 | sImageDecodeThread = NULL; |
1377 | 1365 | ||
1366 | //Note: | ||
1367 | //LLViewerMedia::cleanupClass() has to be put before gImageList.shutdown() | ||
1368 | //because some new image might be generated during cleaning up media. --bao | ||
1369 | LLViewerMedia::cleanupClass(); | ||
1378 | gImageList.shutdown(); // shutdown again in case a callback added something | 1370 | gImageList.shutdown(); // shutdown again in case a callback added something |
1379 | LLUIImageList::getInstance()->cleanUp(); | 1371 | LLUIImageList::getInstance()->cleanUp(); |
1380 | 1372 | ||
1381 | // This should eventually be done in LLAppViewer | 1373 | // This should eventually be done in LLAppViewer |
1382 | LLImageJ2C::closeDSO(); | 1374 | LLImage::cleanupClass(); |
1383 | LLImageFormatted::cleanupClass(); | ||
1384 | LLVFSThread::cleanupClass(); | 1375 | LLVFSThread::cleanupClass(); |
1385 | LLLFSThread::cleanupClass(); | 1376 | LLLFSThread::cleanupClass(); |
1386 | 1377 | ||
@@ -1401,14 +1392,17 @@ bool LLAppViewer::cleanup() | |||
1401 | LLWatchdog::getInstance()->cleanup(); | 1392 | LLWatchdog::getInstance()->cleanup(); |
1402 | 1393 | ||
1403 | end_messaging_system(); | 1394 | end_messaging_system(); |
1395 | llinfos << "Message system deleted." << llendflush; | ||
1404 | 1396 | ||
1405 | // *NOTE:Mani - The following call is not thread safe. | 1397 | // *NOTE:Mani - The following call is not thread safe. |
1406 | LLCurl::cleanupClass(); | 1398 | LLCurl::cleanupClass(); |
1399 | llinfos << "LLCurl cleaned up." << llendflush; | ||
1407 | 1400 | ||
1408 | // If we're exiting to launch an URL, do that here so the screen | 1401 | // If we're exiting to launch an URL, do that here so the screen |
1409 | // is at the right resolution before we launch IE. | 1402 | // is at the right resolution before we launch IE. |
1410 | if (!gLaunchFileOnQuit.empty()) | 1403 | if (!gLaunchFileOnQuit.empty()) |
1411 | { | 1404 | { |
1405 | llinfos << "Launch file on quit." << llendflush; | ||
1412 | #if LL_WINDOWS | 1406 | #if LL_WINDOWS |
1413 | // Indicate an application is starting. | 1407 | // Indicate an application is starting. |
1414 | SetCursor(LoadCursor(NULL, IDC_WAIT)); | 1408 | SetCursor(LoadCursor(NULL, IDC_WAIT)); |
@@ -1418,9 +1412,8 @@ bool LLAppViewer::cleanup() | |||
1418 | ms_sleep(1000); | 1412 | ms_sleep(1000); |
1419 | 1413 | ||
1420 | LLWeb::loadURLExternal( gLaunchFileOnQuit ); | 1414 | LLWeb::loadURLExternal( gLaunchFileOnQuit ); |
1415 | llinfos << "File launched." << llendflush; | ||
1421 | } | 1416 | } |
1422 | |||
1423 | LLViewerMedia::cleanupClass(); | ||
1424 | 1417 | ||
1425 | llinfos << "Goodbye" << llendflush; | 1418 | llinfos << "Goodbye" << llendflush; |
1426 | 1419 | ||
@@ -1428,6 +1421,25 @@ bool LLAppViewer::cleanup() | |||
1428 | return true; | 1421 | return true; |
1429 | } | 1422 | } |
1430 | 1423 | ||
1424 | // A callback for llerrs to call during the watchdog error. | ||
1425 | void watchdog_llerrs_callback(const std::string &error_string) | ||
1426 | { | ||
1427 | gLLErrorActivated = true; | ||
1428 | |||
1429 | #ifdef LL_WINDOWS | ||
1430 | RaiseException(0,0,0,0); | ||
1431 | #else | ||
1432 | raise(SIGQUIT); | ||
1433 | #endif | ||
1434 | } | ||
1435 | |||
1436 | // A callback for the watchdog to call. | ||
1437 | void watchdog_killer_callback() | ||
1438 | { | ||
1439 | LLError::setFatalFunction(watchdog_llerrs_callback); | ||
1440 | llerrs << "Watchdog killer event" << llendl; | ||
1441 | } | ||
1442 | |||
1431 | bool LLAppViewer::initThreads() | 1443 | bool LLAppViewer::initThreads() |
1432 | { | 1444 | { |
1433 | #if MEM_TRACK_MEM | 1445 | #if MEM_TRACK_MEM |
@@ -1437,10 +1449,11 @@ bool LLAppViewer::initThreads() | |||
1437 | #endif | 1449 | #endif |
1438 | 1450 | ||
1439 | const S32 NEVER_SUBMIT_REPORT = 2; | 1451 | const S32 NEVER_SUBMIT_REPORT = 2; |
1440 | if(TRUE == gSavedSettings.getBOOL("WatchdogEnabled") | 1452 | bool use_watchdog = gSavedSettings.getBOOL("WatchdogEnabled"); |
1441 | && (gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING) != NEVER_SUBMIT_REPORT)) | 1453 | bool send_reports = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING) != NEVER_SUBMIT_REPORT; |
1454 | if(use_watchdog && send_reports) | ||
1442 | { | 1455 | { |
1443 | LLWatchdog::getInstance()->init(); | 1456 | LLWatchdog::getInstance()->init(watchdog_killer_callback); |
1444 | } | 1457 | } |
1445 | 1458 | ||
1446 | LLVFSThread::initClass(enable_threads && true); | 1459 | LLVFSThread::initClass(enable_threads && true); |
@@ -1450,8 +1463,7 @@ bool LLAppViewer::initThreads() | |||
1450 | LLAppViewer::sImageDecodeThread = new LLWorkerThread("ImageDecode", enable_threads && true); | 1463 | LLAppViewer::sImageDecodeThread = new LLWorkerThread("ImageDecode", enable_threads && true); |
1451 | LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true); | 1464 | LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true); |
1452 | LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), enable_threads && false); | 1465 | LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), enable_threads && false); |
1453 | LLImageWorker::initClass(LLAppViewer::getImageDecodeThread()); | 1466 | LLImage::initClass(LLAppViewer::getImageDecodeThread()); |
1454 | LLImageJ2C::openDSO(); | ||
1455 | 1467 | ||
1456 | // *FIX: no error handling here! | 1468 | // *FIX: no error handling here! |
1457 | return true; | 1469 | return true; |
@@ -1883,22 +1895,6 @@ bool LLAppViewer::initConfiguration() | |||
1883 | // llerrs << "Failed to parse skin definition." << llendl; | 1895 | // llerrs << "Failed to parse skin definition." << llendl; |
1884 | // } | 1896 | // } |
1885 | 1897 | ||
1886 | // LLXmlTreeNode* rootp = skin_def_tree.getRoot(); | ||
1887 | // LLXmlTreeNode* disabled_message_node = rootp->getChildByName("disabled_message"); | ||
1888 | // if (disabled_message_node) | ||
1889 | // { | ||
1890 | // gDisabledMessage = disabled_message_node->getContents(); | ||
1891 | // } | ||
1892 | |||
1893 | // static LLStdStringHandle hide_links_string = LLXmlTree::addAttributeString("hide_links"); | ||
1894 | // rootp->getFastAttributeBOOL(hide_links_string, gHideLinks); | ||
1895 | |||
1896 | // // Legacy string. This flag really meant we didn't want to expose references to "Second Life". | ||
1897 | // // Just set gHideLinks instead. | ||
1898 | // static LLStdStringHandle silent_string = LLXmlTree::addAttributeString("silent_update"); | ||
1899 | // BOOL silent_update; | ||
1900 | // rootp->getFastAttributeBOOL(silent_string, silent_update); | ||
1901 | // gHideLinks = (gHideLinks || silent_update); | ||
1902 | //} | 1898 | //} |
1903 | 1899 | ||
1904 | #if LL_DARWIN | 1900 | #if LL_DARWIN |
@@ -1951,7 +1947,7 @@ bool LLAppViewer::initConfiguration() | |||
1951 | #endif | 1947 | #endif |
1952 | LLStringUtil::truncate(gWindowTitle, 255); | 1948 | LLStringUtil::truncate(gWindowTitle, 255); |
1953 | 1949 | ||
1954 | //RN: if we received a URL, hand it off to the existing instance | 1950 | //RN: if we received a URL, hand it off to the existing instance. |
1955 | // don't call anotherInstanceRunning() when doing URL handoff, as | 1951 | // don't call anotherInstanceRunning() when doing URL handoff, as |
1956 | // it relies on checking a marker file which will not work when running | 1952 | // it relies on checking a marker file which will not work when running |
1957 | // out of different directories | 1953 | // out of different directories |
@@ -1966,7 +1962,7 @@ bool LLAppViewer::initConfiguration() | |||
1966 | } | 1962 | } |
1967 | if (!slurl.empty()) | 1963 | if (!slurl.empty()) |
1968 | { | 1964 | { |
1969 | if (send_url_to_other_instance(slurl)) | 1965 | if (sendURLToOtherInstance(slurl)) |
1970 | { | 1966 | { |
1971 | // successfully handed off URL to existing instance, exit | 1967 | // successfully handed off URL to existing instance, exit |
1972 | return false; | 1968 | return false; |
@@ -1997,7 +1993,7 @@ bool LLAppViewer::initConfiguration() | |||
1997 | } | 1993 | } |
1998 | 1994 | ||
1999 | initMarkerFile(); | 1995 | initMarkerFile(); |
2000 | 1996 | ||
2001 | #if LL_SEND_CRASH_REPORTS | 1997 | #if LL_SEND_CRASH_REPORTS |
2002 | if (gLastExecEvent == LAST_EXEC_FROZE) | 1998 | if (gLastExecEvent == LAST_EXEC_FROZE) |
2003 | { | 1999 | { |
@@ -2019,52 +2015,8 @@ bool LLAppViewer::initConfiguration() | |||
2019 | { | 2015 | { |
2020 | llinfos << "Sending crash report." << llendl; | 2016 | llinfos << "Sending crash report." << llendl; |
2021 | 2017 | ||
2022 | #if LL_WINDOWS | 2018 | bool report_freeze = true; |
2023 | std::string exe_path = gDirUtilp->getAppRODataDir(); | 2019 | handleCrashReporting(report_freeze); |
2024 | exe_path += gDirUtilp->getDirDelimiter(); | ||
2025 | exe_path += "win_crash_logger.exe"; | ||
2026 | |||
2027 | std::string arg_string = "-previous "; | ||
2028 | // Spawn crash logger. | ||
2029 | // NEEDS to wait until completion, otherwise log files will get smashed. | ||
2030 | _spawnl(_P_WAIT, exe_path.c_str(), exe_path.c_str(), arg_string.c_str(), NULL); | ||
2031 | #elif LL_DARWIN | ||
2032 | std::string command_str; | ||
2033 | command_str = "mac-crash-logger.app/Contents/MacOS/mac-crash-logger "; | ||
2034 | command_str += "-previous"; | ||
2035 | // XXX -- We need to exit fullscreen mode for this to work. | ||
2036 | // XXX -- system() also doesn't wait for completion. Hmm... | ||
2037 | system(command_str.c_str()); /* Flawfinder: Ignore */ | ||
2038 | #elif LL_LINUX || LL_SOLARIS | ||
2039 | std::string cmd =gDirUtilp->getAppRODataDir(); | ||
2040 | cmd += gDirUtilp->getDirDelimiter(); | ||
2041 | #if LL_LINUX | ||
2042 | cmd += "linux-crash-logger.bin"; | ||
2043 | #else // LL_SOLARIS | ||
2044 | cmd += "bin/solaris-crash-logger"; | ||
2045 | #endif // LL_LINUX | ||
2046 | char* const cmdargv[] = | ||
2047 | {(char*)cmd.c_str(), | ||
2048 | (char*)"-previous", | ||
2049 | NULL}; | ||
2050 | fflush(NULL); // flush all buffers before the child inherits them | ||
2051 | pid_t pid = fork(); | ||
2052 | if (pid == 0) | ||
2053 | { // child | ||
2054 | execv(cmd.c_str(), cmdargv); /* Flawfinder: Ignore */ | ||
2055 | llwarns << "execv failure when trying to start " << cmd << llendl; | ||
2056 | _exit(1); // avoid atexit() | ||
2057 | } else { | ||
2058 | if (pid > 0) | ||
2059 | { | ||
2060 | // wait for child proc to die | ||
2061 | int childExitStatus; | ||
2062 | waitpid(pid, &childExitStatus, 0); | ||
2063 | } else { | ||
2064 | llwarns << "fork failure." << llendl; | ||
2065 | } | ||
2066 | } | ||
2067 | #endif | ||
2068 | } | 2020 | } |
2069 | else | 2021 | else |
2070 | { | 2022 | { |
@@ -2229,7 +2181,6 @@ void LLAppViewer::cleanupSavedSettings() | |||
2229 | 2181 | ||
2230 | gSavedSettings.setF32("MapScale", gMapScale ); | 2182 | gSavedSettings.setF32("MapScale", gMapScale ); |
2231 | gSavedSettings.setF32("MiniMapScale", gMiniMapScale ); | 2183 | gSavedSettings.setF32("MiniMapScale", gMiniMapScale ); |
2232 | gSavedSettings.setBOOL("AsyncKeyboard", gHandleKeysAsync); | ||
2233 | gSavedSettings.setBOOL("ShowHoverTips", LLHoverView::sShowHoverTips); | 2184 | gSavedSettings.setBOOL("ShowHoverTips", LLHoverView::sShowHoverTips); |
2234 | 2185 | ||
2235 | // Some things are cached in LLAgent. | 2186 | // Some things are cached in LLAgent. |
@@ -2271,7 +2222,7 @@ void LLAppViewer::writeSystemInfo() | |||
2271 | gDebugInfo["RAMInfo"]["Physical"] = (LLSD::Integer)(gSysMemory.getPhysicalMemoryKB()); | 2222 | gDebugInfo["RAMInfo"]["Physical"] = (LLSD::Integer)(gSysMemory.getPhysicalMemoryKB()); |
2272 | gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer)(gMemoryAllocated>>10); // MB -> KB | 2223 | gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer)(gMemoryAllocated>>10); // MB -> KB |
2273 | gDebugInfo["OSInfo"] = getOSInfo().getOSStringSimple(); | 2224 | gDebugInfo["OSInfo"] = getOSInfo().getOSStringSimple(); |
2274 | 2225 | ||
2275 | // The user is not logged on yet, but record the current grid choice login url | 2226 | // The user is not logged on yet, but record the current grid choice login url |
2276 | // which may have been the intended grid. This can b | 2227 | // which may have been the intended grid. This can b |
2277 | gDebugInfo["GridName"] = LLViewerLogin::getInstance()->getGridLabel(); | 2228 | gDebugInfo["GridName"] = LLViewerLogin::getInstance()->getGridLabel(); |
@@ -2282,6 +2233,13 @@ void LLAppViewer::writeSystemInfo() | |||
2282 | gDebugInfo["MainloopThreadID"] = (S32)thread_id; | 2233 | gDebugInfo["MainloopThreadID"] = (S32)thread_id; |
2283 | #endif | 2234 | #endif |
2284 | 2235 | ||
2236 | // "CrashNotHandled" is set here, while things are running well, | ||
2237 | // in case of a freeze. If there is a freeze, the crash logger will be launched | ||
2238 | // and can read this value from the debug_info.log. | ||
2239 | // If the crash is handled by LLAppViewer::handleViewerCrash, ie not a freeze, | ||
2240 | // then the value of "CrashNotHandled" will be set to true. | ||
2241 | gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)true; | ||
2242 | |||
2285 | // Dump some debugging info | 2243 | // Dump some debugging info |
2286 | LL_INFOS("SystemInfo") << gCurrentVersion << LL_ENDL; | 2244 | LL_INFOS("SystemInfo") << gCurrentVersion << LL_ENDL; |
2287 | 2245 | ||
@@ -2358,6 +2316,10 @@ void LLAppViewer::handleViewerCrash() | |||
2358 | gDebugInfo["CAFilename"] = gDirUtilp->getCAFile(); | 2316 | gDebugInfo["CAFilename"] = gDirUtilp->getCAFile(); |
2359 | gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); | 2317 | gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); |
2360 | gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); | 2318 | gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); |
2319 | gDebugInfo["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds()); | ||
2320 | gDebugInfo["StartupState"] = LLStartUp::getStartupStateString(); | ||
2321 | gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer) getCurrentRSS() >> 10; | ||
2322 | |||
2361 | if(gLogoutInProgress) | 2323 | if(gLogoutInProgress) |
2362 | { | 2324 | { |
2363 | gDebugInfo["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH; | 2325 | gDebugInfo["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH; |
@@ -2383,6 +2345,9 @@ void LLAppViewer::handleViewerCrash() | |||
2383 | gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); | 2345 | gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); |
2384 | } | 2346 | } |
2385 | 2347 | ||
2348 | // The crash is being handled here so set this value to false. | ||
2349 | // Otherwise the crash logger will think this crash was a freeze. | ||
2350 | gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)false; | ||
2386 | 2351 | ||
2387 | //Write out the crash status file | 2352 | //Write out the crash status file |
2388 | //Use marker file style setup, as that's the simplest, especially since | 2353 | //Use marker file style setup, as that's the simplest, especially since |
@@ -2466,24 +2431,23 @@ bool LLAppViewer::anotherInstanceRunning() | |||
2466 | { | 2431 | { |
2467 | // Another instance is running. Skip the rest of these operations. | 2432 | // Another instance is running. Skip the rest of these operations. |
2468 | LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL; | 2433 | LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL; |
2469 | return TRUE; | 2434 | return true; |
2470 | } | 2435 | } |
2471 | if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) //flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1) | 2436 | if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) //flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1) |
2472 | { | 2437 | { |
2473 | apr_file_close(fMarker); | 2438 | apr_file_close(fMarker); |
2474 | LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL; | 2439 | LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL; |
2475 | return TRUE; | 2440 | return true; |
2476 | } | 2441 | } |
2477 | // No other instances; we'll lock this file now & delete on quit. | 2442 | // No other instances; we'll lock this file now & delete on quit. |
2478 | apr_file_close(fMarker); | 2443 | apr_file_close(fMarker); |
2479 | } | 2444 | } |
2480 | LL_DEBUGS("MarkerFile") << "Marker file isn't locked." << LL_ENDL; | 2445 | LL_DEBUGS("MarkerFile") << "Marker file isn't locked." << LL_ENDL; |
2481 | return FALSE; | 2446 | return false; |
2482 | } | 2447 | } |
2483 | 2448 | ||
2484 | void LLAppViewer::initMarkerFile() | 2449 | void LLAppViewer::initMarkerFile() |
2485 | { | 2450 | { |
2486 | |||
2487 | //First, check for the existence of other files. | 2451 | //First, check for the existence of other files. |
2488 | //There are marker files for two different types of crashes | 2452 | //There are marker files for two different types of crashes |
2489 | 2453 | ||
@@ -2738,7 +2702,7 @@ bool LLAppViewer::initCache() | |||
2738 | 2702 | ||
2739 | // Init the texture cache | 2703 | // Init the texture cache |
2740 | // Allocate 80% of the cache size for textures | 2704 | // Allocate 80% of the cache size for textures |
2741 | BOOL read_only = mSecondInstance ? true : false; | 2705 | BOOL read_only = mSecondInstance ? TRUE : FALSE; |
2742 | const S32 MB = 1024*1024; | 2706 | const S32 MB = 1024*1024; |
2743 | S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB; | 2707 | S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB; |
2744 | const S64 MAX_CACHE_SIZE = 1024*MB; | 2708 | const S64 MAX_CACHE_SIZE = 1024*MB; |
@@ -3539,12 +3503,12 @@ void LLAppViewer::sendLogoutRequest() | |||
3539 | if (mLogoutMarkerFile) | 3503 | if (mLogoutMarkerFile) |
3540 | { | 3504 | { |
3541 | llinfos << "Created logout marker file " << mLogoutMarkerFileName << llendl; | 3505 | llinfos << "Created logout marker file " << mLogoutMarkerFileName << llendl; |
3506 | apr_file_close(mLogoutMarkerFile); | ||
3542 | } | 3507 | } |
3543 | else | 3508 | else |
3544 | { | 3509 | { |
3545 | llwarns << "Cannot create logout marker file " << mLogoutMarkerFileName << llendl; | 3510 | llwarns << "Cannot create logout marker file " << mLogoutMarkerFileName << llendl; |
3546 | } | 3511 | } |
3547 | apr_file_close(mLogoutMarkerFile); | ||
3548 | } | 3512 | } |
3549 | } | 3513 | } |
3550 | 3514 | ||
@@ -3765,6 +3729,11 @@ void LLAppViewer::forceErrorSoftwareException() | |||
3765 | throw; | 3729 | throw; |
3766 | } | 3730 | } |
3767 | 3731 | ||
3732 | void LLAppViewer::forceErrorDriverCrash() | ||
3733 | { | ||
3734 | glDeleteTextures(1, NULL); | ||
3735 | } | ||
3736 | |||
3768 | void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs) | 3737 | void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs) |
3769 | { | 3738 | { |
3770 | if(!mMainloopTimeout) | 3739 | if(!mMainloopTimeout) |
@@ -3807,6 +3776,11 @@ void LLAppViewer::pauseMainloopTimeout() | |||
3807 | 3776 | ||
3808 | void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs) | 3777 | void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs) |
3809 | { | 3778 | { |
3779 | // if(!restoreErrorTrap()) | ||
3780 | // { | ||
3781 | // llwarns << "!!!!!!!!!!!!! Its an error trap!!!!" << state << llendl; | ||
3782 | // } | ||
3783 | |||
3810 | if(mMainloopTimeout) | 3784 | if(mMainloopTimeout) |
3811 | { | 3785 | { |
3812 | if(secs < 0.0f) | 3786 | if(secs < 0.0f) |
@@ -3819,3 +3793,42 @@ void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs) | |||
3819 | } | 3793 | } |
3820 | } | 3794 | } |
3821 | 3795 | ||
3796 | void LLAppViewer::handleLoginComplete() | ||
3797 | { | ||
3798 | initMainloopTimeout("Mainloop Init"); | ||
3799 | |||
3800 | // Store some data to DebugInfo in case of a freeze. | ||
3801 | gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName"); | ||
3802 | |||
3803 | gDebugInfo["ClientInfo"]["MajorVersion"] = LL_VERSION_MAJOR; | ||
3804 | gDebugInfo["ClientInfo"]["MinorVersion"] = LL_VERSION_MINOR; | ||
3805 | gDebugInfo["ClientInfo"]["PatchVersion"] = LL_VERSION_PATCH; | ||
3806 | gDebugInfo["ClientInfo"]["BuildVersion"] = LL_VERSION_BUILD; | ||
3807 | |||
3808 | LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); | ||
3809 | if ( parcel && parcel->getMusicURL()[0]) | ||
3810 | { | ||
3811 | gDebugInfo["ParcelMusicURL"] = parcel->getMusicURL(); | ||
3812 | } | ||
3813 | if ( parcel && parcel->getMediaURL()[0]) | ||
3814 | { | ||
3815 | gDebugInfo["ParcelMediaURL"] = parcel->getMediaURL(); | ||
3816 | } | ||
3817 | |||
3818 | gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile"); | ||
3819 | gDebugInfo["CAFilename"] = gDirUtilp->getCAFile(); | ||
3820 | gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); | ||
3821 | gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); | ||
3822 | |||
3823 | if(gAgent.getRegion()) | ||
3824 | { | ||
3825 | gDebugInfo["CurrentSimHost"] = gAgent.getRegionHost().getHostName(); | ||
3826 | gDebugInfo["CurrentRegion"] = gAgent.getRegion()->getName(); | ||
3827 | } | ||
3828 | |||
3829 | if(LLAppViewer::instance()->mMainloopTimeout) | ||
3830 | { | ||
3831 | gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState(); | ||
3832 | } | ||
3833 | writeDebugInfo(); | ||
3834 | } | ||