diff options
author | Jacek Antonelli | 2008-08-15 23:45:29 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:29 -0500 |
commit | 7bdb4845afdd157f95281293803567090e3f992a (patch) | |
tree | fbcada1c227d7407f9f37ccba360bfe6326d9c5e /linden/indra/newview/llappviewer.cpp | |
parent | Second Life viewer sources 1.19.0.0 (diff) | |
download | meta-impy-7bdb4845afdd157f95281293803567090e3f992a.zip meta-impy-7bdb4845afdd157f95281293803567090e3f992a.tar.gz meta-impy-7bdb4845afdd157f95281293803567090e3f992a.tar.bz2 meta-impy-7bdb4845afdd157f95281293803567090e3f992a.tar.xz |
Second Life viewer sources 1.19.0.2
Diffstat (limited to 'linden/indra/newview/llappviewer.cpp')
-rw-r--r-- | linden/indra/newview/llappviewer.cpp | 152 |
1 files changed, 85 insertions, 67 deletions
diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index c357b8f..2933fe9 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp | |||
@@ -270,7 +270,7 @@ BOOL gAcceptTOS = FALSE; | |||
270 | BOOL gAcceptCriticalMessage = FALSE; | 270 | BOOL gAcceptCriticalMessage = FALSE; |
271 | 271 | ||
272 | LLUUID gViewerDigest; // MD5 digest of the viewer's executable file. | 272 | LLUUID gViewerDigest; // MD5 digest of the viewer's executable file. |
273 | BOOL gLastExecFroze = FALSE; | 273 | eLastExecEvent gLastExecEvent = LAST_EXEC_NORMAL; |
274 | 274 | ||
275 | LLSD gDebugInfo; | 275 | LLSD gDebugInfo; |
276 | 276 | ||
@@ -334,6 +334,7 @@ BOOL gRandomizeFramerate = FALSE; | |||
334 | BOOL gPeriodicSlowFrame = FALSE; | 334 | BOOL gPeriodicSlowFrame = FALSE; |
335 | 335 | ||
336 | BOOL gQAMode = FALSE; | 336 | BOOL gQAMode = FALSE; |
337 | BOOL gLLErrorActivated = FALSE; | ||
337 | 338 | ||
338 | //////////////////////////////////////////////////////////// | 339 | //////////////////////////////////////////////////////////// |
339 | // Internal globals... that should be removed. | 340 | // Internal globals... that should be removed. |
@@ -355,6 +356,9 @@ static LLString gArgs; | |||
355 | 356 | ||
356 | static LLString gOldSettingsFileName; | 357 | static LLString gOldSettingsFileName; |
357 | static const char* LEGACY_DEFAULT_SETTINGS_FILE = "settings.ini"; | 358 | static const char* LEGACY_DEFAULT_SETTINGS_FILE = "settings.ini"; |
359 | const char* MARKER_FILE_NAME = "SecondLife.exec_marker"; | ||
360 | const char* ERROR_MARKER_FILE_NAME = "SecondLife.error_marker"; | ||
361 | const char* LLERROR_MARKER_FILE_NAME = "SecondLife.llerror_marker"; | ||
358 | static BOOL gDoDisconnect = FALSE; | 362 | static BOOL gDoDisconnect = FALSE; |
359 | static LLString gLaunchFileOnQuit; | 363 | static LLString gLaunchFileOnQuit; |
360 | 364 | ||
@@ -957,7 +961,6 @@ LLTextureFetch* LLAppViewer::sTextureFetch = NULL; | |||
957 | 961 | ||
958 | LLAppViewer::LLAppViewer() : | 962 | LLAppViewer::LLAppViewer() : |
959 | mMarkerFile(NULL), | 963 | mMarkerFile(NULL), |
960 | mLastExecFroze(false), | ||
961 | mCrashBehavior(CRASH_BEHAVIOR_ASK), | 964 | mCrashBehavior(CRASH_BEHAVIOR_ASK), |
962 | mReportedCrash(false), | 965 | mReportedCrash(false), |
963 | mNumSessions(0), | 966 | mNumSessions(0), |
@@ -1983,6 +1986,10 @@ void errorCallback(const std::string &error_string) | |||
1983 | #ifndef LL_RELEASE_FOR_DOWNLOAD | 1986 | #ifndef LL_RELEASE_FOR_DOWNLOAD |
1984 | OSMessageBox(error_string.c_str(), "Fatal Error", OSMB_OK); | 1987 | OSMessageBox(error_string.c_str(), "Fatal Error", OSMB_OK); |
1985 | #endif | 1988 | #endif |
1989 | |||
1990 | //Set the ErrorActivated global so we know to create a marker file | ||
1991 | gLLErrorActivated = true; | ||
1992 | |||
1986 | LLError::crashAndLoop(error_string); | 1993 | LLError::crashAndLoop(error_string); |
1987 | } | 1994 | } |
1988 | 1995 | ||
@@ -2163,7 +2170,7 @@ bool LLAppViewer::initConfiguration() | |||
2163 | initMarkerFile(); | 2170 | initMarkerFile(); |
2164 | 2171 | ||
2165 | #if LL_SEND_CRASH_REPORTS | 2172 | #if LL_SEND_CRASH_REPORTS |
2166 | if (gLastExecFroze) | 2173 | if (gLastExecEvent == LAST_EXEC_FROZE) |
2167 | { | 2174 | { |
2168 | llinfos << "Last execution froze, requesting to send crash report." << llendl; | 2175 | llinfos << "Last execution froze, requesting to send crash report." << llendl; |
2169 | // | 2176 | // |
@@ -2549,6 +2556,27 @@ void LLAppViewer::handleViewerCrash() | |||
2549 | gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath().c_str(); | 2556 | gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath().c_str(); |
2550 | gDebugInfo["CurrentSimHost"] = gAgent.getRegionHost().getHostName(); | 2557 | gDebugInfo["CurrentSimHost"] = gAgent.getRegionHost().getHostName(); |
2551 | 2558 | ||
2559 | //Write out the crash status file | ||
2560 | //Use marker file style setup, as that's the simplest, especially since | ||
2561 | //we're already in a crash situation | ||
2562 | if (gDirUtilp) | ||
2563 | { | ||
2564 | LLString crash_file_name; | ||
2565 | if(gLLErrorActivated) crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LLERROR_MARKER_FILE_NAME); | ||
2566 | else crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,ERROR_MARKER_FILE_NAME); | ||
2567 | llinfos << "Creating crash marker file " << crash_file_name << llendl; | ||
2568 | apr_file_t* crash_file = ll_apr_file_open(crash_file_name, LL_APR_W); | ||
2569 | if (crash_file) | ||
2570 | { | ||
2571 | llinfos << "Created crash marker file " << crash_file_name << llendl; | ||
2572 | } | ||
2573 | else | ||
2574 | { | ||
2575 | llwarns << "Cannot create error marker file " << crash_file_name << llendl; | ||
2576 | } | ||
2577 | apr_file_close(crash_file); | ||
2578 | } | ||
2579 | |||
2552 | if (gMessageSystem && gDirUtilp) | 2580 | if (gMessageSystem && gDirUtilp) |
2553 | { | 2581 | { |
2554 | std::string filename; | 2582 | std::string filename; |
@@ -2575,6 +2603,9 @@ void LLAppViewer::handleViewerCrash() | |||
2575 | pApp->closeDebug(); | 2603 | pApp->closeDebug(); |
2576 | LLError::logToFile(""); | 2604 | LLError::logToFile(""); |
2577 | 2605 | ||
2606 | // Remove the marker file, since otherwise we'll spawn a process that'll keep it locked | ||
2607 | pApp->removeMarkerFile(); | ||
2608 | |||
2578 | // Call to pure virtual, handled by platform specifc llappviewer instance. | 2609 | // Call to pure virtual, handled by platform specifc llappviewer instance. |
2579 | pApp->handleCrashReporting(); | 2610 | pApp->handleCrashReporting(); |
2580 | 2611 | ||
@@ -2592,7 +2623,7 @@ bool LLAppViewer::anotherInstanceRunning() | |||
2592 | // We create a marker file when the program starts and remove the file when it finishes. | 2623 | // We create a marker file when the program starts and remove the file when it finishes. |
2593 | // If the file is currently locked, that means another process is already running. | 2624 | // If the file is currently locked, that means another process is already running. |
2594 | 2625 | ||
2595 | std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.exec_marker"); | 2626 | std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, MARKER_FILE_NAME); |
2596 | llinfos << "Checking marker file for lock..." << llendl; | 2627 | llinfos << "Checking marker file for lock..." << llendl; |
2597 | 2628 | ||
2598 | // If file doesn't exist, we create it | 2629 | // If file doesn't exist, we create it |
@@ -2630,71 +2661,69 @@ bool LLAppViewer::anotherInstanceRunning() | |||
2630 | 2661 | ||
2631 | void LLAppViewer::initMarkerFile() | 2662 | void LLAppViewer::initMarkerFile() |
2632 | { | 2663 | { |
2633 | // *FIX:Mani - an actually cross platform LLFile lib would be nice. | ||
2634 | |||
2635 | #if LL_SOLARIS | ||
2636 | struct flock fl; | ||
2637 | fl.l_whence = SEEK_SET; | ||
2638 | fl.l_start = 0; | ||
2639 | fl.l_len = 1; | ||
2640 | #endif | ||
2641 | // We create a marker file when the program starts and remove the file when it finishes. | ||
2642 | // If the file is currently locked, that means another process is already running. | ||
2643 | // If the file exists and isn't locked, we crashed on the last run. | ||
2644 | 2664 | ||
2645 | std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.exec_marker"); | 2665 | //First, check for the existence of other files. |
2666 | //There are marker files for two different types of crashes | ||
2667 | |||
2668 | mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME); | ||
2646 | llinfos << "Checking marker file for lock..." << llendl; | 2669 | llinfos << "Checking marker file for lock..." << llendl; |
2647 | 2670 | ||
2648 | FILE* fMarker = LLFile::fopen(marker_file.c_str(), "rb"); // Flawfinder: ignore | 2671 | //We've got 4 things to test for here |
2672 | // - Other Process Running (SecondLife.exec_marker present, locked) | ||
2673 | // - Freeze (SecondLife.exec_marker present, not locked) | ||
2674 | // - LLError Crash (SecondLife.llerror_marker present) | ||
2675 | // - Other Crash (SecondLife.error_marker present) | ||
2676 | // These checks should also remove these files for the last 2 cases if they currently exist | ||
2677 | |||
2678 | //LLError/Error checks. Only one of these should ever happen at a time. | ||
2679 | LLString llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME); | ||
2680 | LLString error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME); | ||
2681 | apr_file_t* fMarker = ll_apr_file_open(llerror_marker_file, LL_APR_RB); | ||
2682 | if(fMarker != NULL) | ||
2683 | { | ||
2684 | apr_file_close(fMarker); | ||
2685 | llinfos << "Last exec LLError crashed, setting LastExecEvent to " << LAST_EXEC_LLERROR_CRASH << llendl; | ||
2686 | gLastExecEvent = LAST_EXEC_LLERROR_CRASH; | ||
2687 | } | ||
2688 | |||
2689 | fMarker = ll_apr_file_open(error_marker_file, LL_APR_RB); | ||
2690 | if(fMarker != NULL) | ||
2691 | { | ||
2692 | apr_file_close(fMarker); | ||
2693 | llinfos << "Last exec crashed, setting LastExecEvent to " << LAST_EXEC_OTHER_CRASH << llendl; | ||
2694 | gLastExecEvent = LAST_EXEC_OTHER_CRASH; | ||
2695 | } | ||
2696 | |||
2697 | ll_apr_file_remove(llerror_marker_file); | ||
2698 | ll_apr_file_remove(error_marker_file); | ||
2699 | |||
2700 | //Freeze case checks | ||
2701 | fMarker = ll_apr_file_open(mMarkerFileName, LL_APR_RB); | ||
2649 | if (fMarker != NULL) | 2702 | if (fMarker != NULL) |
2650 | { | 2703 | { |
2651 | // File exists, try opening with write permissions | 2704 | // File exists, try opening with write permissions |
2652 | fclose(fMarker); | 2705 | apr_file_close(fMarker); |
2653 | fMarker = LLFile::fopen(marker_file.c_str(), "wb"); // Flawfinder: ignxore | 2706 | fMarker = ll_apr_file_open(mMarkerFileName, LL_APR_WB); |
2654 | if (fMarker == NULL) | 2707 | if (fMarker == NULL) |
2655 | { | 2708 | { |
2656 | // Another instance is running. Skip the rest of these operations. | 2709 | // Another instance is running. Skip the rest of these operations. |
2657 | llinfos << "Marker file is locked." << llendl; | 2710 | llinfos << "Marker file is locked." << llendl; |
2658 | return; | 2711 | return; |
2659 | } | 2712 | } |
2660 | #if LL_DARWIN || LL_LINUX || LL_SOLARIS | 2713 | if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) //flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1) |
2661 | // Try to lock it. On Mac, this is the only way to test if it's actually locked. | ||
2662 | if (flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1) | ||
2663 | { | 2714 | { |
2664 | // Lock failed - somebody else has it. | 2715 | apr_file_close(fMarker); |
2665 | fclose(fMarker); | ||
2666 | llinfos << "Marker file is locked." << llendl; | 2716 | llinfos << "Marker file is locked." << llendl; |
2667 | return; | 2717 | return; |
2668 | } | 2718 | } |
2669 | #endif | ||
2670 | |||
2671 | // No other instances; we'll lock this file now & delete on quit. | 2719 | // No other instances; we'll lock this file now & delete on quit. |
2672 | fclose(fMarker); | 2720 | apr_file_close(fMarker); |
2673 | gLastExecFroze = TRUE; | 2721 | gLastExecEvent = LAST_EXEC_FROZE; |
2674 | llinfos << "Exec marker found: program froze on previous execution" << llendl; | 2722 | llinfos << "Exec marker found: program froze on previous execution" << llendl; |
2675 | } | 2723 | } |
2676 | 2724 | ||
2677 | // Create the marker file for this execution & lock it | 2725 | // Create the marker file for this execution & lock it |
2678 | // FILE *fp_executing_marker; | 2726 | mMarkerFile = ll_apr_file_open(mMarkerFileName, LL_APR_W); |
2679 | #if LL_WINDOWS | ||
2680 | mMarkerFile = LLFile::_fsopen(marker_file.c_str(), "w", _SH_DENYWR); | ||
2681 | #else | ||
2682 | mMarkerFile = LLFile::fopen(marker_file.c_str(), "w"); // Flawfinder: ignore | ||
2683 | if (mMarkerFile) | ||
2684 | { | ||
2685 | int fd = fileno(mMarkerFile); | ||
2686 | // Attempt to lock | ||
2687 | #if LL_SOLARIS | ||
2688 | fl.l_type = F_WRLCK; | ||
2689 | if (fcntl(fd, F_SETLK, &fl) == -1) | ||
2690 | #else | ||
2691 | if (flock(fd, LOCK_EX | LOCK_NB) == -1) | ||
2692 | #endif | ||
2693 | { | ||
2694 | llinfos << "Failed to lock file." << llendl; | ||
2695 | } | ||
2696 | } | ||
2697 | #endif | ||
2698 | if (mMarkerFile) | 2727 | if (mMarkerFile) |
2699 | { | 2728 | { |
2700 | llinfos << "Marker file created." << llendl; | 2729 | llinfos << "Marker file created." << llendl; |
@@ -2703,20 +2732,14 @@ void LLAppViewer::initMarkerFile() | |||
2703 | { | 2732 | { |
2704 | llinfos << "Failed to create marker file." << llendl; | 2733 | llinfos << "Failed to create marker file." << llendl; |
2705 | } | 2734 | } |
2735 | if (apr_file_lock(mMarkerFile, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) | ||
2736 | { | ||
2737 | apr_file_close(mMarkerFile); | ||
2738 | llinfos << "Marker file cannot be locked." << llendl; | ||
2739 | return; | ||
2740 | } | ||
2706 | 2741 | ||
2707 | #if LL_WINDOWS | 2742 | llinfos << "Marker file locked." << llendl; |
2708 | // Clean up SecondLife.dmp files, to avoid confusion | ||
2709 | llinfos << "Removing SecondLife.dmp" << llendl; | ||
2710 | std::string dmp_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.dmp"); | ||
2711 | LLFile::remove(dmp_filename.c_str()); | ||
2712 | #endif | ||
2713 | |||
2714 | // This is to keep the crash reporter from constantly sending stale message logs | ||
2715 | // We wipe the message file now. | ||
2716 | llinfos << "Removing message.log" << llendl; | ||
2717 | std::string message_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "message.log"); | ||
2718 | LLFile::remove(message_filename.c_str()); | ||
2719 | |||
2720 | llinfos << "Exiting initMarkerFile()." << llendl; | 2743 | llinfos << "Exiting initMarkerFile()." << llendl; |
2721 | } | 2744 | } |
2722 | 2745 | ||
@@ -2725,14 +2748,9 @@ void LLAppViewer::removeMarkerFile() | |||
2725 | llinfos << "removeMarkerFile()" << llendl; | 2748 | llinfos << "removeMarkerFile()" << llendl; |
2726 | if (mMarkerFile != NULL) | 2749 | if (mMarkerFile != NULL) |
2727 | { | 2750 | { |
2728 | fclose(mMarkerFile); | 2751 | ll_apr_file_remove( mMarkerFileName ); |
2729 | mMarkerFile = NULL; | 2752 | mMarkerFile = NULL; |
2730 | } | 2753 | } |
2731 | if( gDirUtilp ) | ||
2732 | { | ||
2733 | LLString marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.exec_marker"); | ||
2734 | ll_apr_file_remove( marker_file ); | ||
2735 | } | ||
2736 | } | 2754 | } |
2737 | 2755 | ||
2738 | void LLAppViewer::forceQuit() | 2756 | void LLAppViewer::forceQuit() |