aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llappviewer.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:29 -0500
committerJacek Antonelli2008-08-15 23:45:29 -0500
commit7bdb4845afdd157f95281293803567090e3f992a (patch)
treefbcada1c227d7407f9f37ccba360bfe6326d9c5e /linden/indra/newview/llappviewer.cpp
parentSecond Life viewer sources 1.19.0.0 (diff)
downloadmeta-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.cpp152
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;
270BOOL gAcceptCriticalMessage = FALSE; 270BOOL gAcceptCriticalMessage = FALSE;
271 271
272LLUUID gViewerDigest; // MD5 digest of the viewer's executable file. 272LLUUID gViewerDigest; // MD5 digest of the viewer's executable file.
273BOOL gLastExecFroze = FALSE; 273eLastExecEvent gLastExecEvent = LAST_EXEC_NORMAL;
274 274
275LLSD gDebugInfo; 275LLSD gDebugInfo;
276 276
@@ -334,6 +334,7 @@ BOOL gRandomizeFramerate = FALSE;
334BOOL gPeriodicSlowFrame = FALSE; 334BOOL gPeriodicSlowFrame = FALSE;
335 335
336BOOL gQAMode = FALSE; 336BOOL gQAMode = FALSE;
337BOOL 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
356static LLString gOldSettingsFileName; 357static LLString gOldSettingsFileName;
357static const char* LEGACY_DEFAULT_SETTINGS_FILE = "settings.ini"; 358static const char* LEGACY_DEFAULT_SETTINGS_FILE = "settings.ini";
359const char* MARKER_FILE_NAME = "SecondLife.exec_marker";
360const char* ERROR_MARKER_FILE_NAME = "SecondLife.error_marker";
361const char* LLERROR_MARKER_FILE_NAME = "SecondLife.llerror_marker";
358static BOOL gDoDisconnect = FALSE; 362static BOOL gDoDisconnect = FALSE;
359static LLString gLaunchFileOnQuit; 363static LLString gLaunchFileOnQuit;
360 364
@@ -957,7 +961,6 @@ LLTextureFetch* LLAppViewer::sTextureFetch = NULL;
957 961
958LLAppViewer::LLAppViewer() : 962LLAppViewer::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
2631void LLAppViewer::initMarkerFile() 2662void 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
2738void LLAppViewer::forceQuit() 2756void LLAppViewer::forceQuit()