From 0488142b93b6a5cc804a98e28e5dedc28cd4ea54 Mon Sep 17 00:00:00 2001
From: Boroondas Gupte <hg@boroon.dasgupta.ch>
Date: Tue, 21 Jun 2011 00:09:17 +0200
Subject: OPEN-99: use -march=pentium3 for 32-bit builds only

---
 indra/cmake/00-Common.cmake | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 2cc8fa5e5f..d9e1dd9afb 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -169,7 +169,10 @@ if (LINUX)
     add_definitions(-fvisibility=hidden)
     # don't catch SIGCHLD in our base application class for the viewer - some of our 3rd party libs may need their *own* SIGCHLD handler to work.  Sigh!  The viewer doesn't need to catch SIGCHLD anyway.
     add_definitions(-DLL_IGNORE_SIGCHLD)
-    add_definitions(-march=pentium3 -mfpmath=sse -ftree-vectorize)
+    if (WORD_SIZE EQUAL 32)
+      add_definitions(-march=pentium3)
+    endif (WORD_SIZE EQUAL 32)
+    add_definitions(-mfpmath=sse -ftree-vectorize)
     if (NOT STANDALONE)
       # this stops us requiring a really recent glibc at runtime
       add_definitions(-fno-stack-protector)
-- 
cgit v1.2.3


From 0ec4d813ebfd80f82bb2b84e993f7a192e3fddb5 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 23 Jun 2011 14:50:28 -0400
Subject: Log enriched memory info for Mac too. Add Mac logic to
 LLMemoryInfo::stream(): run vm_stat and log its output. Add comments with Mac
 and Linux suggestions to LLMemoryInfo::getAvailableMemoryKB(), responding to
 comment: //do not know how to collect available memory info for other
 systems.

---
 indra/llcommon/llsys.cpp | 106 +++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 99 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index e8616a9be6..4190c91fd8 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -1,6 +1,6 @@
 /** 
  * @file llsys.cpp
- * @brief Impelementation of the basic system query functions.
+ * @brief Implementation of the basic system query functions.
  *
  * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -697,6 +697,76 @@ void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_v
 	avail_physical_mem_kb = (U32)(state.ullAvailPhys/1024) ;
 	avail_virtual_mem_kb = (U32)(state.ullAvailVirtual/1024) ;
 
+#elif LL_DARWIN
+	// Run vm_stat and filter output, scaling for page size:
+	// $ vm_stat
+	// Mach Virtual Memory Statistics: (page size of 4096 bytes)
+	// Pages free:                   462078.
+	// Pages active:                 142010.
+	// Pages inactive:               220007.
+	// Pages wired down:             159552.
+	// "Translation faults":      220825184.
+	// Pages copy-on-write:         2104153.
+	// Pages zero filled:         167034876.
+	// Pages reactivated:             65153.
+	// Pageins:                     2097212.
+	// Pageouts:                      41759.
+	// Object cache: 841598 hits of 7629869 lookups (11% hit rate)
+	avail_physical_mem_kb = -1 ;
+	avail_virtual_mem_kb = -1 ;
+
+#elif LL_LINUX
+	// Read selected lines from MEMINFO_FILE:
+	// $ cat /proc/meminfo
+	// MemTotal:        4108424 kB
+	// MemFree:         1244064 kB
+	// Buffers:           85164 kB
+	// Cached:          1990264 kB
+	// SwapCached:            0 kB
+	// Active:          1176648 kB
+	// Inactive:        1427532 kB
+	// Active(anon):     529152 kB
+	// Inactive(anon):    15924 kB
+	// Active(file):     647496 kB
+	// Inactive(file):  1411608 kB
+	// Unevictable:          16 kB
+	// Mlocked:              16 kB
+	// HighTotal:       3266316 kB
+	// HighFree:         721308 kB
+	// LowTotal:         842108 kB
+	// LowFree:          522756 kB
+	// SwapTotal:       6384632 kB
+	// SwapFree:        6384632 kB
+	// Dirty:                28 kB
+	// Writeback:             0 kB
+	// AnonPages:        528820 kB
+	// Mapped:            89472 kB
+	// Shmem:             16324 kB
+	// Slab:             159624 kB
+	// SReclaimable:     145168 kB
+	// SUnreclaim:        14456 kB
+	// KernelStack:        2560 kB
+	// PageTables:         5560 kB
+	// NFS_Unstable:          0 kB
+	// Bounce:                0 kB
+	// WritebackTmp:          0 kB
+	// CommitLimit:     8438844 kB
+	// Committed_AS:    1271596 kB
+	// VmallocTotal:     122880 kB
+	// VmallocUsed:       65252 kB
+	// VmallocChunk:      52356 kB
+	// HardwareCorrupted:     0 kB
+	// HugePages_Total:       0
+	// HugePages_Free:        0
+	// HugePages_Rsvd:        0
+	// HugePages_Surp:        0
+	// Hugepagesize:       2048 kB
+	// DirectMap4k:      434168 kB
+	// DirectMap2M:      477184 kB
+	// (could also run 'free', but easier to read a file than run a program)
+	avail_physical_mem_kb = -1 ;
+	avail_virtual_mem_kb = -1 ;
+
 #else
 	//do not know how to collect available memory info for other systems.
 	//leave it blank here for now.
@@ -720,6 +790,7 @@ void LLMemoryInfo::stream(std::ostream& s) const
 	s << "Avail page KB:      " << (U32)(state.ullAvailPageFile/1024) << std::endl;
 	s << "Total Virtual KB:   " << (U32)(state.ullTotalVirtual/1024) << std::endl;
 	s << "Avail Virtual KB:   " << (U32)(state.ullAvailVirtual/1024) << std::endl;
+
 #elif LL_DARWIN
 	uint64_t phys = 0;
 
@@ -731,22 +802,39 @@ void LLMemoryInfo::stream(std::ostream& s) const
 	}
 	else
 	{
-		s << "Unable to collect memory information";
+		s << "Unable to collect hw.memsize memory information" << std::endl;
+	}
+
+	FILE* pout = popen("vm_stat 2>&1", "r");
+	if (! pout)
+	{
+		s << "Unable to collect vm_stat memory information" << std::endl;
 	}
+	else
+	{
+		// Here 'pout' is vm_stat's stdout. Copy it to output stream.
+		char line[100];
+		while (fgets(line, sizeof(line), pout))
+		{
+			s << line;
+		}
+		fclose(pout);
+	}
+
 #elif LL_SOLARIS
         U64 phys = 0;
 
         phys = (U64)(sysconf(_SC_PHYS_PAGES)) * (U64)(sysconf(_SC_PAGESIZE)/1024);
 
         s << "Total Physical KB:  " << phys << std::endl;
-#else
-	// *NOTE: This works on linux. What will it do on other systems?
+
+#elif LL_LINUX
 	LLFILE* meminfo = LLFile::fopen(MEMINFO_FILE,"rb");
 	if(meminfo)
 	{
 		char line[MAX_STRING];		/* Flawfinder: ignore */
-		memset(line, 0, MAX_STRING);
-		while(fgets(line, MAX_STRING, meminfo))
+		memset(line, 0, sizeof(line));
+		while(fgets(line, sizeof(line), meminfo))
 		{
 			line[strlen(line)-1] = ' ';		 /*Flawfinder: ignore*/
 			s << line;
@@ -755,8 +843,12 @@ void LLMemoryInfo::stream(std::ostream& s) const
 	}
 	else
 	{
-		s << "Unable to collect memory information";
+		s << "Unable to collect memory information" << std::endl;
 	}
+
+#else
+	s << "Unknown system; unable to collect memory information" << std::endl;
+
 #endif
 }
 
-- 
cgit v1.2.3


From 2619f3db1f781489b9efab0c5ed26c526b013158 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 24 Jun 2011 10:46:38 -0400
Subject: CHOP-753: add timestamp and <mem> marker to memory stats log lines

---
 indra/llcommon/llsys.cpp | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 4190c91fd8..015a24cf23 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -36,6 +36,7 @@
 #endif
 
 #include "llprocessor.h"
+#include "llerrorcontrol.h"
 
 #if LL_WINDOWS
 #	define WIN32_LEAN_AND_MEAN
@@ -778,18 +779,24 @@ void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_v
 
 void LLMemoryInfo::stream(std::ostream& s) const
 {
+	// We want these memory stats to be easy to grep from the log, along with
+	// the timestamp. So preface each line with the timestamp and a
+	// distinctive marker. Without that, we'd have to search the log for the
+	// introducer line, then read subsequent lines, etc...
+	std::string pfx(LLError::utcTime() + " <mem> ");
+
 #if LL_WINDOWS
 	MEMORYSTATUSEX state;
 	state.dwLength = sizeof(state);
 	GlobalMemoryStatusEx(&state);
 
-	s << "Percent Memory use: " << (U32)state.dwMemoryLoad << '%' << std::endl;
-	s << "Total Physical KB:  " << (U32)(state.ullTotalPhys/1024) << std::endl;
-	s << "Avail Physical KB:  " << (U32)(state.ullAvailPhys/1024) << std::endl;
-	s << "Total page KB:      " << (U32)(state.ullTotalPageFile/1024) << std::endl;
-	s << "Avail page KB:      " << (U32)(state.ullAvailPageFile/1024) << std::endl;
-	s << "Total Virtual KB:   " << (U32)(state.ullTotalVirtual/1024) << std::endl;
-	s << "Avail Virtual KB:   " << (U32)(state.ullAvailVirtual/1024) << std::endl;
+	s << pfx << "Percent Memory use: " << (U32)state.dwMemoryLoad << '%' << std::endl;
+	s << pfx << "Total Physical KB:  " << (U32)(state.ullTotalPhys/1024) << std::endl;
+	s << pfx << "Avail Physical KB:  " << (U32)(state.ullAvailPhys/1024) << std::endl;
+	s << pfx << "Total page KB:      " << (U32)(state.ullTotalPageFile/1024) << std::endl;
+	s << pfx << "Avail page KB:      " << (U32)(state.ullAvailPageFile/1024) << std::endl;
+	s << pfx << "Total Virtual KB:   " << (U32)(state.ullTotalVirtual/1024) << std::endl;
+	s << pfx << "Avail Virtual KB:   " << (U32)(state.ullAvailVirtual/1024) << std::endl;
 
 #elif LL_DARWIN
 	uint64_t phys = 0;
@@ -798,7 +805,7 @@ void LLMemoryInfo::stream(std::ostream& s) const
 	
 	if(sysctlbyname("hw.memsize", &phys, &len, NULL, 0) == 0)
 	{
-		s << "Total Physical KB:  " << phys/1024 << std::endl;
+		s << pfx << "Total Physical KB:  " << phys/1024 << std::endl;
 	}
 	else
 	{
@@ -816,7 +823,7 @@ void LLMemoryInfo::stream(std::ostream& s) const
 		char line[100];
 		while (fgets(line, sizeof(line), pout))
 		{
-			s << line;
+			s << pfx << line;
 		}
 		fclose(pout);
 	}
@@ -826,7 +833,7 @@ void LLMemoryInfo::stream(std::ostream& s) const
 
         phys = (U64)(sysconf(_SC_PHYS_PAGES)) * (U64)(sysconf(_SC_PAGESIZE)/1024);
 
-        s << "Total Physical KB:  " << phys << std::endl;
+        s << pfx << "Total Physical KB:  " << phys << std::endl;
 
 #elif LL_LINUX
 	LLFILE* meminfo = LLFile::fopen(MEMINFO_FILE,"rb");
@@ -837,7 +844,7 @@ void LLMemoryInfo::stream(std::ostream& s) const
 		while(fgets(line, sizeof(line), meminfo))
 		{
 			line[strlen(line)-1] = ' ';		 /*Flawfinder: ignore*/
-			s << line;
+			s << pfx << line;
 		}
 		fclose(meminfo);
 	}
-- 
cgit v1.2.3


From abb8a7018d0fc7a52aa35f4be1cec372719e4eda Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 28 Jun 2011 08:21:49 -0400
Subject: CHOP-753: Log LLMemoryInfo whenever framerate hits a new low.
 Introduce FrameWatcher, a static object that hooks into the LLEventPump named
 "mainloop" to get a call every frame. Track framerate over a defined sample
 time (20 seconds atm); track minimum and log LLMemoryInfo every time we hit a
 new minimum.

---
 indra/llcommon/llsys.cpp | 106 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 015a24cf23..92fdf4f327 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -37,6 +37,9 @@
 
 #include "llprocessor.h"
 #include "llerrorcontrol.h"
+#include "llevents.h"
+#include "lltimer.h"
+#include <boost/bind.hpp>
 
 #if LL_WINDOWS
 #	define WIN32_LEAN_AND_MEAN
@@ -71,6 +74,10 @@ extern int errno;
 static const S32 CPUINFO_BUFFER_SIZE = 16383;
 LLCPUInfo gSysCPU;
 
+// Don't log memory info any more often than this. It also serves as our
+// framerate sample size.
+static const F32 MEM_INFO_THROTTLE = 20;
+
 #if LL_WINDOWS
 #ifndef DLLVERSIONINFO
 typedef struct _DllVersionInfo
@@ -877,6 +884,105 @@ std::ostream& operator<<(std::ostream& s, const LLMemoryInfo& info)
 	return s;
 }
 
+class FrameWatcher
+{
+public:
+    FrameWatcher():
+        // Hooking onto the "mainloop" event pump gets us one call per frame.
+        mConnection(LLEventPumps::instance()
+                    .obtain("mainloop")
+                    .listen("FrameWatcher", boost::bind(&FrameWatcher::tick, this, _1))),
+        // Initializing mSampleStart to an invalid timestamp alerts us to skip
+        // trying to compute framerate on the first call.
+        mSampleStart(-1),
+        // Initializing mSampleEnd to 0 ensures that we treat the first call
+        // as the completion of a sample window.
+        mSampleEnd(0),
+        mFrames(0),
+        // Initializing to F32_MAX means that the first real frame will become
+        // the slowest ever, which sounds like a good idea.
+        mSlowest(F32_MAX),
+        mDesc("startup")
+    {}
+
+    bool tick(const LLSD&)
+    {
+        F32 timestamp(mTimer.getElapsedTimeF32());
+
+        // Count this frame in the interval just completed.
+        ++mFrames;
+
+        // Have we finished a sample window yet?
+        if (timestamp < mSampleEnd)
+        {
+            // no, just keep waiting
+            return false;
+        }
+
+        // Set up for next sample window. Capture values for previous frame in
+        // local variables and reset data members.
+        U32 frames(mFrames);
+        F32 sampleStart(mSampleStart);
+        // No frames yet in next window
+        mFrames = 0;
+        // which starts right now
+        mSampleStart = timestamp;
+        // and ends MEM_INFO_THROTTLE seconds in the future
+        mSampleEnd = mSampleStart + MEM_INFO_THROTTLE;
+
+        // On the very first call, that's all we can do, no framerate
+        // computation is possible.
+        if (sampleStart < 0)
+        {
+            return false;
+        }
+
+        // How long did this actually take? As framerate slows, the duration
+        // of the frame we just finished could push us WELL beyond our desired
+        // sample window size.
+        F32 elapsed(timestamp - sampleStart);
+        F32 framerate(frames/elapsed);
+
+        // We're especially interested in memory as framerate drops. Only log
+        // when framerate is lower than ever before. (Should always be true
+        // for the end of the very first sample window.)
+        if (framerate >= mSlowest)
+        {
+            return false;
+        }
+        // Congratulations, we've hit a new low.  :-P
+        mSlowest = framerate;
+
+        LL_INFOS("FrameWatcher") << mDesc << " framerate "
+                                 << std::fixed << std::setprecision(1) << framerate << '\n'
+                                 << LLMemoryInfo() << LL_ENDL;
+        mDesc = "new lowest";
+
+        return false;
+    }
+
+private:
+    // Storing the connection in an LLTempBoundListener ensures it will be
+    // disconnected when we're destroyed.
+    LLTempBoundListener mConnection;
+    // Track elapsed time
+    LLTimer mTimer;
+    // Some of what you see here is in fact redundant with functionality you
+    // can get from LLTimer. Unfortunately the LLTimer API is missing the
+    // feature we need: has at least the stated interval elapsed, and if so,
+    // exactly how long has passed? So we have to do it by hand, sigh.
+    // Time at start, end of sample window
+    F32 mSampleStart, mSampleEnd;
+    // Frames this sample window
+    U32 mFrames;
+    // Slowest framerate EVAR
+    F32 mSlowest;
+    // Description of next notable framerate
+    std::string mDesc;
+};
+
+static FrameWatcher sFrameWatcher;
+
 BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile)
 {
 	std::string tmpfile;
-- 
cgit v1.2.3


From 57c230b73ea171d310ad3c132624a8fdd6751b0e Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 28 Jun 2011 08:58:10 -0400
Subject: CHOP-753: suppress VS fatal warning 4355

---
 indra/llcommon/llsys.cpp | 4 ++++
 1 file changed, 4 insertions(+)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 92fdf4f327..156c78b1e8 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -24,6 +24,10 @@
  * $/LicenseInfo$
  */
 
+#if LL_WINDOWS
+#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
+#endif
+
 #include "linden_common.h"
 
 #include "llsys.h"
-- 
cgit v1.2.3


From 26be53aede499182252bb797e798611169ea0553 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 28 Jun 2011 16:01:16 -0400
Subject: CHOP-753: Introduce a sliding window of framerate samples. The
 trouble with remembering the slowest-ever framerate is that framerate drops
 dramatically on login, then typically bounces back to something reasonable
 during the session. So the session-normal framerate has to drop pretty
 dramatically before it falls below the original login framerate. To address
 this, only remember the last ~10 minutes of framerates, and log memory stats
 every time a new framerate is slower than the previous 10 minutes.

---
 indra/llcommon/llsys.cpp | 70 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 57 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 156c78b1e8..ccd6f261b7 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -44,6 +44,7 @@
 #include "llevents.h"
 #include "lltimer.h"
 #include <boost/bind.hpp>
+#include <boost/circular_buffer.hpp>
 
 #if LL_WINDOWS
 #	define WIN32_LEAN_AND_MEAN
@@ -81,6 +82,11 @@ LLCPUInfo gSysCPU;
 // Don't log memory info any more often than this. It also serves as our
 // framerate sample size.
 static const F32 MEM_INFO_THROTTLE = 20;
+// Sliding window of samples. We intentionally limit the length of time we
+// remember "the slowest" framerate because framerate is very slow at login.
+// If we only triggered FrameWatcher logging when the session framerate
+// dropped below the login framerate, we'd have very little additional data.
+static const F32 MEM_INFO_WINDOW = 10*60;
 
 #if LL_WINDOWS
 #ifndef DLLVERSIONINFO
@@ -903,10 +909,13 @@ public:
         // as the completion of a sample window.
         mSampleEnd(0),
         mFrames(0),
+        // Both MEM_INFO_WINDOW and MEM_INFO_THROTTLE are in seconds. We need
+        // the number of integer MEM_INFO_THROTTLE sample slots that will fit
+        // in MEM_INFO_WINDOW. Round up.
+        mSamples(int((MEM_INFO_WINDOW / MEM_INFO_THROTTLE) + 0.7)),
         // Initializing to F32_MAX means that the first real frame will become
         // the slowest ever, which sounds like a good idea.
-        mSlowest(F32_MAX),
-        mDesc("startup")
+        mSlowest(F32_MAX)
     {}
 
     bool tick(const LLSD&)
@@ -947,20 +956,54 @@ public:
         F32 elapsed(timestamp - sampleStart);
         F32 framerate(frames/elapsed);
 
+        // Remember previous slowest framerate because we're just about to
+        // update it.
+        F32 slowest(mSlowest);
+        // Remember previous number of samples.
+        boost::circular_buffer<F32>::size_type prevSize(mSamples.size());
+
+        // Capture new framerate in our samples buffer. Once the buffer is
+        // full (after MEM_INFO_WINDOW seconds), this will displace the oldest
+        // sample. ("So they all rolled over, and one fell out...")
+        mSamples.push_back(framerate);
+
+        // Calculate the new minimum framerate. I know of no way to update a
+        // rolling minimum without ever rescanning the buffer. But since there
+        // are only a few tens of items in this buffer, rescanning it is
+        // probably cheaper (and certainly easier to reason about) than
+        // attempting to optimize away some of the scans.
+        mSlowest = framerate;       // pick an arbitrary entry to start
+        for (boost::circular_buffer<F32>::const_iterator si(mSamples.begin()), send(mSamples.end());
+             si != send; ++si)
+        {
+            if (*si < mSlowest)
+            {
+                mSlowest = *si;
+            }
+        }
+
         // We're especially interested in memory as framerate drops. Only log
-        // when framerate is lower than ever before. (Should always be true
-        // for the end of the very first sample window.)
-        if (framerate >= mSlowest)
+        // when framerate drops below the slowest framerate we remember.
+        // (Should always be true for the end of the very first sample
+        // window.)
+        if (framerate >= slowest)
         {
             return false;
         }
         // Congratulations, we've hit a new low.  :-P
-        mSlowest = framerate;
 
-        LL_INFOS("FrameWatcher") << mDesc << " framerate "
-                                 << std::fixed << std::setprecision(1) << framerate << '\n'
-                                 << LLMemoryInfo() << LL_ENDL;
-        mDesc = "new lowest";
+        LL_INFOS("FrameWatcher") << ' ';
+        if (! prevSize)
+        {
+            LL_CONT << "initial framerate ";
+        }
+        else
+        {
+            LL_CONT << "slowest framerate for last " << int(prevSize * MEM_INFO_THROTTLE)
+                    << " seconds ";
+        }
+        LL_CONT << std::fixed << std::setprecision(1) << framerate << '\n'
+                << LLMemoryInfo() << LL_ENDL;
 
         return false;
     }
@@ -979,12 +1022,13 @@ private:
     F32 mSampleStart, mSampleEnd;
     // Frames this sample window
     U32 mFrames;
-    // Slowest framerate EVAR
+    // Sliding window of framerate samples
+    boost::circular_buffer<F32> mSamples;
+    // Slowest framerate in mSamples
     F32 mSlowest;
-    // Description of next notable framerate
-    std::string mDesc;
 };
 
+// Need an instance of FrameWatcher before it does any good
 static FrameWatcher sFrameWatcher;
 
 BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile)
-- 
cgit v1.2.3


From 1262f710b548100e4522866341febba3d7cf535d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 28 Jun 2011 23:09:00 -0400
Subject: CHOP-753: Report Linux memory stats 1/line, like other platforms.
 Previous code deliberately flowed the different lines from MEMINFO_FILE
 together on a single line, which seems pointless to me, since we want to be
 able to grep the viewer log to recognize individual stats. Also replace
 classic-C LLFILE* machinery used to read MEMINFO_FILE with std::ifstream and
 std::getline().

---
 indra/llcommon/llsys.cpp | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index ccd6f261b7..f0f98f5bf6 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -853,17 +853,14 @@ void LLMemoryInfo::stream(std::ostream& s) const
         s << pfx << "Total Physical KB:  " << phys << std::endl;
 
 #elif LL_LINUX
-	LLFILE* meminfo = LLFile::fopen(MEMINFO_FILE,"rb");
-	if(meminfo)
+	std::ifstream meminfo(MEMINFO_FILE);
+	if (meminfo.is_open())
 	{
-		char line[MAX_STRING];		/* Flawfinder: ignore */
-		memset(line, 0, sizeof(line));
-		while(fgets(line, sizeof(line), meminfo))
+		std::string line;
+		while (std::getline(meminfo, line))
 		{
-			line[strlen(line)-1] = ' ';		 /*Flawfinder: ignore*/
-			s << pfx << line;
+			s << pfx << line << '\n';
 		}
-		fclose(meminfo);
 	}
 	else
 	{
-- 
cgit v1.2.3


From 7f8ec9f142f34057fc10436f94ce420183cf75b8 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 29 Jun 2011 20:35:44 -0400
Subject: CHOP-753: Introduce LLSD access to LLMemoryInfo ** BROKEN ** This is
 known not to compile on Mac yet; checking in to concurrently work on
 Linux-specific code.

---
 indra/llcommon/llsys.cpp | 211 +++++++++++++++++++++++++++++++++++++++++++++++
 indra/llcommon/llsys.h   |  28 +++++++
 2 files changed, 239 insertions(+)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index f0f98f5bf6..40914dca3f 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -43,8 +43,15 @@
 #include "llerrorcontrol.h"
 #include "llevents.h"
 #include "lltimer.h"
+#include "llsdserialize.h"
+#include "llsdutil.h"
 #include <boost/bind.hpp>
 #include <boost/circular_buffer.hpp>
+#include <boost/regex.hpp>
+#include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
+
+using namespace llsd;
 
 #if LL_WINDOWS
 #	define WIN32_LEAN_AND_MEAN
@@ -633,6 +640,7 @@ void LLCPUInfo::stream(std::ostream& s) const
 
 LLMemoryInfo::LLMemoryInfo()
 {
+	refresh();
 }
 
 #if LL_WINDOWS
@@ -873,6 +881,209 @@ void LLMemoryInfo::stream(std::ostream& s) const
 #endif
 }
 
+LLSD LLMemoryInfo::getStatsMap() const
+{
+    LLSD map;
+
+    BOOST_FOREACH(LLSD pair, inArray(mData))
+    {
+        // Have to be clear that we want the key asString() to specify map
+        // indexing rather than array subscripting.
+        map[pair[0].asString()] = pair[1];
+    }
+
+    return map;
+}
+
+LLSD LLMemoryInfo::getStatsArray() const
+{
+    return mData;
+}
+
+LLMemoryInfo& LLMemoryInfo::refresh()
+{
+    // This implementation is derived from stream() code (as of 2011-06-29).
+    // Hopefully we'll reimplement stream() to use mData before long...
+    mData = LLSD::emptyArray();
+
+#if LL_WINDOWS
+	MEMORYSTATUSEX state;
+	state.dwLength = sizeof(state);
+	GlobalMemoryStatusEx(&state);
+
+	mData.append(LLSDArray("Percent Memory use")(LLSD::Integer(state.dwMemoryLoad)));
+	mData.append(LLSDArray("Total Physical KB") (LLSD::Integer(state.ullTotalPhys/1024)));
+	mData.append(LLSDArray("Avail Physical KB") (LLSD::Integer(state.ullAvailPhys/1024)));
+	mData.append(LLSDArray("Total page KB")     (LLSD::Integer(state.ullTotalPageFile/1024)));
+	mData.append(LLSDArray("Avail page KB")     (LLSD::Integer(state.ullAvailPageFile/1024)));
+	mData.append(LLSDArray("Total Virtual KB")  (LLSD::Integer(state.ullTotalVirtual/1024)));
+	mData.append(LLSDArray("Avail Virtual KB")  (LLSD::Integer(state.ullAvailVirtual/1024)));
+
+#elif LL_DARWIN
+	uint64_t phys = 0;
+
+	size_t len = sizeof(phys);	
+	
+	if (sysctlbyname("hw.memsize", &phys, &len, NULL, 0) == 0)
+	{
+		mData.append(LLSDArray("Total Physical KB")(LLSD::Integer(phys/1024)));
+	}
+	else
+	{
+		LL_WARNS("LLMemoryInfo") << "Unable to collect hw.memsize memory information" << LL_ENDL;
+	}
+
+	FILE* pout = popen("vm_stat 2>&1", "r");
+	if (! pout)
+	{
+		LL_WARNS("LLMemoryInfo") << "Unable to collect vm_stat memory information" << LL_ENDL;
+	}
+	else
+	{
+		// Mach Virtual Memory Statistics: (page size of 4096 bytes)
+		// Pages free:					 462078.
+		// Pages active:				 142010.
+		// Pages inactive:				 220007.
+		// Pages wired down:			 159552.
+		// "Translation faults":	  220825184.
+		// Pages copy-on-write:			2104153.
+		// Pages zero filled:		  167034876.
+		// Pages reactivated:			  65153.
+		// Pageins:						2097212.
+		// Pageouts:					  41759.
+		// Object cache: 841598 hits of 7629869 lookups (11% hit rate)
+
+		boost::regex pagesize_rx("\\(page size of ([0-9]+) bytes\\)");
+		boost::regex stat_rx("(.+): +([0-9]+)\\.");
+		boost::regex pages_rx("Pages ");
+		boost::cmatch matched;
+		LLSD::Integer pagesizekb(4096/1024);
+
+		// Here 'pout' is vm_stat's stdout. Search it for relevant data.
+		char line[100];
+		line[sizeof(line)-1] = '\0';
+		while (fgets(line, sizeof(line)-1, pout))
+		{
+			size_t linelen(strlen(line));
+			// Truncate any trailing newline
+			if (line[linelen - 1] == '\n')
+			{
+				line[--linelen] = '\0';
+			}
+			if (boost::regex_search(&line[0], line+linelen, matched, pagesize_rx))
+			{
+				// "Mach Virtual Memory Statistics: (page size of 4096 bytes)"
+				std::string pagesize_str(matched[1].first, matched[1].second);
+				// Reasonable to assume that pagesize will always be a
+				// multiple of 1Kb?
+				pagesizekb = boost::lexical_cast<LLSD::Integer>(pagesize_str)/1024;
+			}
+			else if (boost::regex_match(&line[0], line+linelen, matched, stat_rx))
+			{
+				// e.g. "Pages free:					 462078."
+				// Strip double-quotes off certain statistic names
+				if (matched[1].first[0] == '"' && matched[1].second[-1] == '"')
+				{
+					++matched[1].first;
+					--matched[1].second;
+				}
+				LLSD::String key(matched[1].first, matched[1].second);
+				LLSD::String value_str(matched[2].first, matched[2].second);
+				LLSD::Integer value(boost::lexical_cast<LLSD::Integer>(value_str));
+				// Store this statistic.
+				mData.append(LLSDArray(key)(value));
+				// Is this in units of pages? If so, convert to Kb.
+				// boost::regex_match() doc sez: "If you want to match a
+				// prefix of the character string then use regex_search with
+				// the flag match_continuous set."
+				boost::smatch smatched;
+				if (boost::regex_search(key, smatched, pages_rx, boost::match_continuous))
+				{
+					// Synthesize a new key with kB in place of Pages
+					LLSD::String kbkey("kB ");
+					kbkey.append(smatched[0].second, key.end());
+					mData.append(LLSDArray(kbkey)(value * pagesizekb));
+				}
+			}
+			else
+			{
+				LL_WARNS("LLMemoryInfo") << "unrecognized vm_stat line: " << line << LL_ENDL;
+			}
+		}
+		fclose(pout);
+	}
+
+#elif LL_SOLARIS
+	U64 phys = 0;
+
+	phys = (U64)(sysconf(_SC_PHYS_PAGES)) * (U64)(sysconf(_SC_PAGESIZE)/1024);
+
+	mData.append(LLSDArray("Total Physical KB")(phys));
+
+#elif LL_LINUX
+	std::ifstream meminfo(MEMINFO_FILE);
+	if (meminfo.is_open())
+	{
+		// MemTotal:		4108424 kB
+		// MemFree:			1244064 kB
+		// Buffers:			  85164 kB
+		// Cached:			1990264 kB
+		// SwapCached:			  0 kB
+		// Active:			1176648 kB
+		// Inactive:		1427532 kB
+		// ...
+		// VmallocTotal:	 122880 kB
+		// VmallocUsed:		  65252 kB
+		// VmallocChunk:	  52356 kB
+		// HardwareCorrupted:	  0 kB
+		// HugePages_Total:		  0
+		// HugePages_Free:		  0
+		// HugePages_Rsvd:		  0
+		// HugePages_Surp:		  0
+		// Hugepagesize:	   2048 kB
+		// DirectMap4k:		 434168 kB
+		// DirectMap2M:		 477184 kB
+
+		boost::regex stat_rx("(.+): +([0-9]+)( kB)?");
+		boost::smatch matched;
+
+		std::string line;
+		while (std::getline(meminfo, line))
+		{
+			if (boost::regex_match(line, line+linelen, matched, stat_rx))
+			{
+				// e.g. "MemTotal:		4108424 kB"
+				LLSD::String key(matched[1].first, matched[1].second);
+				LLSD::String value_str(matched[2].first, matched[2].second);
+				LLSD::Integer value(boost::lexical_cast<LLSD::Integer>(value_str));
+				// Store this statistic.
+				mData.append(LLSDArray(key)(value));
+			}
+			else
+			{
+				LL_WARNS("LLMemoryInfo") << "unrecognized " << MEMINFO_FILE << " line: "
+										 << line << LL_ENDL;
+			}
+		}
+	}
+	else
+	{
+		s << "Unable to collect memory information" << std::endl;
+	}
+
+#else
+	s << "Unknown system; unable to collect memory information" << std::endl;
+
+#endif
+
+    // should become LL_DEBUGS when we're happy
+    LL_INFOS("LLMemoryInfo") << "Populated mData:\n";
+    LLSDSerialize::toPrettyXML(mData, LL_CONT);
+    LL_ENDL;
+
+    return *this;
+}
+
 std::ostream& operator<<(std::ostream& s, const LLOSInfo& info)
 {
 	info.stream(s);
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index 41a4f25000..5b44757e08 100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -36,6 +36,7 @@
 //  llinfos << info << llendl;
 //
 
+#include "llsd.h"
 #include <iosfwd>
 #include <string>
 
@@ -117,6 +118,33 @@ public:
 
 	//get the available memory infomation in KiloBytes.
 	static void getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb);
+
+	// Retrieve a map of memory statistics. The keys of the map are platform-
+	// dependent. The values are in kilobytes.
+	LLSD getStatsMap() const;
+
+	// Retrieve memory statistics: an array of pair arrays [name, value]. This
+	// is the same data as presented in getStatsMap(), but it preserves the
+	// order in which we retrieved it from the OS in case that's useful. The
+	// set of statistics names is platform-dependent. The values are in
+	// kilobytes to try to avoid integer overflow.
+	LLSD getStatsArray() const;
+
+	// Re-fetch memory data (as reported by stream() and getStats*()) from the
+	// system. Normally this is fetched at construction time. Return (*this)
+	// to permit usage of the form:
+	// @code
+	// LLMemoryInfo info;
+	// ...
+	// info.refresh().getStatsArray();
+	// @endcode
+	LLMemoryInfo& refresh();
+
+private:
+	// Internally, we store memory stats as for getStatsArray(). It's
+	// straightforward to convert that to getStatsMap() form, less so to
+	// reconstruct the original order when converting the other way.
+	LLSD mData;
 };
 
 
-- 
cgit v1.2.3


From 21ff3d0d1ce10446cbb1cf9bc08d2c0ebe9705fe Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 29 Jun 2011 20:42:30 -0400
Subject: CHOP-753: fix minor compilation errors on Linux

---
 indra/llcommon/llsys.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 40914dca3f..2897a533d9 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -1050,7 +1050,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 		std::string line;
 		while (std::getline(meminfo, line))
 		{
-			if (boost::regex_match(line, line+linelen, matched, stat_rx))
+			if (boost::regex_match(line, matched, stat_rx))
 			{
 				// e.g. "MemTotal:		4108424 kB"
 				LLSD::String key(matched[1].first, matched[1].second);
@@ -1068,11 +1068,11 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 	}
 	else
 	{
-		s << "Unable to collect memory information" << std::endl;
+		LL_WARNS("LLMemoryInfo") << "Unable to collect memory information" << LL_ENDL;
 	}
 
 #else
-	s << "Unknown system; unable to collect memory information" << std::endl;
+	LL_WARNS("LLMemoryInfo") << "Unknown system; unable to collect memory information" << LL_ENDL;
 
 #endif
 
-- 
cgit v1.2.3


From b75eedb0dce0c6b11e248c4f244e0020a5b97a42 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 30 Jun 2011 10:12:45 -0400
Subject: CHOP-753: Fix errors in LLMemoryInfo Mac-specific code. Handle
 conversion errors (boost::bad_lexical_cast). Glean additional LLSD statistics
 from vm_stat output.

---
 indra/llcommon/llsys.cpp | 93 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 73 insertions(+), 20 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 2897a533d9..e4404f31c7 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -50,6 +50,7 @@
 #include <boost/regex.hpp>
 #include <boost/foreach.hpp>
 #include <boost/lexical_cast.hpp>
+#include <boost/range.hpp>
 
 using namespace llsd;
 
@@ -955,7 +956,8 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 
 		boost::regex pagesize_rx("\\(page size of ([0-9]+) bytes\\)");
 		boost::regex stat_rx("(.+): +([0-9]+)\\.");
-		boost::regex pages_rx("Pages ");
+		boost::regex cache_rx("Object cache: ([0-9]+) hits of ([0-9]+) lookups "
+							  "\\(([0-9]+)% hit rate\\)");
 		boost::cmatch matched;
 		LLSD::Integer pagesizekb(4096/1024);
 
@@ -970,41 +972,81 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 			{
 				line[--linelen] = '\0';
 			}
-			if (boost::regex_search(&line[0], line+linelen, matched, pagesize_rx))
+			if (boost::regex_search(line, matched, pagesize_rx))
 			{
 				// "Mach Virtual Memory Statistics: (page size of 4096 bytes)"
 				std::string pagesize_str(matched[1].first, matched[1].second);
-				// Reasonable to assume that pagesize will always be a
-				// multiple of 1Kb?
-				pagesizekb = boost::lexical_cast<LLSD::Integer>(pagesize_str)/1024;
+				try
+				{
+					// Reasonable to assume that pagesize will always be a
+					// multiple of 1Kb?
+					pagesizekb = boost::lexical_cast<LLSD::Integer>(pagesize_str)/1024;
+				}
+				catch (const boost::bad_lexical_cast&)
+				{
+					LL_WARNS("LLMemoryInfo") << "couldn't parse '" << pagesize_str
+											 << "' in vm_stat line: " << line << LL_ENDL;
+					continue;
+				}
+				mData.append(LLSDArray("page size")(pagesizekb));
 			}
-			else if (boost::regex_match(&line[0], line+linelen, matched, stat_rx))
+			else if (boost::regex_match(line, matched, stat_rx))
 			{
 				// e.g. "Pages free:					 462078."
 				// Strip double-quotes off certain statistic names
-				if (matched[1].first[0] == '"' && matched[1].second[-1] == '"')
+				const char *key_begin(matched[1].first), *key_end(matched[1].second);
+				if (key_begin[0] == '"' && key_end[-1] == '"')
 				{
-					++matched[1].first;
-					--matched[1].second;
+					++key_begin;
+					--key_end;
 				}
-				LLSD::String key(matched[1].first, matched[1].second);
+				LLSD::String key(key_begin, key_end);
 				LLSD::String value_str(matched[2].first, matched[2].second);
-				LLSD::Integer value(boost::lexical_cast<LLSD::Integer>(value_str));
+				LLSD::Integer value(0);
+				try
+				{
+					value = boost::lexical_cast<LLSD::Integer>(value_str);
+				}
+				catch (const boost::bad_lexical_cast&)
+				{
+					LL_WARNS("LLMemoryInfo") << "couldn't parse '" << value_str
+											 << "' in vm_stat line: " << line << LL_ENDL;
+					continue;
+				}
 				// Store this statistic.
 				mData.append(LLSDArray(key)(value));
 				// Is this in units of pages? If so, convert to Kb.
-				// boost::regex_match() doc sez: "If you want to match a
-				// prefix of the character string then use regex_search with
-				// the flag match_continuous set."
-				boost::smatch smatched;
-				if (boost::regex_search(key, smatched, pages_rx, boost::match_continuous))
+				static const LLSD::String pages("Pages ");
+				if (key.substr(0, pages.length()) == pages)
 				{
-					// Synthesize a new key with kB in place of Pages
-					LLSD::String kbkey("kB ");
-					kbkey.append(smatched[0].second, key.end());
+					// Synthesize a new key with kb in place of Pages
+					LLSD::String kbkey("kb ");
+					kbkey.append(key.substr(pages.length()));
 					mData.append(LLSDArray(kbkey)(value * pagesizekb));
 				}
 			}
+			else if (boost::regex_match(line, matched, cache_rx))
+			{
+				// e.g. "Object cache: 841598 hits of 7629869 lookups (11% hit rate)"
+				static const char* cache_keys[] = { "cache hits", "cache lookups", "cache hit%" };
+				std::vector<LLSD::Integer> cache_values;
+				for (size_t i = 0; i < (sizeof(cache_keys)/sizeof(cache_keys[0])); ++i)
+				{
+					LLSD::String value_str(matched[i+1].first, matched[i+1].second);
+					LLSD::Integer value(0);
+					try
+					{
+						value = boost::lexical_cast<LLSD::Integer>(value_str);
+					}
+					catch (boost::bad_lexical_cast&)
+					{
+						LL_WARNS("LLMemoryInfo") << "couldn't parse '" << value_str
+												 << "' in vm_stat line: " << line << LL_ENDL;
+						continue;
+					}
+					mData.append(LLSDArray(cache_keys[i])(value));
+				}
+			}
 			else
 			{
 				LL_WARNS("LLMemoryInfo") << "unrecognized vm_stat line: " << line << LL_ENDL;
@@ -1055,7 +1097,18 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 				// e.g. "MemTotal:		4108424 kB"
 				LLSD::String key(matched[1].first, matched[1].second);
 				LLSD::String value_str(matched[2].first, matched[2].second);
-				LLSD::Integer value(boost::lexical_cast<LLSD::Integer>(value_str));
+				LLSD::Integer value(0);
+				try
+				{
+					value = boost::lexical_cast<LLSD::Integer>(value_str);
+				}
+				catch (const boost::bad_lexical_cast&)
+				{
+					LL_WARNS("LLMemoryInfo") << "couldn't parse '" << value_str
+											 << "' in " << MEMINFO_FILE << " line: "
+											 << line << LL_ENDL;
+					continue;
+				}
 				// Store this statistic.
 				mData.append(LLSDArray(key)(value));
 			}
-- 
cgit v1.2.3


From 01607fe418b19e7439020047c270c0e7c86725e7 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 30 Jun 2011 11:50:54 -0400
Subject: CHOP-753: Reduce redundancy in LLMemoryInfo. Recast stream() to
 display data from LLSD array rather than reinvoking OS operations used to
 capture it. Make refresh() cache LLSD data in map form as well as array;
 fetch items from that in a few places to avoid going back to OS.

---
 indra/llcommon/llsys.cpp | 159 ++++++++++++++++-------------------------------
 indra/llcommon/llsys.h   |  10 +--
 2 files changed, 58 insertions(+), 111 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index e4404f31c7..8222702c50 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -665,11 +665,7 @@ static U32 LLMemoryAdjustKBResult(U32 inKB)
 U32 LLMemoryInfo::getPhysicalMemoryKB() const
 {
 #if LL_WINDOWS
-	MEMORYSTATUSEX state;
-	state.dwLength = sizeof(state);
-	GlobalMemoryStatusEx(&state);
-
-	return LLMemoryAdjustKBResult((U32)(state.ullTotalPhys >> 10));
+	return LLMemoryAdjustKBResult(mStatsMap["Total Physical KB"]);
 
 #elif LL_DARWIN
 	// This might work on Linux as well.  Someone check...
@@ -717,15 +713,11 @@ U32 LLMemoryInfo::getPhysicalMemoryClamped() const
 void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb)
 {
 #if LL_WINDOWS
-	MEMORYSTATUSEX state;
-	state.dwLength = sizeof(state);
-	GlobalMemoryStatusEx(&state);
-
-	avail_physical_mem_kb = (U32)(state.ullAvailPhys/1024) ;
-	avail_virtual_mem_kb = (U32)(state.ullAvailVirtual/1024) ;
+	avail_physical_mem_kb = mStatsMap["Avail Physical KB"];
+	avail_virtual_mem_kb  = mStatsMap["Avail Virtual KB"];
 
 #elif LL_DARWIN
-	// Run vm_stat and filter output, scaling for page size:
+	// mStatsMap is derived from vm_stat, look for (e.g.) "kb free":
 	// $ vm_stat
 	// Mach Virtual Memory Statistics: (page size of 4096 bytes)
 	// Pages free:                   462078.
@@ -743,7 +735,7 @@ void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_v
 	avail_virtual_mem_kb = -1 ;
 
 #elif LL_LINUX
-	// Read selected lines from MEMINFO_FILE:
+	// mStatsMap is derived from MEMINFO_FILE:
 	// $ cat /proc/meminfo
 	// MemTotal:        4108424 kB
 	// MemFree:         1244064 kB
@@ -811,114 +803,58 @@ void LLMemoryInfo::stream(std::ostream& s) const
 	// introducer line, then read subsequent lines, etc...
 	std::string pfx(LLError::utcTime() + " <mem> ");
 
-#if LL_WINDOWS
-	MEMORYSTATUSEX state;
-	state.dwLength = sizeof(state);
-	GlobalMemoryStatusEx(&state);
-
-	s << pfx << "Percent Memory use: " << (U32)state.dwMemoryLoad << '%' << std::endl;
-	s << pfx << "Total Physical KB:  " << (U32)(state.ullTotalPhys/1024) << std::endl;
-	s << pfx << "Avail Physical KB:  " << (U32)(state.ullAvailPhys/1024) << std::endl;
-	s << pfx << "Total page KB:      " << (U32)(state.ullTotalPageFile/1024) << std::endl;
-	s << pfx << "Avail page KB:      " << (U32)(state.ullAvailPageFile/1024) << std::endl;
-	s << pfx << "Total Virtual KB:   " << (U32)(state.ullTotalVirtual/1024) << std::endl;
-	s << pfx << "Avail Virtual KB:   " << (U32)(state.ullAvailVirtual/1024) << std::endl;
-
-#elif LL_DARWIN
-	uint64_t phys = 0;
-
-	size_t len = sizeof(phys);	
-	
-	if(sysctlbyname("hw.memsize", &phys, &len, NULL, 0) == 0)
-	{
-		s << pfx << "Total Physical KB:  " << phys/1024 << std::endl;
-	}
-	else
-	{
-		s << "Unable to collect hw.memsize memory information" << std::endl;
-	}
+	// Most of the reason we even store mStatsArray is to preserve the
+	// original order in which we obtained these stats from the OS. So use
+	// mStatsArray in this method rather than mStatsMap, which should present
+	// the same information but in arbitrary order.
 
-	FILE* pout = popen("vm_stat 2>&1", "r");
-	if (! pout)
-	{
-		s << "Unable to collect vm_stat memory information" << std::endl;
-	}
-	else
+	// Max key length
+	size_t key_width(0);
+	BOOST_FOREACH(LLSD pair, inArray(mStatsArray))
 	{
-		// Here 'pout' is vm_stat's stdout. Copy it to output stream.
-		char line[100];
-		while (fgets(line, sizeof(line), pout))
+		size_t len(pair[0].asString().length());
+		if (len > key_width)
 		{
-			s << pfx << line;
+			key_width = len;
 		}
-		fclose(pout);
 	}
 
-#elif LL_SOLARIS
-        U64 phys = 0;
-
-        phys = (U64)(sysconf(_SC_PHYS_PAGES)) * (U64)(sysconf(_SC_PAGESIZE)/1024);
-
-        s << pfx << "Total Physical KB:  " << phys << std::endl;
-
-#elif LL_LINUX
-	std::ifstream meminfo(MEMINFO_FILE);
-	if (meminfo.is_open())
-	{
-		std::string line;
-		while (std::getline(meminfo, line))
-		{
-			s << pfx << line << '\n';
-		}
-	}
-	else
+	// Now stream stats
+	BOOST_FOREACH(LLSD pair, inArray(mStatsArray))
 	{
-		s << "Unable to collect memory information" << std::endl;
+		s << pfx << std::setw(key_width+1) << (pair[0].asString() + ':')
+		  << ' '
+		  << std::setw(12) << pair[1].asInteger() << std::endl;
 	}
-
-#else
-	s << "Unknown system; unable to collect memory information" << std::endl;
-
-#endif
 }
 
 LLSD LLMemoryInfo::getStatsMap() const
 {
-    LLSD map;
-
-    BOOST_FOREACH(LLSD pair, inArray(mData))
-    {
-        // Have to be clear that we want the key asString() to specify map
-        // indexing rather than array subscripting.
-        map[pair[0].asString()] = pair[1];
-    }
-
-    return map;
+	return mStatsMap;
 }
 
 LLSD LLMemoryInfo::getStatsArray() const
 {
-    return mData;
+	return mStatsArray;
 }
 
 LLMemoryInfo& LLMemoryInfo::refresh()
 {
-    // This implementation is derived from stream() code (as of 2011-06-29).
-    // Hopefully we'll reimplement stream() to use mData before long...
-    mData = LLSD::emptyArray();
+	// This implementation is derived from stream() code (as of 2011-06-29).
+	mStatsArray = LLSD::emptyArray();
 
 #if LL_WINDOWS
 	MEMORYSTATUSEX state;
 	state.dwLength = sizeof(state);
 	GlobalMemoryStatusEx(&state);
 
-	mData.append(LLSDArray("Percent Memory use")(LLSD::Integer(state.dwMemoryLoad)));
-	mData.append(LLSDArray("Total Physical KB") (LLSD::Integer(state.ullTotalPhys/1024)));
-	mData.append(LLSDArray("Avail Physical KB") (LLSD::Integer(state.ullAvailPhys/1024)));
-	mData.append(LLSDArray("Total page KB")     (LLSD::Integer(state.ullTotalPageFile/1024)));
-	mData.append(LLSDArray("Avail page KB")     (LLSD::Integer(state.ullAvailPageFile/1024)));
-	mData.append(LLSDArray("Total Virtual KB")  (LLSD::Integer(state.ullTotalVirtual/1024)));
-	mData.append(LLSDArray("Avail Virtual KB")  (LLSD::Integer(state.ullAvailVirtual/1024)));
+	mStatsArray.append(LLSDArray("Percent Memory use")(LLSD::Integer(state.dwMemoryLoad)));
+	mStatsArray.append(LLSDArray("Total Physical KB") (LLSD::Integer(state.ullTotalPhys/1024)));
+	mStatsArray.append(LLSDArray("Avail Physical KB") (LLSD::Integer(state.ullAvailPhys/1024)));
+	mStatsArray.append(LLSDArray("Total page KB")     (LLSD::Integer(state.ullTotalPageFile/1024)));
+	mStatsArray.append(LLSDArray("Avail page KB")     (LLSD::Integer(state.ullAvailPageFile/1024)));
+	mStatsArray.append(LLSDArray("Total Virtual KB")  (LLSD::Integer(state.ullTotalVirtual/1024)));
+	mStatsArray.append(LLSDArray("Avail Virtual KB")  (LLSD::Integer(state.ullAvailVirtual/1024)));
 
 #elif LL_DARWIN
 	uint64_t phys = 0;
@@ -927,7 +863,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 	
 	if (sysctlbyname("hw.memsize", &phys, &len, NULL, 0) == 0)
 	{
-		mData.append(LLSDArray("Total Physical KB")(LLSD::Integer(phys/1024)));
+		mStatsArray.append(LLSDArray("Total Physical KB")(LLSD::Integer(phys/1024)));
 	}
 	else
 	{
@@ -972,6 +908,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 			{
 				line[--linelen] = '\0';
 			}
+			LL_DEBUGS("LLMemoryInfo") << line << LL_ENDL;
 			if (boost::regex_search(line, matched, pagesize_rx))
 			{
 				// "Mach Virtual Memory Statistics: (page size of 4096 bytes)"
@@ -988,7 +925,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 											 << "' in vm_stat line: " << line << LL_ENDL;
 					continue;
 				}
-				mData.append(LLSDArray("page size")(pagesizekb));
+				mStatsArray.append(LLSDArray("page size")(pagesizekb));
 			}
 			else if (boost::regex_match(line, matched, stat_rx))
 			{
@@ -1014,7 +951,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 					continue;
 				}
 				// Store this statistic.
-				mData.append(LLSDArray(key)(value));
+				mStatsArray.append(LLSDArray(key)(value));
 				// Is this in units of pages? If so, convert to Kb.
 				static const LLSD::String pages("Pages ");
 				if (key.substr(0, pages.length()) == pages)
@@ -1022,7 +959,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 					// Synthesize a new key with kb in place of Pages
 					LLSD::String kbkey("kb ");
 					kbkey.append(key.substr(pages.length()));
-					mData.append(LLSDArray(kbkey)(value * pagesizekb));
+					mStatsArray.append(LLSDArray(kbkey)(value * pagesizekb));
 				}
 			}
 			else if (boost::regex_match(line, matched, cache_rx))
@@ -1044,7 +981,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 												 << "' in vm_stat line: " << line << LL_ENDL;
 						continue;
 					}
-					mData.append(LLSDArray(cache_keys[i])(value));
+					mStatsArray.append(LLSDArray(cache_keys[i])(value));
 				}
 			}
 			else
@@ -1060,7 +997,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 
 	phys = (U64)(sysconf(_SC_PHYS_PAGES)) * (U64)(sysconf(_SC_PAGESIZE)/1024);
 
-	mData.append(LLSDArray("Total Physical KB")(phys));
+	mStatsArray.append(LLSDArray("Total Physical KB")(phys));
 
 #elif LL_LINUX
 	std::ifstream meminfo(MEMINFO_FILE);
@@ -1092,6 +1029,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 		std::string line;
 		while (std::getline(meminfo, line))
 		{
+			LL_DEBUGS("LLMemoryInfo") << line << LL_ENDL;
 			if (boost::regex_match(line, matched, stat_rx))
 			{
 				// e.g. "MemTotal:		4108424 kB"
@@ -1110,7 +1048,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 					continue;
 				}
 				// Store this statistic.
-				mData.append(LLSDArray(key)(value));
+				mStatsArray.append(LLSDArray(key)(value));
 			}
 			else
 			{
@@ -1129,12 +1067,19 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 
 #endif
 
-    // should become LL_DEBUGS when we're happy
-    LL_INFOS("LLMemoryInfo") << "Populated mData:\n";
-    LLSDSerialize::toPrettyXML(mData, LL_CONT);
-    LL_ENDL;
+	// Recast same data as mStatsMap for easy access
+	BOOST_FOREACH(LLSD pair, inArray(mStatsArray))
+	{
+		// Specify asString() to disambiguate map indexing from array
+		// subscripting.
+		mStatsMap[pair[0].asString()] = pair[1];
+	}
+
+	LL_DEBUGS("LLMemoryInfo") << "Populated mStatsMap:\n";
+	LLSDSerialize::toPrettyXML(mStatsMap, LL_CONT);
+	LL_ENDL;
 
-    return *this;
+	return *this;
 }
 
 std::ostream& operator<<(std::ostream& s, const LLOSInfo& info)
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index 5b44757e08..8565bfa0b9 100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -141,10 +141,12 @@ public:
 	LLMemoryInfo& refresh();
 
 private:
-	// Internally, we store memory stats as for getStatsArray(). It's
-	// straightforward to convert that to getStatsMap() form, less so to
-	// reconstruct the original order when converting the other way.
-	LLSD mData;
+	// Memory stats for getStatsArray(). It's straightforward to convert that
+	// to getStatsMap() form, less so to reconstruct the original order when
+	// converting the other way.
+	LLSD mStatsArray;
+	// Memory stats for getStatsMap().
+	LLSD mStatsMap;
 };
 
 
-- 
cgit v1.2.3


From abf50e8c7d3cf0bab46286f4b300c7d3be976775 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 30 Jun 2011 13:57:11 -0400
Subject: CHOP-753: Fix compile errors in LLMemoryInfo Windows-specific code.

---
 indra/llcommon/llsys.cpp | 72 ++++++++++++++++++++++++++++++------------------
 indra/llcommon/llsys.h   |  4 +++
 2 files changed, 49 insertions(+), 27 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 8222702c50..d02a807000 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -665,7 +665,7 @@ static U32 LLMemoryAdjustKBResult(U32 inKB)
 U32 LLMemoryInfo::getPhysicalMemoryKB() const
 {
 #if LL_WINDOWS
-	return LLMemoryAdjustKBResult(mStatsMap["Total Physical KB"]);
+	return LLMemoryAdjustKBResult(mStatsMap["Total Physical KB"].asInteger());
 
 #elif LL_DARWIN
 	// This might work on Linux as well.  Someone check...
@@ -712,9 +712,13 @@ U32 LLMemoryInfo::getPhysicalMemoryClamped() const
 //static
 void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb)
 {
+	// Sigh, this shouldn't be a static method, then we wouldn't have to
+	// reload this data separately from refresh()
+	LLSD statsMap(loadStatsMap(loadStatsArray()));
+
 #if LL_WINDOWS
-	avail_physical_mem_kb = mStatsMap["Avail Physical KB"];
-	avail_virtual_mem_kb  = mStatsMap["Avail Virtual KB"];
+	avail_physical_mem_kb = statsMap["Avail Physical KB"].asInteger();
+	avail_virtual_mem_kb  = statsMap["Avail Virtual KB"].asInteger();
 
 #elif LL_DARWIN
 	// mStatsMap is derived from vm_stat, look for (e.g.) "kb free":
@@ -839,22 +843,35 @@ LLSD LLMemoryInfo::getStatsArray() const
 }
 
 LLMemoryInfo& LLMemoryInfo::refresh()
+{
+	mStatsArray = loadStatsArray();
+	// Recast same data as mStatsMap for easy access
+	mStatsMap = loadStatsMap(mStatsArray);
+
+	LL_DEBUGS("LLMemoryInfo") << "Populated mStatsMap:\n";
+	LLSDSerialize::toPrettyXML(mStatsMap, LL_CONT);
+	LL_ENDL;
+
+	return *this;
+}
+
+LLSD LLMemoryInfo::loadStatsArray()
 {
 	// This implementation is derived from stream() code (as of 2011-06-29).
-	mStatsArray = LLSD::emptyArray();
+	LLSD statsArray(LLSD::emptyArray());
 
 #if LL_WINDOWS
 	MEMORYSTATUSEX state;
 	state.dwLength = sizeof(state);
 	GlobalMemoryStatusEx(&state);
 
-	mStatsArray.append(LLSDArray("Percent Memory use")(LLSD::Integer(state.dwMemoryLoad)));
-	mStatsArray.append(LLSDArray("Total Physical KB") (LLSD::Integer(state.ullTotalPhys/1024)));
-	mStatsArray.append(LLSDArray("Avail Physical KB") (LLSD::Integer(state.ullAvailPhys/1024)));
-	mStatsArray.append(LLSDArray("Total page KB")     (LLSD::Integer(state.ullTotalPageFile/1024)));
-	mStatsArray.append(LLSDArray("Avail page KB")     (LLSD::Integer(state.ullAvailPageFile/1024)));
-	mStatsArray.append(LLSDArray("Total Virtual KB")  (LLSD::Integer(state.ullTotalVirtual/1024)));
-	mStatsArray.append(LLSDArray("Avail Virtual KB")  (LLSD::Integer(state.ullAvailVirtual/1024)));
+	statsArray.append(LLSDArray("Percent Memory use")(LLSD::Integer(state.dwMemoryLoad)));
+	statsArray.append(LLSDArray("Total Physical KB") (LLSD::Integer(state.ullTotalPhys/1024)));
+	statsArray.append(LLSDArray("Avail Physical KB") (LLSD::Integer(state.ullAvailPhys/1024)));
+	statsArray.append(LLSDArray("Total page KB")     (LLSD::Integer(state.ullTotalPageFile/1024)));
+	statsArray.append(LLSDArray("Avail page KB")     (LLSD::Integer(state.ullAvailPageFile/1024)));
+	statsArray.append(LLSDArray("Total Virtual KB")  (LLSD::Integer(state.ullTotalVirtual/1024)));
+	statsArray.append(LLSDArray("Avail Virtual KB")  (LLSD::Integer(state.ullAvailVirtual/1024)));
 
 #elif LL_DARWIN
 	uint64_t phys = 0;
@@ -863,7 +880,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 	
 	if (sysctlbyname("hw.memsize", &phys, &len, NULL, 0) == 0)
 	{
-		mStatsArray.append(LLSDArray("Total Physical KB")(LLSD::Integer(phys/1024)));
+		statsArray.append(LLSDArray("Total Physical KB")(LLSD::Integer(phys/1024)));
 	}
 	else
 	{
@@ -925,7 +942,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 											 << "' in vm_stat line: " << line << LL_ENDL;
 					continue;
 				}
-				mStatsArray.append(LLSDArray("page size")(pagesizekb));
+				statsArray.append(LLSDArray("page size")(pagesizekb));
 			}
 			else if (boost::regex_match(line, matched, stat_rx))
 			{
@@ -951,7 +968,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 					continue;
 				}
 				// Store this statistic.
-				mStatsArray.append(LLSDArray(key)(value));
+				statsArray.append(LLSDArray(key)(value));
 				// Is this in units of pages? If so, convert to Kb.
 				static const LLSD::String pages("Pages ");
 				if (key.substr(0, pages.length()) == pages)
@@ -959,7 +976,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 					// Synthesize a new key with kb in place of Pages
 					LLSD::String kbkey("kb ");
 					kbkey.append(key.substr(pages.length()));
-					mStatsArray.append(LLSDArray(kbkey)(value * pagesizekb));
+					statsArray.append(LLSDArray(kbkey)(value * pagesizekb));
 				}
 			}
 			else if (boost::regex_match(line, matched, cache_rx))
@@ -981,7 +998,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 												 << "' in vm_stat line: " << line << LL_ENDL;
 						continue;
 					}
-					mStatsArray.append(LLSDArray(cache_keys[i])(value));
+					statsArray.append(LLSDArray(cache_keys[i])(value));
 				}
 			}
 			else
@@ -997,7 +1014,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 
 	phys = (U64)(sysconf(_SC_PHYS_PAGES)) * (U64)(sysconf(_SC_PAGESIZE)/1024);
 
-	mStatsArray.append(LLSDArray("Total Physical KB")(phys));
+	statsArray.append(LLSDArray("Total Physical KB")(phys));
 
 #elif LL_LINUX
 	std::ifstream meminfo(MEMINFO_FILE);
@@ -1048,7 +1065,7 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 					continue;
 				}
 				// Store this statistic.
-				mStatsArray.append(LLSDArray(key)(value));
+				statsArray.append(LLSDArray(key)(value));
 			}
 			else
 			{
@@ -1067,19 +1084,20 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 
 #endif
 
-	// Recast same data as mStatsMap for easy access
-	BOOST_FOREACH(LLSD pair, inArray(mStatsArray))
+	return statsArray;
+}
+
+LLSD LLMemoryInfo::loadStatsMap(const LLSD& statsArray)
+{
+	LLSD statsMap;
+
+	BOOST_FOREACH(LLSD pair, inArray(statsArray))
 	{
 		// Specify asString() to disambiguate map indexing from array
 		// subscripting.
-		mStatsMap[pair[0].asString()] = pair[1];
+		statsMap[pair[0].asString()] = pair[1];
 	}
-
-	LL_DEBUGS("LLMemoryInfo") << "Populated mStatsMap:\n";
-	LLSDSerialize::toPrettyXML(mStatsMap, LL_CONT);
-	LL_ENDL;
-
-	return *this;
+	return statsMap;
 }
 
 std::ostream& operator<<(std::ostream& s, const LLOSInfo& info)
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index 8565bfa0b9..7fcb050ed0 100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -141,6 +141,10 @@ public:
 	LLMemoryInfo& refresh();
 
 private:
+	// These methods are used to set mStatsArray and mStatsMap.
+	static LLSD loadStatsArray();
+	static LLSD loadStatsMap(const LLSD&);
+
 	// Memory stats for getStatsArray(). It's straightforward to convert that
 	// to getStatsMap() form, less so to reconstruct the original order when
 	// converting the other way.
-- 
cgit v1.2.3


From bfbd7c6df5d00b40a5a36fe7d99527084f19e76d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 5 Jul 2011 20:20:26 -0400
Subject: CHOP-753: On Windows, add GetPerformanceInfo to LLMemoryInfo stats.
 So far we've only been querying GlobalMemoryStatusEx(), but
 GetPerformanceInfo() delivers a bunch more memory-related stats that may be
 pertinent. Try capturing those too. May not yet compile on Windows...

---
 indra/llcommon/llsys.cpp | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index d02a807000..e0ce74234d 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -58,6 +58,7 @@ using namespace llsd;
 #	define WIN32_LEAN_AND_MEAN
 #	include <winsock2.h>
 #	include <windows.h>
+#   include <psapi.h>
 #elif LL_DARWIN
 #	include <errno.h>
 #	include <sys/sysctl.h>
@@ -873,6 +874,25 @@ LLSD LLMemoryInfo::loadStatsArray()
 	statsArray.append(LLSDArray("Total Virtual KB")  (LLSD::Integer(state.ullTotalVirtual/1024)));
 	statsArray.append(LLSDArray("Avail Virtual KB")  (LLSD::Integer(state.ullAvailVirtual/1024)));
 
+	PERFORMANCE_INFORMATION perf;
+	perf.cb = sizeof(perf);
+	GetPerformanceInfo(&perf, sizeof(perf));
+
+	SIZE_T pagekb(perf.PageSize/1024);
+	statsArray.append(LLSDArray("CommitTotal KB")	(LLSD::Integer(perf.CommitTotal * pagekb)));
+	statsArray.append(LLSDArray("CommitLimit KB")	(LLSD::Integer(perf.CommitLimit * pagekb)));
+	statsArray.append(LLSDArray("CommitPeak KB")	(LLSD::Integer(perf.CommitPeak * pagekb)));
+	statsArray.append(LLSDArray("PhysicalTotal KB") (LLSD::Integer(perf.PhysicalTotal * pagekb)));
+	statsArray.append(LLSDArray("PhysicalAvail KB") (LLSD::Integer(perf.PhysicalAvailable * pagekb)));
+	statsArray.append(LLSDArray("SystemCache KB")	(LLSD::Integer(perf.SystemCache * pagekb)));
+	statsArray.append(LLSDArray("KernelTotal KB")	(LLSD::Integer(perf.KernelTotal * pagekb)));
+	statsArray.append(LLSDArray("KernelPaged KB")	(LLSD::Integer(perf.KernelPaged * pagekb)));
+	statsArray.append(LLSDArray("KernelNonpaged KB")(LLSD::Integer(perf.KernelNonpaged * pagekb)));
+	statsArray.append(LLSDArray("PageSize KB")		(LLSD::Integer(pagekb)));
+	statsArray.append(LLSDArray("HandleCount")		(LLSD::Integer(perf.HandleCount)));
+	statsArray.append(LLSDArray("ProcessCount")		(LLSD::Integer(perf.ProcessCount)));
+	statsArray.append(LLSDArray("ThreadCount")		(LLSD::Integer(perf.ThreadCount)));
+
 #elif LL_DARWIN
 	uint64_t phys = 0;
 
-- 
cgit v1.2.3


From 6c0d6956da046df9638932030d4c95ff299ca76f Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 7 Jul 2011 14:05:56 -0400
Subject: CHOP-753: add stats from GetProcessMemoryInfo() on Windows. Introduce
 StatsArray helper class to facilitate accumulating stats in the
 array-of-pair-arrays form cached internally by LLMemoryInfo.

---
 indra/llcommon/llsys.cpp | 96 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 66 insertions(+), 30 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index e0ce74234d..cec1cd90e9 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -58,7 +58,8 @@ using namespace llsd;
 #	define WIN32_LEAN_AND_MEAN
 #	include <winsock2.h>
 #	include <windows.h>
-#   include <psapi.h>
+#   include <psapi.h>               // GetPerformanceInfo() et al.
+#   include <kfuncs.h>              // GetCurrentProcess()
 #elif LL_DARWIN
 #	include <errno.h>
 #	include <sys/sysctl.h>
@@ -640,6 +641,26 @@ void LLCPUInfo::stream(std::ostream& s) const
 	s << "->mCPUString:  " << mCPUString << std::endl;
 }
 
+// Helper class for LLMemoryInfo: accumulate stats in the array-of-pair-arrays
+// form we store for LLMemoryInfo::getStatsArray().
+class StatsArray
+{
+public:
+	StatsArray():
+		mStats(LLSD::emptyArray())
+	{}
+
+	void add(const LLSD::String& name, LLSD::Integer value)
+	{
+		mStats.append(LLSDArray(name)(value));
+	}
+
+	LLSD get() const { return mStats; }
+
+private:
+	LLSD mStats;
+};
+
 LLMemoryInfo::LLMemoryInfo()
 {
 	refresh();
@@ -859,39 +880,54 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 LLSD LLMemoryInfo::loadStatsArray()
 {
 	// This implementation is derived from stream() code (as of 2011-06-29).
-	LLSD statsArray(LLSD::emptyArray());
+	StatsArray stats;
 
 #if LL_WINDOWS
 	MEMORYSTATUSEX state;
 	state.dwLength = sizeof(state);
 	GlobalMemoryStatusEx(&state);
 
-	statsArray.append(LLSDArray("Percent Memory use")(LLSD::Integer(state.dwMemoryLoad)));
-	statsArray.append(LLSDArray("Total Physical KB") (LLSD::Integer(state.ullTotalPhys/1024)));
-	statsArray.append(LLSDArray("Avail Physical KB") (LLSD::Integer(state.ullAvailPhys/1024)));
-	statsArray.append(LLSDArray("Total page KB")     (LLSD::Integer(state.ullTotalPageFile/1024)));
-	statsArray.append(LLSDArray("Avail page KB")     (LLSD::Integer(state.ullAvailPageFile/1024)));
-	statsArray.append(LLSDArray("Total Virtual KB")  (LLSD::Integer(state.ullTotalVirtual/1024)));
-	statsArray.append(LLSDArray("Avail Virtual KB")  (LLSD::Integer(state.ullAvailVirtual/1024)));
+	stats.add("Percent Memory use", state.dwMemoryLoad);
+	stats.add("Total Physical KB",  state.ullTotalPhys/1024);
+	stats.add("Avail Physical KB",  state.ullAvailPhys/1024);
+	stats.add("Total page KB",      state.ullTotalPageFile/1024);
+	stats.add("Avail page KB",      state.ullAvailPageFile/1024);
+	stats.add("Total Virtual KB",   state.ullTotalVirtual/1024);
+	stats.add("Avail Virtual KB",   state.ullAvailVirtual/1024);
 
 	PERFORMANCE_INFORMATION perf;
 	perf.cb = sizeof(perf);
 	GetPerformanceInfo(&perf, sizeof(perf));
 
 	SIZE_T pagekb(perf.PageSize/1024);
-	statsArray.append(LLSDArray("CommitTotal KB")	(LLSD::Integer(perf.CommitTotal * pagekb)));
-	statsArray.append(LLSDArray("CommitLimit KB")	(LLSD::Integer(perf.CommitLimit * pagekb)));
-	statsArray.append(LLSDArray("CommitPeak KB")	(LLSD::Integer(perf.CommitPeak * pagekb)));
-	statsArray.append(LLSDArray("PhysicalTotal KB") (LLSD::Integer(perf.PhysicalTotal * pagekb)));
-	statsArray.append(LLSDArray("PhysicalAvail KB") (LLSD::Integer(perf.PhysicalAvailable * pagekb)));
-	statsArray.append(LLSDArray("SystemCache KB")	(LLSD::Integer(perf.SystemCache * pagekb)));
-	statsArray.append(LLSDArray("KernelTotal KB")	(LLSD::Integer(perf.KernelTotal * pagekb)));
-	statsArray.append(LLSDArray("KernelPaged KB")	(LLSD::Integer(perf.KernelPaged * pagekb)));
-	statsArray.append(LLSDArray("KernelNonpaged KB")(LLSD::Integer(perf.KernelNonpaged * pagekb)));
-	statsArray.append(LLSDArray("PageSize KB")		(LLSD::Integer(pagekb)));
-	statsArray.append(LLSDArray("HandleCount")		(LLSD::Integer(perf.HandleCount)));
-	statsArray.append(LLSDArray("ProcessCount")		(LLSD::Integer(perf.ProcessCount)));
-	statsArray.append(LLSDArray("ThreadCount")		(LLSD::Integer(perf.ThreadCount)));
+	stats.add("CommitTotal KB",     perf.CommitTotal * pagekb);
+	stats.add("CommitLimit KB",     perf.CommitLimit * pagekb);
+	stats.add("CommitPeak KB",      perf.CommitPeak * pagekb);
+	stats.add("PhysicalTotal KB",   perf.PhysicalTotal * pagekb);
+	stats.add("PhysicalAvail KB",   perf.PhysicalAvailable * pagekb);
+	stats.add("SystemCache KB",     perf.SystemCache * pagekb);
+	stats.add("KernelTotal KB",     perf.KernelTotal * pagekb);
+	stats.add("KernelPaged KB",     perf.KernelPaged * pagekb);
+	stats.add("KernelNonpaged KB",  perf.KernelNonpaged * pagekb);
+	stats.add("PageSize KB",        pagekb);
+	stats.add("HandleCount",        perf.HandleCount);
+	stats.add("ProcessCount",       perf.ProcessCount);
+	stats.add("ThreadCount",        perf.ThreadCount);
+
+	PROCESS_MEMORY_COUNTERS_EX pmem;
+	pmem.cb = sizeof(pmem);
+	GetProcessMemoryInfo(GetCurrentProcess(), &pmem, sizeof(pmem));
+
+	stats.add("Page Fault Count",              pmem.PageFaultCount);
+	stats.add("PeakWorkingSetSize KB",         pmem.PeakWorkingSetSize/1024);
+	stats.add("WorkingSetSize KB",             pmem.WorkingSetSize/1024);
+	stats.add("QutaPeakPagedPoolUsage KB",     pmem.QuotaPeakPagedPoolUsage/1024);
+	stats.add("QuotaPagedPoolUsage KB",        pmem.QuotaPagedPoolUsage/1024);
+	stats.add("QuotaPeakNonPagedPoolUsage KB", pmem.QuotaPeakNonPagedPoolUsage/1024);
+	stats.add("QuotaNonPagedPoolUsage KB",     pmem.QuotaNonPagedPoolUsage/1024);
+	stats.add("PagefileUsage KB",              pmem.PagefileUsage/1024);
+	stats.add("PeakPagefileUsage KB",          pmem.PeakPagefileUsage/1024);
+	stats.add("PrivateUsage KB",               pmem.PrivateUsage/1024);
 
 #elif LL_DARWIN
 	uint64_t phys = 0;
@@ -900,7 +936,7 @@ LLSD LLMemoryInfo::loadStatsArray()
 	
 	if (sysctlbyname("hw.memsize", &phys, &len, NULL, 0) == 0)
 	{
-		statsArray.append(LLSDArray("Total Physical KB")(LLSD::Integer(phys/1024)));
+		stats.add("Total Physical KB", phys/1024);
 	}
 	else
 	{
@@ -962,7 +998,7 @@ LLSD LLMemoryInfo::loadStatsArray()
 											 << "' in vm_stat line: " << line << LL_ENDL;
 					continue;
 				}
-				statsArray.append(LLSDArray("page size")(pagesizekb));
+				stats.add("page size", pagesizekb);
 			}
 			else if (boost::regex_match(line, matched, stat_rx))
 			{
@@ -988,7 +1024,7 @@ LLSD LLMemoryInfo::loadStatsArray()
 					continue;
 				}
 				// Store this statistic.
-				statsArray.append(LLSDArray(key)(value));
+				stats.add(key, value);
 				// Is this in units of pages? If so, convert to Kb.
 				static const LLSD::String pages("Pages ");
 				if (key.substr(0, pages.length()) == pages)
@@ -996,7 +1032,7 @@ LLSD LLMemoryInfo::loadStatsArray()
 					// Synthesize a new key with kb in place of Pages
 					LLSD::String kbkey("kb ");
 					kbkey.append(key.substr(pages.length()));
-					statsArray.append(LLSDArray(kbkey)(value * pagesizekb));
+					stats.add(kbkey, value * pagesizekb);
 				}
 			}
 			else if (boost::regex_match(line, matched, cache_rx))
@@ -1018,7 +1054,7 @@ LLSD LLMemoryInfo::loadStatsArray()
 												 << "' in vm_stat line: " << line << LL_ENDL;
 						continue;
 					}
-					statsArray.append(LLSDArray(cache_keys[i])(value));
+					stats.add(cache_keys[i], value);
 				}
 			}
 			else
@@ -1034,7 +1070,7 @@ LLSD LLMemoryInfo::loadStatsArray()
 
 	phys = (U64)(sysconf(_SC_PHYS_PAGES)) * (U64)(sysconf(_SC_PAGESIZE)/1024);
 
-	statsArray.append(LLSDArray("Total Physical KB")(phys));
+	stats.add("Total Physical KB", phys);
 
 #elif LL_LINUX
 	std::ifstream meminfo(MEMINFO_FILE);
@@ -1085,7 +1121,7 @@ LLSD LLMemoryInfo::loadStatsArray()
 					continue;
 				}
 				// Store this statistic.
-				statsArray.append(LLSDArray(key)(value));
+				stats.add(key, value);
 			}
 			else
 			{
@@ -1104,7 +1140,7 @@ LLSD LLMemoryInfo::loadStatsArray()
 
 #endif
 
-	return statsArray;
+	return stats.get();
 }
 
 LLSD LLMemoryInfo::loadStatsMap(const LLSD& statsArray)
-- 
cgit v1.2.3


From be2c0c1f0b6e04e278dbd1cdd84299aa26dec4b7 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 7 Jul 2011 14:17:28 -0400
Subject: disable watchdog

---
 indra/newview/app_settings/settings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 9161519a10..fc7fd2dd8a 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -12406,7 +12406,7 @@
       <key>Type</key>
       <string>S32</string>
       <key>Value</key>
-      <integer>20</integer>
+      <integer>-1</integer>
     </map>
     <key>WaterEditPresets</key>
     <map>
-- 
cgit v1.2.3


From 65657b9f5cf04b5a84e566b7491daabb1291ace9 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 7 Jul 2011 14:20:37 -0400
Subject: CHOP-753: uh, Microsoft docs lied about header file to use? Remove
 <kfuncs.h>, documented header file for GetCurrentProcess().

---
 indra/llcommon/llsys.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index cec1cd90e9..68566cdbfa 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -59,7 +59,6 @@ using namespace llsd;
 #	include <winsock2.h>
 #	include <windows.h>
 #   include <psapi.h>               // GetPerformanceInfo() et al.
-#   include <kfuncs.h>              // GetCurrentProcess()
 #elif LL_DARWIN
 #	include <errno.h>
 #	include <sys/sysctl.h>
-- 
cgit v1.2.3


From 774306bc25b4b737d318bdd28ab0b078dc60db74 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 7 Jul 2011 14:47:20 -0400
Subject: CHOP-753: have to cast pointer passed to GetProcessMemoryInfo().
 GetProcessMemoryInfo() is prototyped with PROCESS_MEMORY_COUNTERS*, so to
 accept PROCESS_MEMORY_COUNTERS_EX* as documented, have to cast.

---
 indra/llcommon/llsys.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 68566cdbfa..b3ab5008fb 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -915,7 +915,13 @@ LLSD LLMemoryInfo::loadStatsArray()
 
 	PROCESS_MEMORY_COUNTERS_EX pmem;
 	pmem.cb = sizeof(pmem);
-	GetProcessMemoryInfo(GetCurrentProcess(), &pmem, sizeof(pmem));
+	// GetProcessMemoryInfo() is documented to accept either
+	// PROCESS_MEMORY_COUNTERS* or PROCESS_MEMORY_COUNTERS_EX*, presumably
+	// using the redundant size info to distinguish. But its prototype
+	// specifically accepts PROCESS_MEMORY_COUNTERS*, and since this is a
+	// classic-C API, PROCESS_MEMORY_COUNTERS_EX isn't a subclass. Cast the
+	// pointer.
+	GetProcessMemoryInfo(GetCurrentProcess(), PPROCESS_MEMORY_COUNTERS(&pmem), sizeof(pmem));
 
 	stats.add("Page Fault Count",              pmem.PageFaultCount);
 	stats.add("PeakWorkingSetSize KB",         pmem.PeakWorkingSetSize/1024);
-- 
cgit v1.2.3


From 9c147be92e81062f8f668b5d5c3331e8d1f395f7 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Fri, 8 Jul 2011 14:18:56 -0400
Subject: storm-899 and vwr-26095: correct xml to restore body parts accordian
 in appearance editor

---
 indra/newview/skins/default/xui/en/panel_cof_wearables.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml
index bbeb592e96..9e70706603 100644
--- a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml
+++ b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml
@@ -52,7 +52,7 @@
              multi_select="true"
              name="list_attachments"
              top="0"
-             width="311">
+             width="311"/>
         </accordion_tab>
         <accordion_tab
          layout="topleft"
-- 
cgit v1.2.3


From 72a52cb5de5be82b536d2c721bf69b3ac4dfc046 Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Fri, 8 Jul 2011 21:01:41 -0600
Subject: fix for STORM-1468: [crashhunters] pre-login crash at
 LLViewerWindow::LLViewerWindow(std::basic_string,std::allocator > const
 &,std::basic_string,std::allocator > const &,int,int,int,int,int,int)
 [secondlife-bin llviewerwindow.cpp]

---
 indra/newview/llappviewer.cpp                  |  2 +-
 indra/newview/llviewerwindow.cpp               | 32 +++++++++++++++-----------
 indra/newview/res/viewerRes.rc                 |  6 ++---
 indra/newview/skins/default/xui/en/strings.xml |  1 +
 4 files changed, 24 insertions(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index d2582d524d..8809b17468 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -4519,7 +4519,7 @@ void LLAppViewer::idleShutdown()
 
 void LLAppViewer::sendLogoutRequest()
 {
-	if(!mLogoutRequestSent)
+	if(!mLogoutRequestSent && gMessageSystem)
 	{
 		LLMessageSystem* msg = gMessageSystem;
 		msg->newMessageFast(_PREHASH_LogoutRequest);
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index b1441cc281..aed143b915 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1578,6 +1578,25 @@ LLViewerWindow::LLViewerWindow(
 		ignore_pixel_depth,
 		gSavedSettings.getBOOL("RenderDeferred") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled
 
+	if (NULL == mWindow)
+	{
+		LLSplashScreen::update(LLTrans::getString("StartupRequireDriverUpdate"));
+	
+		LL_WARNS("Window") << "Failed to create window, to be shutting Down, be sure your graphics driver is updated." << llendl ;
+
+		ms_sleep(5000) ; //wait for 5 seconds.
+
+		LLSplashScreen::update(LLTrans::getString("ShuttingDown"));
+#if LL_LINUX || LL_SOLARIS
+		llwarns << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly.  See README-linux.txt or README-solaris.txt for further information."
+				<< llendl;
+#else
+		LL_WARNS("Window") << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings"
+				<< LL_ENDL;
+#endif
+        LLAppViewer::instance()->fastQuit(1);
+	}
+	
 	if (!LLAppViewer::instance()->restoreErrorTrap())
 	{
 		LL_WARNS("Window") << " Someone took over my signal/exception handler (post createWindow)!" << LL_ENDL;
@@ -1593,19 +1612,6 @@ LLViewerWindow::LLViewerWindow(
 		gSavedSettings.setS32("FullScreenHeight",scr.mY);
     }
 
-	if (NULL == mWindow)
-	{
-		LLSplashScreen::update(LLTrans::getString("ShuttingDown"));
-#if LL_LINUX || LL_SOLARIS
-		llwarns << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly.  See README-linux.txt or README-solaris.txt for further information."
-				<< llendl;
-#else
-		LL_WARNS("Window") << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings"
-				<< LL_ENDL;
-#endif
-        LLAppViewer::instance()->fastQuit(1);
-	}
-	
 	// Get the real window rect the window was created with (since there are various OS-dependent reasons why
 	// the size of a window or fullscreen context may have been adjusted slightly...)
 	F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor");
diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc
index 38d04b4b5c..fefeaa9d11 100644
--- a/indra/newview/res/viewerRes.rc
+++ b/indra/newview/res/viewerRes.rc
@@ -62,12 +62,12 @@ IDI_LCD_LL_ICON         ICON                    "icon1.ico"
 // Dialog
 //
 
-SPLASHSCREEN DIALOG  32, 32, 144, 34
+SPLASHSCREEN DIALOG  32, 32, 194, 34
 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE
 FONT 8, "MS Sans Serif"
 BEGIN
     ICON            IDI_LL_ICON,IDC_STATIC,7,7,20,20
-    LTEXT           "Loading Second Life...",666,36,13,91,8
+    LTEXT           "Loading Second Life...",666,36,13,141,8
 END
 
 
@@ -82,7 +82,7 @@ BEGIN
     "SPLASHSCREEN", DIALOG
     BEGIN
         LEFTMARGIN, 7
-        RIGHTMARGIN, 137
+        RIGHTMARGIN, 187
         VERTGUIDE, 36
         TOPMARGIN, 7
         BOTTOMMARGIN, 27
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 71f48c833d..c107aee4ec 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -18,6 +18,7 @@
 	<string name="StartupClearingCache">Clearing cache...</string>
 	<string name="StartupInitializingTextureCache">Initializing Texture Cache...</string>
 	<string name="StartupInitializingVFS">Initializing VFS...</string>
+  <string name="StartupRequireDriverUpdate">Error: Please Update Your Graphics Driver!</string>
 
 	<!--  progress -->
 	<string name="ProgressRestoring">Restoring...</string>
-- 
cgit v1.2.3


From 607f60d6f6ddf18e69b5106bbb6ef31b72ba78f2 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 11 Jul 2011 10:57:14 -0400
Subject: CHOP-753: Add timestamp to LLMemoryInfo's LLSD stats block. For
 postprocessing these stats, we'll want the time at which they were captured.
 We'll want the current framerate too, but handle that at a higher level.

---
 indra/llcommon/llsys.cpp | 38 ++++++++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index b3ab5008fb..74a9a68dc8 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -51,6 +51,9 @@
 #include <boost/foreach.hpp>
 #include <boost/lexical_cast.hpp>
 #include <boost/range.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_float.hpp>
 
 using namespace llsd;
 
@@ -649,7 +652,24 @@ public:
 		mStats(LLSD::emptyArray())
 	{}
 
-	void add(const LLSD::String& name, LLSD::Integer value)
+	// Store every integer type as LLSD::Integer.
+	template <class T>
+	void add(const LLSD::String& name, const T& value,
+			 typename boost::enable_if<boost::is_integral<T> >::type* = 0)
+	{
+		mStats.append(LLSDArray(name)(LLSD::Integer(value)));
+	}
+
+	// Store every floating-point type as LLSD::Real.
+	template <class T>
+	void add(const LLSD::String& name, const T& value,
+			 typename boost::enable_if<boost::is_float<T> >::type* = 0)
+	{
+		mStats.append(LLSDArray(name)(LLSD::Real(value)));
+	}
+
+	// Hope that LLSD::Date values are sufficiently unambiguous.
+	void add(const LLSD::String& name, const LLSD::Date& value)
 	{
 		mStats.append(LLSDArray(name)(value));
 	}
@@ -847,9 +867,16 @@ void LLMemoryInfo::stream(std::ostream& s) const
 	// Now stream stats
 	BOOST_FOREACH(LLSD pair, inArray(mStatsArray))
 	{
-		s << pfx << std::setw(key_width+1) << (pair[0].asString() + ':')
-		  << ' '
-		  << std::setw(12) << pair[1].asInteger() << std::endl;
+		s << pfx << std::setw(key_width+1) << (pair[0].asString() + ':') << ' ';
+		if (pair[1].isInteger())
+			s << std::setw(12) << pair[1].asInteger();
+		else if (pair[1].isReal())
+			s << std::fixed << std::setprecision(1) << pair[1].asReal();
+		else if (pair[1].isDate())
+			pair[1].asDate().toStream(s);
+		else
+			s << pair[1];           // just use default LLSD formatting
+		s << std::endl;
 	}
 }
 
@@ -881,6 +908,9 @@ LLSD LLMemoryInfo::loadStatsArray()
 	// This implementation is derived from stream() code (as of 2011-06-29).
 	StatsArray stats;
 
+	// associate timestamp for analysis over time
+	stats.add("timestamp", LLDate::now());
+
 #if LL_WINDOWS
 	MEMORYSTATUSEX state;
 	state.dwLength = sizeof(state);
-- 
cgit v1.2.3


From 8fcda650a71d4784dcb24e86b3fc59ad15bc6a2d Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 11 Jul 2011 14:24:28 -0400
Subject: CHOP-753: Add classic-C-style diagnostics around popen("vm_stat"). On
 Mac, where LLMemoryInfo relies on a child process rather than any sort of
 internal system API, try to produce more informative LL_WARNS output if
 popen() fails to run vm_stat, or if vm_stat terminates with nonzero rc.

---
 indra/llcommon/llsys.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 58 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 74a9a68dc8..9390fc170c 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -68,6 +68,8 @@ using namespace llsd;
 #	include <sys/utsname.h>
 #	include <stdint.h>
 #	include <Carbon/Carbon.h>
+#   include <sys/wait.h>
+#   include <string.h>
 #elif LL_LINUX
 #	include <errno.h>
 #	include <sys/utsname.h>
@@ -979,11 +981,23 @@ LLSD LLMemoryInfo::loadStatsArray()
 	}
 
 	FILE* pout = popen("vm_stat 2>&1", "r");
-	if (! pout)
+	if (! pout)                     // popen() couldn't run vm_stat
 	{
-		LL_WARNS("LLMemoryInfo") << "Unable to collect vm_stat memory information" << LL_ENDL;
+		// Save errno right away.
+		int popen_errno(errno);
+		LL_WARNS("LLMemoryInfo") << "Unable to collect vm_stat memory information: ";
+		char buffer[256];
+		if (0 == strerror_r(popen_errno, buffer, sizeof(buffer)))
+		{
+			LL_CONT << buffer;
+		}
+		else
+		{
+			LL_CONT << "errno " << popen_errno;
+		}
+		LL_CONT << LL_ENDL;
 	}
-	else
+	else                            // popen() launched vm_stat
 	{
 		// Mach Virtual Memory Statistics: (page size of 4096 bytes)
 		// Pages free:					 462078.
@@ -1097,7 +1111,47 @@ LLSD LLMemoryInfo::loadStatsArray()
 				LL_WARNS("LLMemoryInfo") << "unrecognized vm_stat line: " << line << LL_ENDL;
 			}
 		}
-		fclose(pout);
+		int status(pclose(pout));
+		if (status == -1)           // pclose() couldn't retrieve rc
+		{
+			// Save errno right away.
+			int pclose_errno(errno);
+			// The ECHILD error happens so frequently that unless filtered,
+			// the warning below spams the log file. This is too bad, because
+			// sometimes the logic above fails to produce any output derived
+			// from vm_stat, but we've been unable to observe any specific
+			// error indicating the problem.
+			if (pclose_errno != ECHILD)
+			{
+				LL_WARNS("LLMemoryInfo") << "Unable to obtain vm_stat termination code: ";
+				char buffer[256];
+				if (0 == strerror_r(pclose_errno, buffer, sizeof(buffer)))
+				{
+					LL_CONT << buffer;
+				}
+				else
+				{
+					LL_CONT << "errno " << pclose_errno;
+				}
+				LL_CONT << LL_ENDL;
+			}
+		}
+		else                        // pclose() retrieved rc; analyze
+		{
+			if (WIFEXITED(status))
+			{
+				int rc(WEXITSTATUS(status));
+				if (rc != 0)
+				{
+					LL_WARNS("LLMemoryInfo") << "vm_stat terminated with rc " << rc << LL_ENDL;
+				}
+			}
+			else if (WIFSIGNALED(status))
+			{
+				LL_WARNS("LLMemoryInfo") << "vm_stat terminated by signal " << WTERMSIG(status)
+										 << LL_ENDL;
+			}
+		}
 	}
 
 #elif LL_SOLARIS
-- 
cgit v1.2.3


From 90ceac118cc8f437587d33ba95b10aae84a5ecac Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Mon, 11 Jul 2011 14:17:57 -0600
Subject: more fix for STORM-1468: [crashhunters] pre-login crash at
 LLViewerWindow::LLViewerWindow(std::basic_string,std::allocator > const
 &,std::basic_string,std::allocator > const &,int,int,int,int,int,int)
 [secondlife-bin llviewerwindow.cpp]

---
 indra/newview/res/viewerRes.rc                 | 6 +++---
 indra/newview/skins/default/xui/en/strings.xml | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc
index fefeaa9d11..a53dece422 100644
--- a/indra/newview/res/viewerRes.rc
+++ b/indra/newview/res/viewerRes.rc
@@ -62,12 +62,12 @@ IDI_LCD_LL_ICON         ICON                    "icon1.ico"
 // Dialog
 //
 
-SPLASHSCREEN DIALOG  32, 32, 194, 34
+SPLASHSCREEN DIALOG  32, 32, 264, 34
 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE
 FONT 8, "MS Sans Serif"
 BEGIN
     ICON            IDI_LL_ICON,IDC_STATIC,7,7,20,20
-    LTEXT           "Loading Second Life...",666,36,13,141,8
+    LTEXT           "Loading Second Life...",666,36,13,211,8
 END
 
 
@@ -82,7 +82,7 @@ BEGIN
     "SPLASHSCREEN", DIALOG
     BEGIN
         LEFTMARGIN, 7
-        RIGHTMARGIN, 187
+        RIGHTMARGIN, 257
         VERTGUIDE, 36
         TOPMARGIN, 7
         BOTTOMMARGIN, 27
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index c107aee4ec..a679e2e85d 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -18,7 +18,7 @@
 	<string name="StartupClearingCache">Clearing cache...</string>
 	<string name="StartupInitializingTextureCache">Initializing Texture Cache...</string>
 	<string name="StartupInitializingVFS">Initializing VFS...</string>
-  <string name="StartupRequireDriverUpdate">Error: Please Update Your Graphics Driver!</string>
+  <string name="StartupRequireDriverUpdate">Graphics Initialization Failed. Please Update Your Graphics Driver!</string>
 
 	<!--  progress -->
 	<string name="ProgressRestoring">Restoring...</string>
-- 
cgit v1.2.3


From 4e2355036358ed712dd7df2668ec705931ad13a1 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 12 Jul 2011 13:34:09 -0400
Subject: CHOP-753: make getAvailableMemoryKB() only load data on Windows. (per
 Monty code review) Other platforms return -1 anyway, so don't need to call
 load methods.

---
 indra/llcommon/llsys.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 9390fc170c..aa71590eae 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -755,11 +755,11 @@ U32 LLMemoryInfo::getPhysicalMemoryClamped() const
 //static
 void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb)
 {
+#if LL_WINDOWS
 	// Sigh, this shouldn't be a static method, then we wouldn't have to
 	// reload this data separately from refresh()
 	LLSD statsMap(loadStatsMap(loadStatsArray()));
 
-#if LL_WINDOWS
 	avail_physical_mem_kb = statsMap["Avail Physical KB"].asInteger();
 	avail_virtual_mem_kb  = statsMap["Avail Virtual KB"].asInteger();
 
-- 
cgit v1.2.3


From e58a0e9b26dc374155b90a8f42c3a5b09e8ed1f7 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 12 Jul 2011 14:34:31 -0400
Subject: CHOP-753: Defend against boost::regex exceptions. (per Monty code
 review) Explain why we intentionally don't suppress exceptions from
 boost::regex objects constructed with string literals. Catch
 std::runtime_error from boost::regex_search() and boost::regex_match(); log
 and return false.

---
 indra/llcommon/llsys.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 46 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index aa71590eae..ebdef56c2a 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -70,11 +70,13 @@ using namespace llsd;
 #	include <Carbon/Carbon.h>
 #   include <sys/wait.h>
 #   include <string.h>
+#   include <stdexcept>
 #elif LL_LINUX
 #	include <errno.h>
 #	include <sys/utsname.h>
 #	include <unistd.h>
 #	include <sys/sysinfo.h>
+#   include <stdexcept>
 const char MEMINFO_FILE[] = "/proc/meminfo";
 #elif LL_SOLARIS
 #	include <stdio.h>
@@ -682,6 +684,38 @@ private:
 	LLSD mStats;
 };
 
+// Wrap boost::regex_match() with a function that doesn't throw.
+template <typename S, typename M, typename R>
+static bool regex_match_no_exc(const S& string, M& match, const R& regex)
+{
+    try
+    {
+        return boost::regex_match(string, match, regex);
+    }
+    catch (const std::runtime_error& e)
+    {
+        LL_WARNS("LLMemoryInfo") << "error matching with '" << regex.str() << "': "
+                                 << e.what() << ":\n'" << string << "'" << LL_ENDL;
+        return false;
+    }
+}
+
+// Wrap boost::regex_search() with a function that doesn't throw.
+template <typename S, typename M, typename R>
+static bool regex_search_no_exc(const S& string, M& match, const R& regex)
+{
+    try
+    {
+        return boost::regex_search(string, match, regex);
+    }
+    catch (const std::runtime_error& e)
+    {
+        LL_WARNS("LLMemoryInfo") << "error searching with '" << regex.str() << "': "
+                                 << e.what() << ":\n'" << string << "'" << LL_ENDL;
+        return false;
+    }
+}
+
 LLMemoryInfo::LLMemoryInfo()
 {
 	refresh();
@@ -1012,6 +1046,10 @@ LLSD LLMemoryInfo::loadStatsArray()
 		// Pageouts:					  41759.
 		// Object cache: 841598 hits of 7629869 lookups (11% hit rate)
 
+		// Intentionally don't pass the boost::no_except flag. These
+		// boost::regex objects are constructed with string literals, so they
+		// should be valid every time. If they become invalid, we WANT an
+		// exception, hopefully even before the dev checks in.
 		boost::regex pagesize_rx("\\(page size of ([0-9]+) bytes\\)");
 		boost::regex stat_rx("(.+): +([0-9]+)\\.");
 		boost::regex cache_rx("Object cache: ([0-9]+) hits of ([0-9]+) lookups "
@@ -1031,7 +1069,7 @@ LLSD LLMemoryInfo::loadStatsArray()
 				line[--linelen] = '\0';
 			}
 			LL_DEBUGS("LLMemoryInfo") << line << LL_ENDL;
-			if (boost::regex_search(line, matched, pagesize_rx))
+			if (regex_search_no_exc(line, matched, pagesize_rx))
 			{
 				// "Mach Virtual Memory Statistics: (page size of 4096 bytes)"
 				std::string pagesize_str(matched[1].first, matched[1].second);
@@ -1049,7 +1087,7 @@ LLSD LLMemoryInfo::loadStatsArray()
 				}
 				stats.add("page size", pagesizekb);
 			}
-			else if (boost::regex_match(line, matched, stat_rx))
+			else if (regex_match_no_exc(line, matched, stat_rx))
 			{
 				// e.g. "Pages free:					 462078."
 				// Strip double-quotes off certain statistic names
@@ -1084,7 +1122,7 @@ LLSD LLMemoryInfo::loadStatsArray()
 					stats.add(kbkey, value * pagesizekb);
 				}
 			}
-			else if (boost::regex_match(line, matched, cache_rx))
+			else if (regex_match_no_exc(line, matched, cache_rx))
 			{
 				// e.g. "Object cache: 841598 hits of 7629869 lookups (11% hit rate)"
 				static const char* cache_keys[] = { "cache hits", "cache lookups", "cache hit%" };
@@ -1185,6 +1223,10 @@ LLSD LLMemoryInfo::loadStatsArray()
 		// DirectMap4k:		 434168 kB
 		// DirectMap2M:		 477184 kB
 
+		// Intentionally don't pass the boost::no_except flag. This
+		// boost::regex object is constructed with a string literal, so it
+		// should be valid every time. If it becomes invalid, we WANT an
+		// exception, hopefully even before the dev checks in.
 		boost::regex stat_rx("(.+): +([0-9]+)( kB)?");
 		boost::smatch matched;
 
@@ -1192,7 +1234,7 @@ LLSD LLMemoryInfo::loadStatsArray()
 		while (std::getline(meminfo, line))
 		{
 			LL_DEBUGS("LLMemoryInfo") << line << LL_ENDL;
-			if (boost::regex_match(line, matched, stat_rx))
+			if (regex_match_no_exc(line, matched, stat_rx))
 			{
 				// e.g. "MemTotal:		4108424 kB"
 				LLSD::String key(matched[1].first, matched[1].second);
-- 
cgit v1.2.3


From 42daa3497b6626cbb5f32ba54162558cd025069b Mon Sep 17 00:00:00 2001
From: Aaron Stone <stone@lindenlab.com>
Date: Tue, 12 Jul 2011 15:48:02 -0700
Subject: STORM-1482 The Viewer shouldn't overwrite the crash behavior
 settings, some cleanups to the crash reporters, and the ability to use --set
 GroupName.SettingName to set parameters outside of the (default) Global
 settings group.

---
 indra/linux_crash_logger/linux_crash_logger.cpp    | 14 +++-
 indra/linux_crash_logger/llcrashloggerlinux.cpp    |  2 -
 indra/llcommon/indra_constants.h                   |  2 -
 indra/llcrashlogger/llcrashlogger.cpp              | 80 ++++++++++++---------
 indra/llcrashlogger/llcrashlogger.h                | 11 ---
 .../mac_crash_logger/CrashReporter.nib/objects.xib |  2 +-
 indra/mac_crash_logger/llcrashloggermac.cpp        |  5 +-
 indra/mac_crash_logger/mac_crash_logger.cpp        | 15 ++--
 indra/newview/app_settings/cmd_line.xml            | 13 +---
 indra/newview/app_settings/settings_files.xml      |  5 +-
 indra/newview/llappviewer.cpp                      | 81 ++++++++++------------
 indra/newview/llappviewerlinux.cpp                 |  2 +-
 indra/newview/llappviewerwin32.cpp                 |  2 +-
 indra/newview/llfloaterpreference.cpp              |  5 +-
 indra/newview/llviewercontrol.cpp                  |  4 +-
 .../default/xui/en/panel_preferences_setup.xml     |  2 +-
 indra/win_crash_logger/llcrashloggerwindows.cpp    |  5 +-
 indra/win_crash_logger/llcrashloggerwindows.h      |  1 -
 indra/win_crash_logger/win_crash_logger.cpp        | 35 ++--------
 19 files changed, 125 insertions(+), 161 deletions(-)

(limited to 'indra')

diff --git a/indra/linux_crash_logger/linux_crash_logger.cpp b/indra/linux_crash_logger/linux_crash_logger.cpp
index 8beae555fb..99d0ad7e14 100644
--- a/indra/linux_crash_logger/linux_crash_logger.cpp
+++ b/indra/linux_crash_logger/linux_crash_logger.cpp
@@ -24,16 +24,24 @@
  * $/LicenseInfo$
  */
 
+#include "linden_common.h"
 #include "llcrashloggerlinux.h"
 
 int main(int argc, char **argv)
 {
+	llinfos << "Starting crash reporter." << llendl;
+
 	LLCrashLoggerLinux app;
 	app.parseCommandOptions(argc, argv);
-	app.init();
+
+	if (! app.init())
+	{
+		llwarns << "Unable to initialize application." << llendl;
+		return 1;
+	}
+
 	app.mainLoop();
 	app.cleanup();
+	llinfos << "Crash reporter finished normally." << llendl;
 	return 0;
 }
-
-
diff --git a/indra/linux_crash_logger/llcrashloggerlinux.cpp b/indra/linux_crash_logger/llcrashloggerlinux.cpp
index 7449c6426f..7316717193 100644
--- a/indra/linux_crash_logger/llcrashloggerlinux.cpp
+++ b/indra/linux_crash_logger/llcrashloggerlinux.cpp
@@ -30,8 +30,6 @@
 
 #include "linden_common.h"
 
-#include "boost/tokenizer.hpp"
-
 #include "indra_constants.h"	// CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME
 #include "llerror.h"
 #include "llfile.h"
diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h
index d0f287657e..0745696ef3 100644
--- a/indra/llcommon/indra_constants.h
+++ b/indra/llcommon/indra_constants.h
@@ -387,8 +387,6 @@ const S32 MAP_SIM_RETURN_NULL_SIMS 	= 0x00010000;
 const S32 MAP_SIM_PRELUDE 			= 0x00020000;
 
 // Crash reporter behavior
-const char* const CRASH_SETTINGS_FILE = "settings_crash_behavior.xml";
-const char* const CRASH_BEHAVIOR_SETTING = "CrashSubmitBehavior";
 const S32 CRASH_BEHAVIOR_ASK = 0;
 const S32 CRASH_BEHAVIOR_ALWAYS_SEND = 1;
 const S32 CRASH_BEHAVIOR_NEVER_SEND = 2;
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index 68e45f36e4..3fbaf61991 100644
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -31,10 +31,12 @@
 #include "llcrashlogger.h"
 #include "linden_common.h"
 #include "llstring.h"
-#include "indra_constants.h"	// CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME
+#include "indra_constants.h"	// CRASH_BEHAVIOR_...
 #include "llerror.h"
+#include "llerrorcontrol.h"
 #include "lltimer.h"
 #include "lldir.h"
+#include "llfile.h"
 #include "llsdserialize.h"
 #include "lliopipe.h"
 #include "llpumpio.h"
@@ -54,7 +56,7 @@ public:
 
 	virtual void error(U32 status, const std::string& reason)
 	{
-		gBreak = true;		
+		gBreak = true;
 	}
 
 	virtual void result(const LLSD& content)
@@ -64,19 +66,6 @@ public:
 	}
 };
 
-bool LLCrashLoggerText::mainLoop()
-{
-	std::cout << "Entering main loop" << std::endl;
-	sendCrashLogs();
-	return true;	
-}
-
-void LLCrashLoggerText::updateApplication(const std::string& message)
-{
-	LLCrashLogger::updateApplication(message);
-	std::cout << message << std::endl;
-}
-
 LLCrashLogger::LLCrashLogger() :
 	mCrashBehavior(CRASH_BEHAVIOR_ASK),
 	mCrashInPreviousExec(false),
@@ -281,26 +270,41 @@ LLSD LLCrashLogger::constructPostData()
 	return mCrashInfo;
 }
 
+const char* const CRASH_SETTINGS_FILE = "settings_crash_behavior.xml";
+
 S32 LLCrashLogger::loadCrashBehaviorSetting()
 {
 	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
 
 	mCrashSettings.loadFromFile(filename);
-		
-	S32 value = mCrashSettings.getS32(CRASH_BEHAVIOR_SETTING);
-	
-	if (value < CRASH_BEHAVIOR_ASK || CRASH_BEHAVIOR_NEVER_SEND < value) return CRASH_BEHAVIOR_ASK;
 
-	return value;
+	S32 value = mCrashSettings.getS32("CrashSubmitBehavior");
+
+	switch (value)
+	{
+	case CRASH_BEHAVIOR_NEVER_SEND:
+		return CRASH_BEHAVIOR_NEVER_SEND;
+	case CRASH_BEHAVIOR_ALWAYS_SEND:
+		return CRASH_BEHAVIOR_ALWAYS_SEND;
+	}
+
+	return CRASH_BEHAVIOR_ASK;
 }
 
 bool LLCrashLogger::saveCrashBehaviorSetting(S32 crash_behavior)
 {
-	if (crash_behavior != CRASH_BEHAVIOR_ASK && crash_behavior != CRASH_BEHAVIOR_ALWAYS_SEND) return false;
+	switch (crash_behavior)
+	{
+	case CRASH_BEHAVIOR_ASK:
+	case CRASH_BEHAVIOR_NEVER_SEND:
+	case CRASH_BEHAVIOR_ALWAYS_SEND:
+		break;
+	default:
+		return false;
+	}
 
-	mCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, crash_behavior);
+	mCrashSettings.setS32("CrashSubmitBehavior", crash_behavior);
 	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
-
 	mCrashSettings.saveToFile(filename, FALSE);
 
 	return true;
@@ -309,14 +313,13 @@ bool LLCrashLogger::saveCrashBehaviorSetting(S32 crash_behavior)
 bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg, int retries, int timeout)
 {
 	gBreak = false;
-	std::string status_message;
 	for(int i = 0; i < retries; ++i)
 	{
-		status_message = llformat("%s, try %d...", msg.c_str(), i+1);
+		updateApplication(llformat("%s, try %d...", msg.c_str(), i+1));
 		LLHTTPClient::post(host, data, new LLCrashLoggerResponder(), timeout);
 		while(!gBreak)
 		{
-			updateApplication(status_message);
+			updateApplication(); // No new message, just pump the IO
 		}
 		if(gSent)
 		{
@@ -336,7 +339,7 @@ bool LLCrashLogger::sendCrashLogs()
 	updateApplication("Sending reports...");
 
 	std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
-															   "SecondLifeCrashReport");
+														   "SecondLifeCrashReport");
 	std::string report_file = dump_path + ".log";
 
 	std::ofstream out_file(report_file.c_str());
@@ -365,6 +368,7 @@ void LLCrashLogger::updateApplication(const std::string& message)
 {
 	gServicePump->pump();
     gServicePump->callback();
+	if (!message.empty()) llinfos << message << llendl;
 }
 
 bool LLCrashLogger::init()
@@ -374,11 +378,24 @@ bool LLCrashLogger::init()
 	// We assume that all the logs we're looking for reside on the current drive
 	gDirUtilp->initAppDirs("SecondLife");
 
+	LLError::initForApplication(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
+
 	// Default to the product name "Second Life" (this is overridden by the -name argument)
 	mProductName = "Second Life";
+
+	// Rename current log file to ".old"
+	std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log.old");
+	std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log");
+	LLFile::rename(log_file.c_str(), old_log_file.c_str());
+
+	// Set the log file to crashreport.log
+	LLError::logToFile(log_file);
 	
-	mCrashSettings.declareS32(CRASH_BEHAVIOR_SETTING, CRASH_BEHAVIOR_ASK, "Controls behavior when viewer crashes "
-		"(0 = ask before sending crash report, 1 = always send crash report, 2 = never send crash report)");
+	mCrashSettings.declareS32("CrashSubmitBehavior", CRASH_BEHAVIOR_ASK,
+							  "Controls behavior when viewer crashes "
+							  "(0 = ask before sending crash report, "
+							  "1 = always send crash report, "
+							  "2 = never send crash report)");
 
 	llinfos << "Loading crash behavior setting" << llendl;
 	mCrashBehavior = loadCrashBehaviorSetting();
@@ -394,10 +411,11 @@ bool LLCrashLogger::init()
 	gServicePump->prime(gAPRPoolp);
 	LLHTTPClient::setPump(*gServicePump);
 
-	//If we've opened the crash logger, assume we can delete the marker file if it exists	
+	//If we've opened the crash logger, assume we can delete the marker file if it exists
 	if( gDirUtilp )
 	{
-		std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.exec_marker");
+		std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
+																 "SecondLife.exec_marker");
 		LLAPRFile::remove( marker_file );
 	}
 	
diff --git a/indra/llcrashlogger/llcrashlogger.h b/indra/llcrashlogger/llcrashlogger.h
index a5daa74247..5d0cb5931c 100644
--- a/indra/llcrashlogger/llcrashlogger.h
+++ b/indra/llcrashlogger/llcrashlogger.h
@@ -66,15 +66,4 @@ protected:
 	bool mSentCrashLogs;
 };
 
-class LLCrashLoggerText : public LLCrashLogger
-{
-public:
-	LLCrashLoggerText(void) {}
-	~LLCrashLoggerText(void) {}
-
-	virtual bool mainLoop();
-	virtual void updateApplication(const std::string& message = LLStringUtil::null);
-};
-
-
 #endif //LLCRASHLOGGER_H
diff --git a/indra/mac_crash_logger/CrashReporter.nib/objects.xib b/indra/mac_crash_logger/CrashReporter.nib/objects.xib
index 634d1c5321..32647391b6 100644
--- a/indra/mac_crash_logger/CrashReporter.nib/objects.xib
+++ b/indra/mac_crash_logger/CrashReporter.nib/objects.xib
@@ -15,7 +15,7 @@
       <string name="bounds">414 390 434 487 </string>
     </object>
     <object class="IBCarbonStaticText" id="181">
-      <string name="title">Second Life appears to have crashed or frozen the last time it ran.&#10;&#10;This crash reporter collects information about your computer&apos;s hardware configuration, operating system, and some Second Life logs, all of which are used for debugging purposes only.&#10;&#10;In the space below, please briefly describe what you were doing or trying to do just prior to the crash. Thank you for your help!&#10;&#10;This report is NOT read by Customer Support. If you have billing or other questions, please go to: http://www.secondlife.com/support/&#10;&#10;If you don&apos;t wish to send Linden Lab a crash report, press Cancel.&#10;</string>
+      <string name="title">Second Life appears to have crashed or frozen the last time it ran.&#10;&#10;This crash reporter collects information about your computer&apos;s hardware configuration, operating system, and some Second Life logs, all of which are used for debugging purposes only.&#10;&#10;In the space below, please briefly describe what you were doing or trying to do just prior to the crash. Thank you for your help!&#10;&#10;This report is NOT read by Customer Support. If you have billing or other questions, please go to: http://www.secondlife.com/support/&#10;&#10;If you don&apos;t wish to send Linden Lab a crash report, press Don&apos;t Send.&#10;</string>
       <string name="bounds">20 20 231 487 </string>
     </object>
     <object class="IBCarbonWindow" id="166">
diff --git a/indra/mac_crash_logger/llcrashloggermac.cpp b/indra/mac_crash_logger/llcrashloggermac.cpp
index bec8cce04e..b555e92b96 100644
--- a/indra/mac_crash_logger/llcrashloggermac.cpp
+++ b/indra/mac_crash_logger/llcrashloggermac.cpp
@@ -29,9 +29,6 @@
 
 #include <Carbon/Carbon.h>
 #include <iostream>
-#include <sstream>
-
-#include "boost/tokenizer.hpp"
 
 #include "indra_constants.h"	// CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME
 #include "llerror.h"
@@ -247,7 +244,7 @@ bool LLCrashLoggerMac::mainLoop()
 
 void LLCrashLoggerMac::updateApplication(const std::string& message)
 {
-	LLCrashLogger::updateApplication();
+	LLCrashLogger::updateApplication(message);
 }
 
 bool LLCrashLoggerMac::cleanup()
diff --git a/indra/mac_crash_logger/mac_crash_logger.cpp b/indra/mac_crash_logger/mac_crash_logger.cpp
index 20b491c401..6571b35241 100644
--- a/indra/mac_crash_logger/mac_crash_logger.cpp
+++ b/indra/mac_crash_logger/mac_crash_logger.cpp
@@ -25,22 +25,23 @@
  */
 
 #include "linden_common.h"
-
 #include "llcrashloggermac.h"
 
 int main(int argc, char **argv)
 {
-	//time(&gLaunchTime);
-	
-	llinfos << "Starting Second Life Viewer Crash Reporter" << llendl;
+	llinfos << "Starting crash reporter." << llendl;
 
 	LLCrashLoggerMac app;
 	app.parseCommandOptions(argc, argv);
-	if(!app.init())
+
+	if (! app.init())
 	{
-		return 0;
+		llwarns << "Unable to initialize application." << llendl;
+		return 1;
 	}
+
 	app.mainLoop();
-		
+	app.cleanup();
+	llinfos << "Crash reporter finished normally." << llendl;
 	return 0;
 }
diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml
index 89e5949fbe..15434f2b8f 100644
--- a/indra/newview/app_settings/cmd_line.xml
+++ b/indra/newview/app_settings/cmd_line.xml
@@ -220,8 +220,7 @@
     <map>
       <key>desc</key>
       <string>Set the detail level. 
-              0 - low, 1 - medium, 2 - high, 3 - ultra
-       </string>
+0 - low, 1 - medium, 2 - high, 3 - ultra</string>
       <key>count</key>
       <integer>1</integer>
     </map>
@@ -229,10 +228,7 @@
     <key>setdefault</key>
     <map>
       <key>desc</key>
-      <string> specify the value of a particular
-               configuration variable which can be
-               overridden by settings.xml
-      </string>
+      <string>specify the value of a particular configuration variable which can be overridden by settings.xml.</string>
       <key>count</key>
       <integer>2</integer>
       <!-- Special case. Mapped to settings procedurally. -->
@@ -241,10 +237,7 @@
     <key>set</key>
     <map>
       <key>desc</key>
-      <string> specify the value of a particular
-               configuration variable that
-               overrides all other settings
-      </string>
+      <string>specify the value of a particular configuration variable that overrides all other settings.</string>
       <key>count</key>
       <integer>2</integer>
       <key>compose</key>
diff --git a/indra/newview/app_settings/settings_files.xml b/indra/newview/app_settings/settings_files.xml
index 079a54f957..bfc09286e3 100644
--- a/indra/newview/app_settings/settings_files.xml
+++ b/indra/newview/app_settings/settings_files.xml
@@ -20,7 +20,8 @@
           file_name="settings.xml"
           file_name_setting="ClientSettingsFile"/>
     <file name="CrashSettings"
-          file_name="settings_crash_behavior"/>
+          file_name="settings_crash_behavior.xml"
+          file_name_setting="CrashSettingsFile"/>
     <file name="Warnings"
           file_name="ignorable_dialogs.xml"
           file_name_setting="WarningSettingsFile"/>
@@ -61,4 +62,4 @@
           file_name="colors.xml"
           file_name_setting="SkinningSettingsFile"/>
   </group>
-</settings_files>
\ No newline at end of file
+</settings_files>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 1d9519d675..1ce92c689d 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -468,18 +468,6 @@ void request_initial_instant_messages()
 	}
 }
 
-// A settings system callback for CrashSubmitBehavior
-bool handleCrashSubmitBehaviorChanged(const LLSD& newvalue)
-{
-	S32 cb = newvalue.asInteger();
-	const S32 NEVER_SUBMIT_REPORT = 2;
-	if(cb == NEVER_SUBMIT_REPORT)
-	{
-		LLAppViewer::instance()->destroyMainloopTimeout();
-	}
-	return true;
-}
-
 // Use these strictly for things that are constructed at startup,
 // or for things that are performance critical.  JC
 static void settings_to_globals()
@@ -611,9 +599,6 @@ bool LLAppViewer::sendURLToOtherInstance(const std::string& url)
 // Static members.
 // The single viewer app.
 LLAppViewer* LLAppViewer::sInstance = NULL;
-
-const std::string LLAppViewer::sGlobalSettingsName = "Global"; 
-
 LLTextureCache* LLAppViewer::sTextureCache = NULL; 
 LLImageDecodeThread* LLAppViewer::sImageDecodeThread = NULL; 
 LLTextureFetch* LLAppViewer::sTextureFetch = NULL; 
@@ -771,16 +756,6 @@ bool LLAppViewer::init()
 	LL_INFOS("InitInfo") << "J2C Engine is: " << LLImageJ2C::getEngineInfo() << LL_ENDL;
 	LL_INFOS("InitInfo") << "libcurl version is: " << LLCurl::getVersionString() << LL_ENDL;
 
-	// Get the single value from the crash settings file, if it exists
-	std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
-	gCrashSettings.loadFromFile(crash_settings_filename);
-	if(gSavedSettings.getBOOL("IgnoreAllNotifications"))
-	{
-		gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, CRASH_BEHAVIOR_ALWAYS_SEND);
-		gCrashSettings.saveToFile(crash_settings_filename, FALSE);
-	}
-	LL_INFOS("InitInfo") << "Crash settings done." << LL_ENDL ;
-
 	/////////////////////////////////////////////////
 	// OS-specific login dialogs
 	/////////////////////////////////////////////////
@@ -1055,7 +1030,7 @@ bool LLAppViewer::init()
 	//EXT-7013 - On windows for some locale (Japanese) standard 
 	//datetime formatting functions didn't support some parameters such as "weekday".
 	//Names for days and months localized in xml are also useful for Polish locale(STORM-107).
-	std::string language = LLControlGroup::getInstance(sGlobalSettingsName)->getString("Language");
+	std::string language = gSavedSettings.getString("Language");
 	if(language == "ja" || language == "pl")
 	{
 		LLStringOps::setupWeekDaysNames(LLTrans::getString("dateTimeWeekdaysNames"));
@@ -1706,10 +1681,6 @@ bool LLAppViewer::cleanup()
 		llinfos << "Saved settings" << llendflush;
 	}
 
-	std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
-	// save all settings, even if equals defaults
-	gCrashSettings.saveToFile(crash_settings_filename, FALSE);
-
 	std::string warnings_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Warnings"));
 	gWarningSettings.saveToFile(warnings_settings_filename, TRUE);
 
@@ -1839,7 +1810,6 @@ bool LLAppViewer::cleanup()
 	
 	gSavedSettings.cleanup();
 	LLUIColorTable::instance().clear();
-	gCrashSettings.cleanup();
 
 	LLWatchdog::getInstance()->cleanup();
 
@@ -1982,7 +1952,6 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
 		llerrs << "Invalid settings location list" << llendl;
 	}
 
-	LLControlGroup* global_settings = LLControlGroup::getInstance(sGlobalSettingsName);  
 	for(LLInitParam::ParamIterator<SettingsGroup>::const_iterator it = mSettingsLocationList->groups.begin(), end_it = mSettingsLocationList->groups.end();
 		it != end_it;
 		++it)
@@ -2015,11 +1984,15 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
 			std::string full_settings_path;
 
 			if (file_it->file_name_setting.isProvided() 
-				&& global_settings->controlExists(file_it->file_name_setting))
+				&& gSavedSettings.controlExists(file_it->file_name_setting))
 			{
 				// try to find filename stored in file_name_setting control
-				full_settings_path = global_settings->getString(file_it->file_name_setting);
-				if (!gDirUtilp->fileExists(full_settings_path))
+				full_settings_path = gSavedSettings.getString(file_it->file_name_setting);
+				if (full_settings_path.empty())
+				{
+					continue;
+				}
+				else if (!gDirUtilp->fileExists(full_settings_path))
 				{
 					// search in default path
 					full_settings_path = gDirUtilp->getExpandedFilename((ELLPath)path_index, full_settings_path);
@@ -2165,8 +2138,6 @@ bool LLAppViewer::initConfiguration()
 	gSavedSettings.setS32("WatchdogEnabled", 0);
 #endif
 	
-	gCrashSettings.getControl(CRASH_BEHAVIOR_SETTING)->getSignal()->connect(boost::bind(&handleCrashSubmitBehaviorChanged, _2));	
-
 	// These are warnings that appear on the first experience of that condition.
 	// They are already set in the settings_default.xml file, but still need to be added to LLFirstUse
 	// for disable/reset ability
@@ -2297,15 +2268,33 @@ bool LLAppViewer::initConfiguration()
             {
                 const std::string& name = *itr;
                 const std::string& value = *(++itr);
-				LLControlVariable* c = LLControlGroup::getInstance(sGlobalSettingsName)->getControl(name);
-                if(c)
+                std::string name_part;
+                std::string group_part;
+				LLControlVariable* control = NULL;
+
+				// Name can be further split into ControlGroup.Name, with the default control group being Global
+				size_t pos = name.find('.');
+				if (pos != std::string::npos)
+				{
+					group_part = name.substr(0, pos);
+					name_part = name.substr(pos+1);
+					llinfos << "Setting " << group_part << "." << name_part << " to " << value << llendl;
+					LLControlGroup* g = LLControlGroup::getInstance(group_part);
+					if (g) control = g->getControl(name_part);
+				}
+				else
+				{
+					llinfos << "Setting Global." << name << " to " << value << llendl;
+					control = gSavedSettings.getControl(name);
+				}
+
+                if (control)
                 {
-                    c->setValue(value, false);
+                    control->setValue(value, false);
                 }
                 else
                 {
-                    llwarns << "'--set' specified with unknown setting: '"
-                        << name << "'." << llendl;
+					llwarns << "Failed --set " << name << ": setting name unknown." << llendl;
                 }
             }
         }
@@ -2762,7 +2751,8 @@ void LLAppViewer::checkForCrash(void)
         // Pop up a freeze or crash warning dialog
         //
         S32 choice;
-        if(gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING) == CRASH_BEHAVIOR_ASK)
+	const S32 cb = gCrashSettings.getS32("CrashSubmitBehavior");
+        if(cb == CRASH_BEHAVIOR_ASK)
         {
             std::ostringstream msg;
 			msg << LLTrans::getString("MBFrozenCrashed");
@@ -2771,7 +2761,7 @@ void LLAppViewer::checkForCrash(void)
                                   alert,
                                   OSMB_YESNO);
         } 
-        else if(gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING) == CRASH_BEHAVIOR_NEVER_SEND)
+        else if(cb == CRASH_BEHAVIOR_NEVER_SEND)
         {
             choice = OSBTN_NO;
         }
@@ -2828,7 +2818,6 @@ bool LLAppViewer::initWindow()
 	LL_INFOS("AppInit") << "gViewerwindow created." << LL_ENDL;
 
 	// Need to load feature table before cheking to start watchdog.
-	const S32 NEVER_SUBMIT_REPORT = 2;
 	bool use_watchdog = false;
 	int watchdog_enabled_setting = gSavedSettings.getS32("WatchdogEnabled");
 	if(watchdog_enabled_setting == -1)
@@ -2841,7 +2830,7 @@ bool LLAppViewer::initWindow()
 		use_watchdog = bool(watchdog_enabled_setting);
 	}
 
-	bool send_reports = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING) != NEVER_SUBMIT_REPORT;
+	bool send_reports = gCrashSettings.getS32("CrashSubmitBehavior") != CRASH_BEHAVIOR_NEVER_SEND;
 	if(use_watchdog && send_reports)
 	{
 		LLWatchdog::getInstance()->init(watchdog_killer_callback);
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index 714e0e6163..08d4f49147 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -361,7 +361,7 @@ void LLAppViewerLinux::handleCrashReporting(bool reportFreeze)
 	}
 	else
 	{
-		const S32 cb = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING);
+		const S32 cb = gCrashSettings.getS32("CrashSubmitBehavior");
 
 		// Always generate the report, have the logger do the asking, and
 		// don't wait for the logger before exiting (-> total cleanup).
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 445bd208ef..9280234ac3 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -518,7 +518,7 @@ void LLAppViewerWin32::handleCrashReporting(bool reportFreeze)
 	}
 	else
 	{
-		S32 cb = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING);
+		S32 cb = gCrashSettings.getS32("CrashSubmitBehavior");
 		if(cb != CRASH_BEHAVIOR_NEVER_SEND)
 		{
 			_spawnl(_P_NOWAIT, exe_path.c_str(), arg_str, NULL);
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 7848484ac6..5fd262a720 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -751,10 +751,7 @@ void LLFloaterPreference::onBtnOK()
 		closeFloater(false);
 
 		LLUIColorTable::instance().saveUserSettings();
-		gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
-		std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
-		// save all settings, even if equals defaults
-		gCrashSettings.saveToFile(crash_settings_filename, FALSE);
+		gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
 	}
 	else
 	{
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 87ca80260f..b87ca1eaec 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -566,7 +566,7 @@ bool toggle_show_object_render_cost(const LLSD& newvalue)
 	return true;
 }
 
-void toggle_updater_service_active(LLControlVariable* control, const LLSD& new_value)
+void toggle_updater_service_active(const LLSD& new_value)
 {
     if(new_value.asInteger())
     {
@@ -735,7 +735,7 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("ShowNavbarFavoritesPanel")->getSignal()->connect(boost::bind(&toggle_show_favorites_panel, _2));
 	gSavedSettings.getControl("ShowMiniLocationPanel")->getSignal()->connect(boost::bind(&toggle_show_mini_location_panel, _2));
 	gSavedSettings.getControl("ShowObjectRenderingCost")->getSignal()->connect(boost::bind(&toggle_show_object_render_cost, _2));
-	gSavedSettings.getControl("UpdaterServiceSetting")->getSignal()->connect(&toggle_updater_service_active);
+	gSavedSettings.getControl("UpdaterServiceSetting")->getSignal()->connect(boost::bind(&toggle_updater_service_active, _2));
 	gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2));
 	gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2));
 }
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
index 1c22a5c02e..e639f0dc9d 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -268,7 +268,7 @@
      height="23"
      layout="topleft"
      left_delta="50"
-	 top_pad="5"
+     top_pad="5"
      name="updater_service_combobox"
      width="300">
         <combo_box.item
diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp
index 51ff754c27..5e8725989c 100644
--- a/indra/win_crash_logger/llcrashloggerwindows.cpp
+++ b/indra/win_crash_logger/llcrashloggerwindows.cpp
@@ -354,7 +354,7 @@ bool LLCrashLoggerWindows::mainLoop()
 
 void LLCrashLoggerWindows::updateApplication(const std::string& message)
 {
-	LLCrashLogger::updateApplication();
+	LLCrashLogger::updateApplication(message);
 	if(!message.empty()) show_progress(message);
 	update_messages();
 }
@@ -370,6 +370,3 @@ bool LLCrashLoggerWindows::cleanup()
 	PostQuitMessage(0);
 	return true;
 }
-
-
-
diff --git a/indra/win_crash_logger/llcrashloggerwindows.h b/indra/win_crash_logger/llcrashloggerwindows.h
index 24c564457c..5c45a998b3 100644
--- a/indra/win_crash_logger/llcrashloggerwindows.h
+++ b/indra/win_crash_logger/llcrashloggerwindows.h
@@ -41,7 +41,6 @@ public:
 	virtual void updateApplication(const std::string& message = LLStringUtil::null);
 	virtual bool cleanup();
 	virtual void gatherPlatformSpecificFiles();
-	//void annotateCallStack();
 	void setHandle(HINSTANCE hInst) { mhInst = hInst; }
 private:
 	void ProcessDlgItemText(HWND hWnd, int nIDDlgItem);
diff --git a/indra/win_crash_logger/win_crash_logger.cpp b/indra/win_crash_logger/win_crash_logger.cpp
index 5c22053317..8e916ae437 100644
--- a/indra/win_crash_logger/win_crash_logger.cpp
+++ b/indra/win_crash_logger/win_crash_logger.cpp
@@ -24,51 +24,30 @@
  * $/LicenseInfo$
  */
 
-// win_crash_logger.cpp : Defines the entry point for the application.
-//
-
-// Must be first include, precompiled headers.
 #include "linden_common.h"
-
 #include "stdafx.h"
-
 #include <stdlib.h>
-
 #include "llcrashloggerwindows.h"
 
-
-
-//
-// Implementation
-//
-
 int APIENTRY WinMain(HINSTANCE hInstance,
                      HINSTANCE hPrevInstance,
                      LPSTR     lpCmdLine,
                      int       nCmdShow)
 {
-	llinfos << "Starting crash reporter" << llendl;
+	llinfos << "Starting crash reporter." << llendl;
 
 	LLCrashLoggerWindows app;
 	app.setHandle(hInstance);
-	bool ok = app.init();
-	if(!ok)
+	app.parseCommandOptions(__argc, __argv);
+
+	if (! app.init())
 	{
 		llwarns << "Unable to initialize application." << llendl;
 		return -1;
 	}
 
-		// Run the application main loop
-	if(!LLApp::isQuitting()) app.mainLoop();
-
-	if (!app.isError())
-	{
-		//
-		// We don't want to do cleanup here if the error handler got called -
-		// the assumption is that the error handler is responsible for doing
-		// app cleanup if there was a problem.
-		//
-		app.cleanup();
-	}
+	app.mainLoop();
+	app.cleanup();
+	llinfos << "Crash reporter finished normally." << llendl;
 	return 0;
 }
-- 
cgit v1.2.3


From ed648b1f08a191250c5c37f831280c31950b502a Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 12 Jul 2011 20:14:39 -0400
Subject: CHOP-753: Eliminate redundant array-of-pair-arrays in LLMemoryInfo.
 (per Monty code review) The notion of storing LLMemoryInfo data both as an
 LLSD::Map and an LLSD::Array of pair arrays arose from a (possibly misguided)
 desire to continue producing stats output into the viewer log in the same
 order it always used to be produced. There is no evidence that anyone cares
 about the order of those stats in the log; there is no other use case for
 preserving order. At Monty's recommendation, eliminate generating and storing
 the array-of-pair-arrays form: directly store LLSD::Map.

---
 indra/llcommon/llsys.cpp | 72 ++++++++++++++++--------------------------------
 indra/llcommon/llsys.h   | 24 ++++------------
 2 files changed, 30 insertions(+), 66 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index ebdef56c2a..99e61433c6 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -647,13 +647,13 @@ void LLCPUInfo::stream(std::ostream& s) const
 	s << "->mCPUString:  " << mCPUString << std::endl;
 }
 
-// Helper class for LLMemoryInfo: accumulate stats in the array-of-pair-arrays
-// form we store for LLMemoryInfo::getStatsArray().
-class StatsArray
+// Helper class for LLMemoryInfo: accumulate stats in the form we store for
+// LLMemoryInfo::getStatsMap().
+class Stats
 {
 public:
-	StatsArray():
-		mStats(LLSD::emptyArray())
+	Stats():
+		mStats(LLSD::emptyMap())
 	{}
 
 	// Store every integer type as LLSD::Integer.
@@ -661,7 +661,7 @@ public:
 	void add(const LLSD::String& name, const T& value,
 			 typename boost::enable_if<boost::is_integral<T> >::type* = 0)
 	{
-		mStats.append(LLSDArray(name)(LLSD::Integer(value)));
+		mStats[name] = LLSD::Integer(value);
 	}
 
 	// Store every floating-point type as LLSD::Real.
@@ -669,13 +669,13 @@ public:
 	void add(const LLSD::String& name, const T& value,
 			 typename boost::enable_if<boost::is_float<T> >::type* = 0)
 	{
-		mStats.append(LLSDArray(name)(LLSD::Real(value)));
+		mStats[name] = LLSD::Real(value);
 	}
 
 	// Hope that LLSD::Date values are sufficiently unambiguous.
 	void add(const LLSD::String& name, const LLSD::Date& value)
 	{
-		mStats.append(LLSDArray(name)(value));
+		mStats[name] = value;
 	}
 
 	LLSD get() const { return mStats; }
@@ -792,7 +792,7 @@ void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_v
 #if LL_WINDOWS
 	// Sigh, this shouldn't be a static method, then we wouldn't have to
 	// reload this data separately from refresh()
-	LLSD statsMap(loadStatsMap(loadStatsArray()));
+	LLSD statsMap(loadStatsMap());
 
 	avail_physical_mem_kb = statsMap["Avail Physical KB"].asInteger();
 	avail_virtual_mem_kb  = statsMap["Avail Virtual KB"].asInteger();
@@ -884,16 +884,11 @@ void LLMemoryInfo::stream(std::ostream& s) const
 	// introducer line, then read subsequent lines, etc...
 	std::string pfx(LLError::utcTime() + " <mem> ");
 
-	// Most of the reason we even store mStatsArray is to preserve the
-	// original order in which we obtained these stats from the OS. So use
-	// mStatsArray in this method rather than mStatsMap, which should present
-	// the same information but in arbitrary order.
-
 	// Max key length
 	size_t key_width(0);
-	BOOST_FOREACH(LLSD pair, inArray(mStatsArray))
+	BOOST_FOREACH(const MapEntry& pair, inMap(mStatsMap))
 	{
-		size_t len(pair[0].asString().length());
+		size_t len(pair.first.length());
 		if (len > key_width)
 		{
 			key_width = len;
@@ -901,17 +896,18 @@ void LLMemoryInfo::stream(std::ostream& s) const
 	}
 
 	// Now stream stats
-	BOOST_FOREACH(LLSD pair, inArray(mStatsArray))
+	BOOST_FOREACH(const MapEntry& pair, inMap(mStatsMap))
 	{
-		s << pfx << std::setw(key_width+1) << (pair[0].asString() + ':') << ' ';
-		if (pair[1].isInteger())
-			s << std::setw(12) << pair[1].asInteger();
-		else if (pair[1].isReal())
-			s << std::fixed << std::setprecision(1) << pair[1].asReal();
-		else if (pair[1].isDate())
-			pair[1].asDate().toStream(s);
+		s << pfx << std::setw(key_width+1) << (pair.first + ':') << ' ';
+		LLSD value(pair.second);
+		if (value.isInteger())
+			s << std::setw(12) << value.asInteger();
+		else if (value.isReal())
+			s << std::fixed << std::setprecision(1) << value.asReal();
+		else if (value.isDate())
+			value.asDate().toStream(s);
 		else
-			s << pair[1];           // just use default LLSD formatting
+			s << value;           // just use default LLSD formatting
 		s << std::endl;
 	}
 }
@@ -921,16 +917,9 @@ LLSD LLMemoryInfo::getStatsMap() const
 	return mStatsMap;
 }
 
-LLSD LLMemoryInfo::getStatsArray() const
-{
-	return mStatsArray;
-}
-
 LLMemoryInfo& LLMemoryInfo::refresh()
 {
-	mStatsArray = loadStatsArray();
-	// Recast same data as mStatsMap for easy access
-	mStatsMap = loadStatsMap(mStatsArray);
+	mStatsMap = loadStatsMap();
 
 	LL_DEBUGS("LLMemoryInfo") << "Populated mStatsMap:\n";
 	LLSDSerialize::toPrettyXML(mStatsMap, LL_CONT);
@@ -939,10 +928,10 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 	return *this;
 }
 
-LLSD LLMemoryInfo::loadStatsArray()
+LLSD LLMemoryInfo::loadStatsMap()
 {
 	// This implementation is derived from stream() code (as of 2011-06-29).
-	StatsArray stats;
+	Stats stats;
 
 	// associate timestamp for analysis over time
 	stats.add("timestamp", LLDate::now());
@@ -1274,19 +1263,6 @@ LLSD LLMemoryInfo::loadStatsArray()
 	return stats.get();
 }
 
-LLSD LLMemoryInfo::loadStatsMap(const LLSD& statsArray)
-{
-	LLSD statsMap;
-
-	BOOST_FOREACH(LLSD pair, inArray(statsArray))
-	{
-		// Specify asString() to disambiguate map indexing from array
-		// subscripting.
-		statsMap[pair[0].asString()] = pair[1];
-	}
-	return statsMap;
-}
-
 std::ostream& operator<<(std::ostream& s, const LLOSInfo& info)
 {
 	info.stream(s);
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index 7fcb050ed0..739e795d3a 100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -120,35 +120,23 @@ public:
 	static void getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb);
 
 	// Retrieve a map of memory statistics. The keys of the map are platform-
-	// dependent. The values are in kilobytes.
+	// dependent. The values are in kilobytes to try to avoid integer overflow.
 	LLSD getStatsMap() const;
 
-	// Retrieve memory statistics: an array of pair arrays [name, value]. This
-	// is the same data as presented in getStatsMap(), but it preserves the
-	// order in which we retrieved it from the OS in case that's useful. The
-	// set of statistics names is platform-dependent. The values are in
-	// kilobytes to try to avoid integer overflow.
-	LLSD getStatsArray() const;
-
-	// Re-fetch memory data (as reported by stream() and getStats*()) from the
+	// Re-fetch memory data (as reported by stream() and getStatsMap()) from the
 	// system. Normally this is fetched at construction time. Return (*this)
 	// to permit usage of the form:
 	// @code
 	// LLMemoryInfo info;
 	// ...
-	// info.refresh().getStatsArray();
+	// info.refresh().getStatsMap();
 	// @endcode
 	LLMemoryInfo& refresh();
 
 private:
-	// These methods are used to set mStatsArray and mStatsMap.
-	static LLSD loadStatsArray();
-	static LLSD loadStatsMap(const LLSD&);
-
-	// Memory stats for getStatsArray(). It's straightforward to convert that
-	// to getStatsMap() form, less so to reconstruct the original order when
-	// converting the other way.
-	LLSD mStatsArray;
+	// set mStatsMap
+	static LLSD loadStatsMap();
+
 	// Memory stats for getStatsMap().
 	LLSD mStatsMap;
 };
-- 
cgit v1.2.3


From f015c073cdbf32d90ff443eec0b31bbd6a94c102 Mon Sep 17 00:00:00 2001
From: jenn <jenn@lindenlab.com>
Date: Wed, 13 Jul 2011 00:16:43 +0000
Subject: Watchdog timeout now set to 60 seconds for long-term use (instead of
 20, used during crash pile-on). Updated setting description field to describe
 how setting the value of WatchdogEnabled will affect Viewer behavior.

---
 indra/newview/app_settings/settings.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 4b62e376b5..2bd106a42e 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -12578,13 +12578,13 @@
     <key>WatchdogEnabled</key>
     <map>
       <key>Comment</key>
-      <string>Controls whether the thread watchdog timer is activated.</string>
+      <string>Controls whether the thread watchdog timer is activated. Value is watchdog timeout in seconds. Set to -1 to disable.</string>
       <key>Persist</key>
       <integer>0</integer>
       <key>Type</key>
       <string>S32</string>
       <key>Value</key>
-      <integer>20</integer>
+      <integer>60</integer>
     </map>
     <key>WaterGLFogDensityScale</key>
     <map>
-- 
cgit v1.2.3


From a6a0d5dda70de972ca1e386534284e2e93f29903 Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Wed, 13 Jul 2011 13:55:04 -0400
Subject: SH-1637 FIX, SH-1638 FIX - fixes jittery camera problems

---
 indra/newview/llagent.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
 mode change 100644 => 100755 indra/newview/llagent.cpp

(limited to 'indra')

diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
old mode 100644
new mode 100755
index 8954937f69..492cfe7c1b
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -577,7 +577,10 @@ void LLAgent::setFlying(BOOL fly)
 // static
 void LLAgent::toggleFlying()
 {
-	LLToolPie::instance().stopClickToWalk();
+	if ( gAgent.mAutoPilot )
+	{
+		LLToolPie::instance().stopClickToWalk();
+	}
 
 	BOOL fly = !gAgent.getFlying();
 
-- 
cgit v1.2.3


From f3dd16ac47ba937a92c3050c087d36c50674b06d Mon Sep 17 00:00:00 2001
From: Aaron Stone <stone@lindenlab.com>
Date: Thu, 14 Jul 2011 12:38:24 -0700
Subject: STORM-1482 Little bit of Windows crash report value logging.

---
 indra/win_crash_logger/llcrashloggerwindows.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp
index 5e8725989c..170babbb98 100644
--- a/indra/win_crash_logger/llcrashloggerwindows.cpp
+++ b/indra/win_crash_logger/llcrashloggerwindows.cpp
@@ -296,6 +296,7 @@ void LLCrashLoggerWindows::gatherPlatformSpecificFiles()
 
 bool LLCrashLoggerWindows::mainLoop()
 {	
+	llinfos << "CrashSubmitBehavior is " << mCrashBehavior << llendl;
 
 	// Note: parent hwnd is 0 (the desktop).  No dlg proc.  See Petzold (5th ed) HexCalc example, Chapter 11, p529
 	// win_crash_logger.rc has been edited by hand.
@@ -308,6 +309,7 @@ bool LLCrashLoggerWindows::mainLoop()
 
 	if (mCrashBehavior == CRASH_BEHAVIOR_ALWAYS_SEND)
 	{
+		llinfos << "Showing crash report submit progress window." << llendl;
 		ShowWindow(gHwndProgress, SW_SHOW );
 		sendCrashLogs();
 	}
-- 
cgit v1.2.3


From 143db44c9abd40131e7246a020f706301f75af83 Mon Sep 17 00:00:00 2001
From: eli <none@none>
Date: Thu, 14 Jul 2011 15:23:23 -0700
Subject: FIX STORM-1494 remove duplicate ID and xml snippet

---
 indra/newview/skins/default/xui/en/menu_viewer.xml | 12 ------------
 1 file changed, 12 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index e00586811b..317c6fe9ac 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -2931,18 +2931,6 @@
                  function="Floater.Toggle"
                  parameter="region_debug_console" />
             </menu_item_check>
-            <menu_item_check
-             label="Region Debug Console"
-             name="Region Debug Console"
-             shortcut="control|shift|`"
-             use_mac_ctrl="true">
-                <menu_item_check.on_check
-                 function="Floater.Visible"
-                 parameter="region_debug_console" />
-                <menu_item_check.on_click
-                 function="Floater.Toggle"
-                 parameter="region_debug_console" />
-            </menu_item_check>
             <menu_item_separator />
 
             <menu_item_check
-- 
cgit v1.2.3


From 187844d5fcc5c489a2112df464d2f5b9d1c28a33 Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Fri, 15 Jul 2011 19:15:30 +0300
Subject: STORM-1506 FIXED Reset the estate to global sun when changing region
 environment settings.

By the way, moved estate info storage from the REGION/ESTATE floater to a model class.
---
 indra/newview/CMakeLists.txt          |   4 +-
 indra/newview/llestateinfomodel.cpp   | 230 +++++++++++++++++++++++
 indra/newview/llestateinfomodel.h     | 103 +++++++++++
 indra/newview/llfloaterauction.cpp    |  15 +-
 indra/newview/llfloaterregioninfo.cpp | 336 ++++++++--------------------------
 indra/newview/llfloaterregioninfo.h   |  19 +-
 6 files changed, 423 insertions(+), 284 deletions(-)
 create mode 100644 indra/newview/llestateinfomodel.cpp
 create mode 100644 indra/newview/llestateinfomodel.h

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index da9a145423..935dd2e887 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -150,8 +150,9 @@ set(viewer_SOURCE_FILES
     lldrawpoolwlsky.cpp
     lldriverparam.cpp
     lldynamictexture.cpp
-    llenvmanager.cpp
     llemote.cpp
+    llenvmanager.cpp
+    llestateinfomodel.cpp
     lleventnotifier.cpp
     lleventpoll.cpp
     llexpandabletextbox.cpp
@@ -711,6 +712,7 @@ set(viewer_HEADER_FILES
     lldynamictexture.h
     llemote.h
     llenvmanager.h
+    llestateinfomodel.h
     lleventnotifier.h
     lleventpoll.h
     llexpandabletextbox.h
diff --git a/indra/newview/llestateinfomodel.cpp b/indra/newview/llestateinfomodel.cpp
new file mode 100644
index 0000000000..7ed22d68f6
--- /dev/null
+++ b/indra/newview/llestateinfomodel.cpp
@@ -0,0 +1,230 @@
+/** 
+ * @file llestateinfomodel.cpp
+ * @brief Estate info model
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llestateinfomodel.h"
+
+// libs
+#include "llhttpclient.h"
+#include "llregionflags.h"
+#include "message.h"
+
+// viewer
+#include "llagent.h"
+#include "llfloaterregioninfo.h" // for invoice id
+#include "llviewerregion.h"
+
+LLEstateInfoModel::LLEstateInfoModel()
+:	mID(0)
+,	mFlags(0)
+,	mSunHour(0)
+{
+}
+
+boost::signals2::connection LLEstateInfoModel::setUpdateCallback(const update_signal_t::slot_type& cb)
+{
+	return mUpdateSignal.connect(cb);
+}
+
+boost::signals2::connection LLEstateInfoModel::setCommitCallback(const update_signal_t::slot_type& cb)
+{
+	return mCommitSignal.connect(cb);
+}
+
+void LLEstateInfoModel::sendEstateInfo()
+{
+	if (!commitEstateInfoCaps())
+	{
+		// the caps method failed, try the old way
+		LLFloaterRegionInfo::nextInvoice();
+		commitEstateInfoDataserver();
+	}
+}
+
+bool LLEstateInfoModel::getUseFixedSun()			const {	return mFlags & REGION_FLAGS_SUN_FIXED;				}
+bool LLEstateInfoModel::getIsExternallyVisible()	const {	return mFlags & REGION_FLAGS_EXTERNALLY_VISIBLE;	}
+bool LLEstateInfoModel::getAllowDirectTeleport()	const {	return mFlags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT;	}
+bool LLEstateInfoModel::getDenyAnonymous()			const {	return mFlags & REGION_FLAGS_DENY_ANONYMOUS; 		}
+bool LLEstateInfoModel::getDenyAgeUnverified()		const {	return mFlags & REGION_FLAGS_DENY_AGEUNVERIFIED;	}
+bool LLEstateInfoModel::getAllowVoiceChat()			const {	return mFlags & REGION_FLAGS_ALLOW_VOICE;			}
+
+void LLEstateInfoModel::setUseFixedSun(bool val)			{ setFlag(REGION_FLAGS_SUN_FIXED, 				val);	}
+void LLEstateInfoModel::setIsExternallyVisible(bool val)	{ setFlag(REGION_FLAGS_EXTERNALLY_VISIBLE,		val);	}
+void LLEstateInfoModel::setAllowDirectTeleport(bool val)	{ setFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT,	val);	}
+void LLEstateInfoModel::setDenyAnonymous(bool val)			{ setFlag(REGION_FLAGS_DENY_ANONYMOUS,			val);	}
+void LLEstateInfoModel::setDenyAgeUnverified(bool val)		{ setFlag(REGION_FLAGS_DENY_AGEUNVERIFIED,		val);	}
+void LLEstateInfoModel::setAllowVoiceChat(bool val)			{ setFlag(REGION_FLAGS_ALLOW_VOICE,				val);	}
+
+void LLEstateInfoModel::update(const strings_t& strings)
+{
+	// NOTE: LLDispatcher extracts strings with an extra \0 at the
+	// end.  If we pass the std::string direct to the UI/renderer
+	// it draws with a weird character at the end of the string.
+	mName		= strings[0].c_str();
+	mOwnerID	= LLUUID(strings[1].c_str());
+	mID			= strtoul(strings[2].c_str(), NULL, 10);
+	mFlags		= strtoul(strings[3].c_str(), NULL, 10);
+	mSunHour	= ((F32)(strtod(strings[4].c_str(), NULL)))/1024.0f;
+
+	LL_DEBUGS("Windlight Sync") << "Received estate info: "
+		<< "is_sun_fixed = " << getUseFixedSun()
+		<< ", sun_hour = " << getSunHour() << LL_ENDL;
+	lldebugs << getInfoDump() << llendl;
+
+	// Update region owner.
+	LLViewerRegion* regionp = gAgent.getRegion();
+	regionp->setOwner(mOwnerID);
+
+	// Let interested parties know that estate info has been updated.
+	mUpdateSignal();
+}
+
+void LLEstateInfoModel::notifyCommit()
+{
+	mCommitSignal();
+}
+
+//== PRIVATE STUFF ============================================================
+
+class LLEstateChangeInfoResponder : public LLHTTPClient::Responder
+{
+public:
+
+	// if we get a normal response, handle it here
+	virtual void result(const LLSD& content)
+	{
+		llinfos << "Committed estate info" << llendl;
+		LLEstateInfoModel::instance().notifyCommit();
+	}
+
+	// if we get an error response
+	virtual void error(U32 status, const std::string& reason)
+	{
+		llwarns << "Failed to commit estate info (" << status << "): " << reason << llendl;
+	}
+};
+
+// tries to send estate info using a cap; returns true if it succeeded
+bool LLEstateInfoModel::commitEstateInfoCaps()
+{
+	std::string url = gAgent.getRegion()->getCapability("EstateChangeInfo");
+
+	if (url.empty())
+	{
+		// whoops, couldn't find the cap, so bail out
+		return false;
+	}
+
+	LLSD body;
+	body["estate_name"          ] = getName();
+	body["sun_hour"             ] = getSunHour();
+
+	body["is_sun_fixed"         ] = getUseFixedSun();
+	body["is_externally_visible"] = getIsExternallyVisible();
+	body["allow_direct_teleport"] = getAllowDirectTeleport();
+	body["deny_anonymous"       ] = getDenyAnonymous();
+	body["deny_age_unverified"  ] = getDenyAgeUnverified();
+	body["allow_voice_chat"     ] = getAllowVoiceChat();
+
+	body["invoice"              ] = LLFloaterRegionInfo::getLastInvoice();
+
+	LL_DEBUGS("Windlight Sync") << "Sending estate caps: "
+		<< "is_sun_fixed = " << getUseFixedSun()
+		<< ", sun_hour = " << getSunHour() << LL_ENDL;
+	lldebugs << body << LL_ENDL;
+
+	// we use a responder so that we can re-get the data after committing to the database
+	LLHTTPClient::post(url, body, new LLEstateChangeInfoResponder);
+    return true;
+}
+
+/* This is the old way of doing things, is deprecated, and should be
+   deleted when the dataserver model can be removed */
+// key = "estatechangeinfo"
+// strings[0] = str(estate_id) (added by simulator before relay - not here)
+// strings[1] = estate_name
+// strings[2] = str(estate_flags)
+// strings[3] = str((S32)(sun_hour * 1024.f))
+void LLEstateInfoModel::commitEstateInfoDataserver()
+{
+	LL_DEBUGS("Windlight Sync") << "Sending estate info: "
+		<< "is_sun_fixed = " << getUseFixedSun()
+		<< ", sun_hour = " << getSunHour() << LL_ENDL;
+	lldebugs << getInfoDump() << LL_ENDL;
+
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessage("EstateOwnerMessage");
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
+
+	msg->nextBlock("MethodData");
+	msg->addString("Method", "estatechangeinfo");
+	msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice());
+
+	msg->nextBlock("ParamList");
+	msg->addString("Parameter", getName());
+
+	msg->nextBlock("ParamList");
+	msg->addString("Parameter", llformat("%u", getFlags()));
+
+	msg->nextBlock("ParamList");
+	msg->addString("Parameter", llformat("%d", (S32) (getSunHour() * 1024.0f)));
+
+	gAgent.sendMessage();
+}
+
+void LLEstateInfoModel::setFlag(U32 flag, bool val)
+{
+	if (val)
+	{
+		mFlags |= flag;
+	}
+	else
+	{
+		mFlags &= ~flag;
+	}
+}
+
+std::string LLEstateInfoModel::getInfoDump()
+{
+	LLSD dump;
+	dump["estate_name"          ] = getName();
+	dump["sun_hour"             ] = getSunHour();
+
+	dump["is_sun_fixed"         ] = getUseFixedSun();
+	dump["is_externally_visible"] = getIsExternallyVisible();
+	dump["allow_direct_teleport"] = getAllowDirectTeleport();
+	dump["deny_anonymous"       ] = getDenyAnonymous();
+	dump["deny_age_unverified"  ] = getDenyAgeUnverified();
+	dump["allow_voice_chat"     ] = getAllowVoiceChat();
+
+	std::stringstream dump_str;
+	dump_str << dump;
+	return dump_str.str();
+}
diff --git a/indra/newview/llestateinfomodel.h b/indra/newview/llestateinfomodel.h
new file mode 100644
index 0000000000..56391eda91
--- /dev/null
+++ b/indra/newview/llestateinfomodel.h
@@ -0,0 +1,103 @@
+/** 
+ * @file llestateinfomodel.h
+ * @brief Estate info model
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLESTATEINFOMODEL_H
+#define LL_LLESTATEINFOMODEL_H
+
+class LLMessageSystem;
+
+#include "llsingleton.h"
+
+/**
+ * Contains estate info, notifies interested parties of its changes.
+ */
+class LLEstateInfoModel : public LLSingleton<LLEstateInfoModel>
+{
+	LOG_CLASS(LLEstateInfoModel);
+
+public:
+	typedef boost::signals2::signal<void()> update_signal_t;
+	boost::signals2::connection setUpdateCallback(const update_signal_t::slot_type& cb); /// the model has been externally updated
+	boost::signals2::connection setCommitCallback(const update_signal_t::slot_type& cb); /// our changes have been applied
+
+	void sendEstateInfo(); /// send estate info to the simulator
+
+	// getters
+	bool				getUseFixedSun()			const;
+	bool				getIsExternallyVisible()	const;
+	bool				getAllowDirectTeleport()	const;
+	bool				getDenyAnonymous()			const;
+	bool				getDenyAgeUnverified()		const;
+	bool				getAllowVoiceChat()			const;
+
+	const std::string&	getName()					const { return mName; }
+	const LLUUID&		getOwnerID()				const { return mOwnerID; }
+	U32					getID()						const { return mID; }
+	F32					getSunHour()				const { return getUseFixedSun() ? mSunHour : 0.f; }
+
+	// setters
+	void setUseFixedSun(bool val);
+	void setIsExternallyVisible(bool val);
+	void setAllowDirectTeleport(bool val);
+	void setDenyAnonymous(bool val);
+	void setDenyAgeUnverified(bool val);
+	void setAllowVoiceChat(bool val);
+
+	void setSunHour(F32 sun_hour) { mSunHour = sun_hour; }
+
+protected:
+	typedef std::vector<std::string> strings_t;
+
+	friend class LLSingleton<LLEstateInfoModel>;
+	friend class LLDispatchEstateUpdateInfo;
+	friend class LLEstateChangeInfoResponder;
+
+	LLEstateInfoModel();
+
+	/// refresh model with data from the incoming server message
+	void update(const strings_t& strings);
+
+	void notifyCommit();
+
+private:
+	bool commitEstateInfoCaps();
+	void commitEstateInfoDataserver();
+	U32  getFlags() const { return mFlags; }
+	void setFlag(U32 flag, bool val);
+	std::string getInfoDump();
+
+	// estate info
+	std::string	mName;			/// estate name
+	LLUUID		mOwnerID;		/// estate owner id
+	U32			mID;			/// estate id
+	U32			mFlags;			/// estate flags
+	F32			mSunHour;		/// estate sun hour
+
+	update_signal_t mUpdateSignal; /// emitted when we receive update from sim
+	update_signal_t mCommitSignal; /// emitted when our update gets applied to sim
+};
+
+#endif // LL_LLESTATEINFOMODEL_H
diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp
index c6743ca13b..2939d31087 100644
--- a/indra/newview/llfloaterauction.cpp
+++ b/indra/newview/llfloaterauction.cpp
@@ -27,7 +27,6 @@
 
 #include "llviewerprecompiledheaders.h"
 #include "llfloaterauction.h"
-#include "llfloaterregioninfo.h"
 
 #include "llgl.h"
 #include "llimagej2c.h"
@@ -40,6 +39,7 @@
 
 #include "llagent.h"
 #include "llcombobox.h"
+#include "llestateinfomodel.h"
 #include "llmimetypes.h"
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
@@ -114,16 +114,9 @@ void LLFloaterAuction::initialize()
 		getChildView("reset_parcel_btn")->setEnabled(TRUE);
 		getChildView("start_auction_btn")->setEnabled(TRUE);
 
-		LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate();
-		if (panel)
-		{	// Only enable "Sell to Anyone" on Teen grid or if we don't know the ID yet
-			U32 estate_id = panel->getEstateID();
-			getChildView("sell_to_anyone_btn")->setEnabled((estate_id == ESTATE_TEEN || estate_id == 0));
-		}
-		else
-		{	// Don't have the panel up, so don't know if we're on the teen grid or not.  Default to enabling it
-			getChildView("sell_to_anyone_btn")->setEnabled(TRUE);
-		}
+		U32 estate_id = LLEstateInfoModel::instance().getID();
+		// Only enable "Sell to Anyone" on Teen grid or if we don't know the ID yet
+		getChildView("sell_to_anyone_btn")->setEnabled(estate_id == ESTATE_TEEN || estate_id == 0);
 	}
 	else
 	{
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index bedc7ef704..538c5e3b88 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -54,6 +54,7 @@
 #include "llcombobox.h"
 #include "lldaycyclemanager.h"
 #include "llenvmanager.h"
+#include "llestateinfomodel.h"
 #include "llfilepicker.h"
 #include "llfloatergodtools.h"	// for send_sim_wide_deletes()
 #include "llfloatertopobjects.h" // added to fix SL-32336
@@ -1363,6 +1364,9 @@ LLPanelEstateInfo::LLPanelEstateInfo()
 :	LLPanelRegionInfo(),
 	mEstateID(0)	// invalid
 {
+	LLEstateInfoModel& estate_info = LLEstateInfoModel::instance();
+	estate_info.setCommitCallback(boost::bind(&LLPanelEstateInfo::refreshFromEstate, this));
+	estate_info.setUpdateCallback(boost::bind(&LLPanelEstateInfo::refreshFromEstate, this));
 }
 
 // static
@@ -1385,29 +1389,6 @@ void LLPanelEstateInfo::initDispatch(LLDispatcher& dispatch)
 	estate_dispatch_initialized = true;
 }
 
-#ifndef TMP_DISABLE_WLES
-// Disables the sun-hour slider and the use fixed time check if the use global time is check
-void LLPanelEstateInfo::onChangeUseGlobalTime()
-{
-	bool enabled = !getChild<LLUICtrl>("use_global_time_check")->getValue().asBoolean();
-	getChildView("sun_hour_slider")->setEnabled(enabled);
-	getChildView("fixed_sun_check")->setEnabled(enabled);
-	getChild<LLUICtrl>("fixed_sun_check")->setValue(LLSD(FALSE));
-	enableButton("apply_btn");
-}
-
-// Enables the sun-hour slider if the fixed-sun checkbox is set
-void LLPanelEstateInfo::onChangeFixedSun()
-{
-	bool enabled = !getChild<LLUICtrl>("fixed_sun_check")->getValue().asBoolean();
-	getChildView("use_global_time_check")->setEnabled(enabled);
-	getChild<LLUICtrl>("use_global_time_check")->setValue(LLSD(FALSE));
-	enableButton("apply_btn");
-}
-#endif // TMP_DISABLE_WLES
-
-
-
 //---------------------------------------------------------------------------
 // Add/Remove estate access button callbacks
 //---------------------------------------------------------------------------
@@ -1610,10 +1591,7 @@ std::string all_estates_text()
 // static
 bool LLPanelEstateInfo::isLindenEstate()
 {
-	LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate();
-	if (!panel) return false;
-
-	U32 estate_id = panel->getEstateID();
+	U32 estate_id = LLEstateInfoModel::instance().getID();
 	return (estate_id <= ESTATE_LAST_LINDEN);
 }
 
@@ -1975,7 +1953,7 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region)
 	// Can't ban people from mainland, orientation islands, etc. because this
 	// creates much network traffic and server load.
 	// Disable their accounts in CSR tool instead.
-	bool linden_estate = (getEstateID() <= ESTATE_LAST_LINDEN);
+	bool linden_estate = isLindenEstate();
 	bool enable_ban = (god || owner || manager) && !linden_estate;
 	getChildView("add_banned_avatar_btn")->setEnabled(enable_ban);
 	getChildView("remove_banned_avatar_btn")->setEnabled(enable_ban);
@@ -1987,6 +1965,8 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region)
 	getChildView("add_estate_manager_btn")->setEnabled(god || owner);
 	getChildView("remove_estate_manager_btn")->setEnabled(god || owner);
 	getChildView("estate_manager_name_list")->setEnabled(god || owner);
+
+	refresh();
 }
 
 bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region)
@@ -2093,10 +2073,13 @@ BOOL LLPanelEstateInfo::postBuild()
 
 void LLPanelEstateInfo::refresh()
 {
+	// Disable access restriction controls if they make no sense.
 	bool public_access = getChild<LLUICtrl>("externally_visible_check")->getValue().asBoolean();
+
 	getChildView("Only Allow")->setEnabled(public_access);
 	getChildView("limit_payment")->setEnabled(public_access);
 	getChildView("limit_age_verified")->setEnabled(public_access);
+
 	// if this is set to false, then the limit fields are meaningless and should be turned off
 	if (public_access == false)
 	{
@@ -2105,6 +2088,39 @@ void LLPanelEstateInfo::refresh()
 	}
 }
 
+void LLPanelEstateInfo::refreshFromEstate()
+{
+	const LLEstateInfoModel& estate_info = LLEstateInfoModel::instance();
+
+	getChild<LLUICtrl>("estate_name")->setValue(estate_info.getName());
+	setOwnerName(LLSLURL("agent", estate_info.getOwnerID(), "inspect").getSLURLString());
+
+	getChild<LLUICtrl>("externally_visible_check")->setValue(estate_info.getIsExternallyVisible());
+	getChild<LLUICtrl>("voice_chat_check")->setValue(estate_info.getAllowVoiceChat());
+	getChild<LLUICtrl>("allow_direct_teleport")->setValue(estate_info.getAllowDirectTeleport());
+	getChild<LLUICtrl>("limit_payment")->setValue(estate_info.getDenyAnonymous());
+	getChild<LLUICtrl>("limit_age_verified")->setValue(estate_info.getDenyAgeUnverified());
+
+	// If visible from mainland, disable the access allowed
+	// UI, as anyone can teleport there.
+	// However, gods need to be able to edit the access list for
+	// linden estates, regardless of visibility, to allow object
+	// and L$ transfers.
+	{
+		bool visible_from_mainland = estate_info.getIsExternallyVisible();
+		bool god = gAgent.isGodlike();
+		bool linden_estate = isLindenEstate();
+
+		bool enable_agent = (!visible_from_mainland || (god && linden_estate));
+		bool enable_group = enable_agent;
+		bool enable_ban = !linden_estate;
+
+		setAccessAllowedEnabled(enable_agent, enable_group, enable_ban);
+	}
+
+	refresh();
+}
+
 BOOL LLPanelEstateInfo::sendUpdate()
 {
 	llinfos << "LLPanelEsateInfo::sendUpdate()" << llendl;
@@ -2112,7 +2128,7 @@ BOOL LLPanelEstateInfo::sendUpdate()
 	LLNotification::Params params("ChangeLindenEstate");
 	params.functor.function(boost::bind(&LLPanelEstateInfo::callbackChangeLindenEstate, this, _1, _2));
 
-	if (getEstateID() <= ESTATE_LAST_LINDEN)
+	if (isLindenEstate())
 	{
 		// trying to change reserved estate, warn
 		LLNotifications::instance().add(params);
@@ -2131,13 +2147,21 @@ bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, con
 	switch(option)
 	{
 	case 0:
-		// send the update
-		if (!commitEstateInfoCaps())
 		{
-			// the caps method failed, try the old way
-			LLFloaterRegionInfo::nextInvoice();
-			commitEstateInfoDataserver();
+			LLEstateInfoModel& estate_info = LLEstateInfoModel::instance();
+
+			// update model
+			estate_info.setUseFixedSun(false); // we don't support fixed sun estates anymore
+			estate_info.setIsExternallyVisible(getChild<LLUICtrl>("externally_visible_check")->getValue().asBoolean());
+			estate_info.setAllowDirectTeleport(getChild<LLUICtrl>("allow_direct_teleport")->getValue().asBoolean());
+			estate_info.setDenyAnonymous(getChild<LLUICtrl>("limit_payment")->getValue().asBoolean());
+			estate_info.setDenyAgeUnverified(getChild<LLUICtrl>("limit_age_verified")->getValue().asBoolean());
+			estate_info.setAllowVoiceChat(getChild<LLUICtrl>("voice_chat_check")->getValue().asBoolean());
+
+			// send the update to sim
+			estate_info.sendEstateInfo();
 		}
+
 		// we don't want to do this because we'll get it automatically from the sim
 		// after the spaceserver processes it
 //		else
@@ -2194,6 +2218,8 @@ public:
 	// if we get a normal response, handle it here
 	virtual void result(const LLSD& content)
 	{
+		LL_INFOS("Windlight") << "Successfully committed estate info" << llendl;
+
 	    // refresh the panel from the database
 		LLPanelEstateInfo* panel = dynamic_cast<LLPanelEstateInfo*>(mpPanel.get());
 		if (panel)
@@ -2210,178 +2236,6 @@ private:
 	LLHandle<LLPanel> mpPanel;
 };
 
-// tries to send estate info using a cap; returns true if it succeeded
-bool LLPanelEstateInfo::commitEstateInfoCaps()
-{
-	std::string url = gAgent.getRegion()->getCapability("EstateChangeInfo");
-	
-	if (url.empty())
-	{
-		// whoops, couldn't find the cap, so bail out
-		return false;
-	}
-	
-	LLSD body;
-	body["estate_name"] = getEstateName();
-
-	body["is_externally_visible"] = getChild<LLUICtrl>("externally_visible_check")->getValue().asBoolean();
-	body["allow_direct_teleport"] = getChild<LLUICtrl>("allow_direct_teleport")->getValue().asBoolean();
-	body["deny_anonymous"       ] = getChild<LLUICtrl>("limit_payment")->getValue().asBoolean();
-	body["deny_age_unverified"  ] = getChild<LLUICtrl>("limit_age_verified")->getValue().asBoolean();
-	body["allow_voice_chat"     ] = getChild<LLUICtrl>("voice_chat_check")->getValue().asBoolean();
-	body["invoice"              ] = LLFloaterRegionInfo::getLastInvoice();
-
-	// block fly is in estate database but not in estate UI, so we're not supporting it
-	//body["block_fly"            ] = getChild<LLUICtrl>("")->getValue().asBoolean();
-
-	F32 sun_hour = getSunHour();
-	if (getChild<LLUICtrl>("use_global_time_check")->getValue().asBoolean())
-	{
-		sun_hour = 0.f;			// 0 = global time
-	}
-	body["sun_hour"] = sun_hour;
-
-	// we use a responder so that we can re-get the data after committing to the database
-	LLHTTPClient::post(url, body, new LLEstateChangeInfoResponder(this));
-    return true;
-}
-
-/* This is the old way of doing things, is deprecated, and should be 
-   deleted when the dataserver model can be removed */
-// key = "estatechangeinfo"
-// strings[0] = str(estate_id) (added by simulator before relay - not here)
-// strings[1] = estate_name
-// strings[2] = str(estate_flags)
-// strings[3] = str((S32)(sun_hour * 1024.f))
-void LLPanelEstateInfo::commitEstateInfoDataserver()
-{
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessage("EstateOwnerMessage");
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
-
-	msg->nextBlock("MethodData");
-	msg->addString("Method", "estatechangeinfo");
-	msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice());
-
-	msg->nextBlock("ParamList");
-	msg->addString("Parameter", getEstateName());
-
-	std::string buffer;
-	buffer = llformat("%u", computeEstateFlags());
-	msg->nextBlock("ParamList");
-	msg->addString("Parameter", buffer);
-
-	F32 sun_hour = getSunHour();
-	if (getChild<LLUICtrl>("use_global_time_check")->getValue().asBoolean())
-	{
-		sun_hour = 0.f;	// 0 = global time
-	}
-
-	buffer = llformat("%d", (S32)(sun_hour*1024.0f));
-	msg->nextBlock("ParamList");
-	msg->addString("Parameter", buffer);
-
-	gAgent.sendMessage();
-}
-
-void LLPanelEstateInfo::setEstateFlags(U32 flags)
-{
-	getChild<LLUICtrl>("externally_visible_check")->setValue(LLSD(flags & REGION_FLAGS_EXTERNALLY_VISIBLE ? TRUE : FALSE) );
-	getChild<LLUICtrl>("voice_chat_check")->setValue(
-		LLSD(flags & REGION_FLAGS_ALLOW_VOICE ? TRUE : FALSE));
-	getChild<LLUICtrl>("allow_direct_teleport")->setValue(LLSD(flags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT ? TRUE : FALSE) );
-	getChild<LLUICtrl>("limit_payment")->setValue(LLSD(flags & REGION_FLAGS_DENY_ANONYMOUS ? TRUE : FALSE) );
-	getChild<LLUICtrl>("limit_age_verified")->setValue(LLSD(flags & REGION_FLAGS_DENY_AGEUNVERIFIED ? TRUE : FALSE) );
-
-	refresh();
-}
-
-U32 LLPanelEstateInfo::computeEstateFlags()
-{
-	U32 flags = 0;
-
-	if (getChild<LLUICtrl>("externally_visible_check")->getValue().asBoolean())
-	{
-		flags |= REGION_FLAGS_EXTERNALLY_VISIBLE;
-	}
-
-	if ( getChild<LLUICtrl>("voice_chat_check")->getValue().asBoolean() )
-	{
-		flags |= REGION_FLAGS_ALLOW_VOICE;
-	}
-	
-	if (getChild<LLUICtrl>("allow_direct_teleport")->getValue().asBoolean())
-	{
-		flags |= REGION_FLAGS_ALLOW_DIRECT_TELEPORT;
-	}
-
-	if (getChild<LLUICtrl>("limit_payment")->getValue().asBoolean())
-	{
-		flags |= REGION_FLAGS_DENY_ANONYMOUS;
-	}
-	
-	if (getChild<LLUICtrl>("limit_age_verified")->getValue().asBoolean())
-	{
-		flags |= REGION_FLAGS_DENY_AGEUNVERIFIED;
-	}
-
-	
-	return flags;
-}
-
-BOOL LLPanelEstateInfo::getGlobalTime()
-{
-	return getChild<LLUICtrl>("use_global_time_check")->getValue().asBoolean();
-}
-
-void LLPanelEstateInfo::setGlobalTime(bool b)
-{
-	getChild<LLUICtrl>("use_global_time_check")->setValue(LLSD(b));
-	getChildView("fixed_sun_check")->setEnabled(LLSD(!b));
-	getChildView("sun_hour_slider")->setEnabled(LLSD(!b));
-	if (b)
-	{
-		getChild<LLUICtrl>("sun_hour_slider")->setValue(LLSD(0.f));
-	}
-}
-
-
-BOOL LLPanelEstateInfo::getFixedSun()
-{
-	return getChild<LLUICtrl>("fixed_sun_check")->getValue().asBoolean();
-}
-
-void LLPanelEstateInfo::setSunHour(F32 sun_hour)
-{
-	if(sun_hour < 6.0f)
-	{
-		sun_hour = 24.0f + sun_hour;
-	}
-	getChild<LLUICtrl>("sun_hour_slider")->setValue(LLSD(sun_hour));
-}
-
-F32 LLPanelEstateInfo::getSunHour()
-{
-	if (getChildView("sun_hour_slider")->getEnabled())
-	{
-		return (F32)getChild<LLUICtrl>("sun_hour_slider")->getValue().asReal();
-	}
-	return 0.f;
-}
-
-const std::string LLPanelEstateInfo::getEstateName() const
-{
-	return getChild<LLUICtrl>("estate_name")->getValue().asString();
-}
-
-void LLPanelEstateInfo::setEstateName(const std::string& name)
-{
-	getChild<LLUICtrl>("estate_name")->setValue(LLSD(name));
-}
-
 const std::string LLPanelEstateInfo::getOwnerName() const
 {
 	return getChild<LLUICtrl>("estate_owner")->getValue().asString();
@@ -2884,55 +2738,10 @@ bool LLDispatchEstateUpdateInfo::operator()(
 {
 	lldebugs << "Received estate update" << llendl;
 
-	LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate();
-	if (!panel) return true;
-
-	// NOTE: LLDispatcher extracts strings with an extra \0 at the
-	// end.  If we pass the std::string direct to the UI/renderer
-	// it draws with a weird character at the end of the string.
-	std::string estate_name = strings[0].c_str(); // preserve c_str() call!
-	panel->setEstateName(estate_name);
-	
-	LLViewerRegion* regionp = gAgent.getRegion();
-
-	LLUUID owner_id(strings[1]);
-	regionp->setOwner(owner_id);
-	// Update estate owner name in UI
-	std::string owner_name = LLSLURL("agent", owner_id, "inspect").getSLURLString();
-	panel->setOwnerName(owner_name);
-
-	U32 estate_id = strtoul(strings[2].c_str(), NULL, 10);
-	panel->setEstateID(estate_id);
-
-	U32 flags = strtoul(strings[3].c_str(), NULL, 10);
-	panel->setEstateFlags(flags);
-
-	F32 sun_hour = ((F32)(strtod(strings[4].c_str(), NULL)))/1024.0f;
-	if(sun_hour == 0 && (flags & REGION_FLAGS_SUN_FIXED ? FALSE : TRUE))
-	{
-		lldebugs << "Estate uses global time" << llendl;
-		panel->setGlobalTime(TRUE);
-	} 
-	else
-	{
-		lldebugs << "Estate sun hour: " << sun_hour << llendl;
-		panel->setGlobalTime(FALSE);
-		panel->setSunHour(sun_hour);
-	}
-
-	bool visible_from_mainland = (bool)(flags & REGION_FLAGS_EXTERNALLY_VISIBLE);
-	bool god = gAgent.isGodlike();
-	bool linden_estate = (estate_id <= ESTATE_LAST_LINDEN);
-
-	// If visible from mainland, disable the access allowed
-	// UI, as anyone can teleport there.
-	// However, gods need to be able to edit the access list for
-	// linden estates, regardless of visibility, to allow object
-	// and L$ transfers.
-	bool enable_agent = (!visible_from_mainland || (god && linden_estate));
-	bool enable_group = enable_agent;
-	bool enable_ban = !linden_estate;
-	panel->setAccessAllowedEnabled(enable_agent, enable_group, enable_ban);
+	// Update estate info model.
+	// This will call LLPanelEstateInfo::refreshFromEstate().
+	// *TODO: Move estate message handling stuff to llestateinfomodel.cpp.
+	LLEstateInfoModel::instance().update(strings);
 
 	return true;
 }
@@ -3275,6 +3084,20 @@ void LLPanelEnvironmentInfo::sendRegionSunUpdate()
 	region_info.sendRegionTerrain(LLFloaterRegionInfo::getLastInvoice());
 }
 
+void LLPanelEnvironmentInfo::fixEstateSun()
+{
+	// We don't support fixed sun estates anymore and need to fix
+	// such estates for region day cycle to take effect.
+	// *NOTE: Assuming that current estate settings have arrived already.
+	LLEstateInfoModel& estate_info = LLEstateInfoModel::instance();
+	if (estate_info.getUseFixedSun())
+	{
+		llinfos << "Switching estate to global sun" << llendl;
+		estate_info.setUseFixedSun(false);
+		estate_info.sendEstateInfo();
+	}
+}
+
 void LLPanelEnvironmentInfo::populateWaterPresetsList()
 {
 	mWaterPresetCombo->removeall();
@@ -3668,6 +3491,9 @@ void LLPanelEnvironmentInfo::onRegionSettingsApplied(bool ok)
 		// That is caused by the simulator re-sending the region info, which in turn makes us
 		// re-request and display old region environment settings while the new ones haven't been applied yet.
 		sendRegionSunUpdate();
+
+		// Switch estate to not using fixed sun for the region day cycle to work properly (STORM-1506).
+		fixEstateSun();
 	}
 	else
 	{
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index e7917c382c..c1fef57ac9 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -304,23 +304,9 @@ public:
 	virtual BOOL postBuild();
 	virtual void updateChild(LLUICtrl* child_ctrl);
 	virtual void refresh();
-	
-	U32 computeEstateFlags();
-	void setEstateFlags(U32 flags);
-	
-	BOOL getGlobalTime();
-	void setGlobalTime(bool b);
-
-	BOOL getFixedSun();				// *TODO: deprecated
 
-	F32 getSunHour();				// *TODO: deprecated
-	void setSunHour(F32 sun_hour);	// *TODO: deprecated
+	void refreshFromEstate();
 	
-	const std::string getEstateName() const;
-	void setEstateName(const std::string& name);
-
-	U32 getEstateID() const { return mEstateID; }
-	void setEstateID(U32 estate_id) { mEstateID = estate_id; }
 	static bool isLindenEstate();
 	
 	const std::string getOwnerName() const;
@@ -334,8 +320,6 @@ protected:
 	// confirmation dialog callback
 	bool callbackChangeLindenEstate(const LLSD& notification, const LLSD& response);
 
-	void commitEstateInfoDataserver();
-	bool commitEstateInfoCaps();
 	void commitEstateAccess();
 	void commitEstateManagers();
 	
@@ -434,6 +418,7 @@ private:
 	void setDirty(bool dirty);
 
 	void sendRegionSunUpdate();
+	void fixEstateSun();
 
 	void populateWaterPresetsList();
 	void populateSkyPresetsList();
-- 
cgit v1.2.3


From a517d32c4877aec79219cd346709c621c51c032b Mon Sep 17 00:00:00 2001
From: Aaron Stone <stone@lindenlab.com>
Date: Fri, 15 Jul 2011 12:46:06 -0700
Subject: STORM-1482 Change the defaults, look in the app_settings dir for
 configs as well.

---
 indra/llcrashlogger/llcrashlogger.cpp | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index 3fbaf61991..93f3c910bd 100644
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -67,7 +67,7 @@ public:
 };
 
 LLCrashLogger::LLCrashLogger() :
-	mCrashBehavior(CRASH_BEHAVIOR_ASK),
+	mCrashBehavior(CRASH_BEHAVIOR_ALWAYS_SEND),
 	mCrashInPreviousExec(false),
 	mCrashSettings("CrashSettings"),
 	mSentCrashLogs(false),
@@ -274,12 +274,19 @@ const char* const CRASH_SETTINGS_FILE = "settings_crash_behavior.xml";
 
 S32 LLCrashLogger::loadCrashBehaviorSetting()
 {
+	// First check user_settings (in the user's home dir)
 	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
+	if (! mCrashSettings.loadFromFile(filename))
+	{
+		// Next check app_settings (in the SL program dir)
+		std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, CRASH_SETTINGS_FILE);
+		mCrashSettings.loadFromFile(filename);
+	}
 
-	mCrashSettings.loadFromFile(filename);
-
+	// If we didn't load any files above, this will return the default
 	S32 value = mCrashSettings.getS32("CrashSubmitBehavior");
 
+	// Whatever value we got, make sure it's valid
 	switch (value)
 	{
 	case CRASH_BEHAVIOR_NEVER_SEND:
@@ -391,14 +398,14 @@ bool LLCrashLogger::init()
 	// Set the log file to crashreport.log
 	LLError::logToFile(log_file);
 	
-	mCrashSettings.declareS32("CrashSubmitBehavior", CRASH_BEHAVIOR_ASK,
+	mCrashSettings.declareS32("CrashSubmitBehavior", CRASH_BEHAVIOR_ALWAYS_SEND,
 							  "Controls behavior when viewer crashes "
 							  "(0 = ask before sending crash report, "
 							  "1 = always send crash report, "
 							  "2 = never send crash report)");
 
-	llinfos << "Loading crash behavior setting" << llendl;
-	mCrashBehavior = loadCrashBehaviorSetting();
+	// llinfos << "Loading crash behavior setting" << llendl;
+	// mCrashBehavior = loadCrashBehaviorSetting();
 
 	// If user doesn't want to send, bail out
 	if (mCrashBehavior == CRASH_BEHAVIOR_NEVER_SEND)
-- 
cgit v1.2.3


From dba72d25659d2a83cefaf17738cc14e5e7eabe28 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Fri, 15 Jul 2011 17:10:36 -0400
Subject: storm-1510: update to new login display url

---
 indra/newview/app_settings/settings.xml      |  2 +-
 indra/newview/llviewernetwork.cpp            |  2 +-
 indra/newview/tests/llviewernetwork_test.cpp | 12 ++++++------
 3 files changed, 8 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 91cbfde07f..5ad62d28c0 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4872,7 +4872,7 @@
       <key>Type</key>
       <string>String</string>
       <key>Value</key>
-      <string />
+      <string>http://viewer-login.agni.lindenlab.com/</string>
     </map>
     <key>LosslessJ2CUpload</key>
     <map>
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index a59afdc28a..ef5c65eb87 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -35,7 +35,7 @@
 #include "llweb.h"
 
                                                             
-const char* DEFAULT_LOGIN_PAGE = "http://secondlife.com/app/login/";
+const char* DEFAULT_LOGIN_PAGE = "http://viewer-login.agni.lindenlab.com/";
 
 const char* SYSTEM_GRID_SLURL_BASE = "secondlife://%s/secondlife/";
 const char* MAIN_GRID_SLURL_BASE = "http://maps.secondlife.com/secondlife/";
diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp
index dd7761475e..3c89b64d52 100644
--- a/indra/newview/tests/llviewernetwork_test.cpp
+++ b/indra/newview/tests/llviewernetwork_test.cpp
@@ -164,7 +164,7 @@ namespace tut
 					  std::string("https://secondlife.com/helpers/"));
 		ensure_equals("Agni login page is correct",
 					  grid[GRID_LOGIN_PAGE_VALUE].asString(), 
-					  std::string("http://secondlife.com/app/login/"));
+					  std::string("http://viewer-login.agni.lindenlab.com/"));
 		ensure("Agni is a favorite",
 			   grid.has(GRID_IS_FAVORITE_VALUE));
 		ensure("Agni is a system grid", 
@@ -208,7 +208,7 @@ namespace tut
 					  std::string("https://secondlife.com/helpers/"));
 		ensure_equals("Agni login page the same after grid file", 
 					  grid[GRID_LOGIN_PAGE_VALUE].asString(), 
-					  std::string("http://secondlife.com/app/login/"));
+					  std::string("http://viewer-login.agni.lindenlab.com/"));
 		ensure("Agni still a favorite after grid file", 
 			   grid.has(GRID_IS_FAVORITE_VALUE));
 		ensure("Agni system grid still set after grid file", 
@@ -310,7 +310,7 @@ namespace tut
 					  std::string("http://aditi-secondlife.webdev.lindenlab.com/helpers/"));
 		ensure_equals("Override known grid login uri: login page is not set",
 					  grid[GRID_LOGIN_PAGE_VALUE].asString(), 
-					  std::string("http://secondlife.com/app/login/"));		
+					  std::string("http://viewer-login.agni.lindenlab.com/"));		
 		
 		// Override with loginuri
 		// override custom grid
@@ -359,7 +359,7 @@ namespace tut
 					  std::string("https://my.helper.uri/mycustomhelpers"));
 		ensure_equals("Override known grid helper uri: login page is not changed",
 					  grid[GRID_LOGIN_PAGE_VALUE].asString(), 
-					  std::string("http://secondlife.com/app/login/"));		
+					  std::string("http://viewer-login.agni.lindenlab.com/"));		
 		
 		// Override with helperuri
 		// override custom grid
@@ -451,9 +451,9 @@ namespace tut
 		ensure_equals("getHelperURI", LLGridManager::getInstance()->getHelperURI(), 
 					  std::string("https://secondlife.com/helpers/"));
 		ensure_equals("getLoginPage", LLGridManager::getInstance()->getLoginPage(), 
-					  std::string("http://secondlife.com/app/login/"));
+					  std::string("http://viewer-login.agni.lindenlab.com/"));
 		ensure_equals("getLoginPage2", LLGridManager::getInstance()->getLoginPage("util.agni.lindenlab.com"), 
-					  std::string("http://secondlife.com/app/login/"));
+					  std::string("http://viewer-login.agni.lindenlab.com/"));
 		ensure("Is Agni a production grid", LLGridManager::getInstance()->isInProductionGrid());		
 		std::vector<std::string> uris;
 		LLGridManager::getInstance()->getLoginURIs(uris);
-- 
cgit v1.2.3


From 5f99d30c20bd4e23d17bbf78d2112f21ee840169 Mon Sep 17 00:00:00 2001
From: Aaron Stone <stone@lindenlab.com>
Date: Fri, 15 Jul 2011 16:25:32 -0700
Subject: STORM-1482 Always run the crash loggers, they will check what to do
 and how to clean up.

---
 indra/newview/llappviewer.cpp      |  5 ++-
 indra/newview/llappviewerlinux.cpp | 63 ++++++++++++++++----------------------
 indra/newview/llappviewerwin32.cpp |  6 +---
 3 files changed, 29 insertions(+), 45 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 6763881094..92e0513464 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2823,7 +2823,7 @@ bool LLAppViewer::initWindow()
 	// Need to load feature table before cheking to start watchdog.
 	bool use_watchdog = false;
 	int watchdog_enabled_setting = gSavedSettings.getS32("WatchdogEnabled");
-	if(watchdog_enabled_setting == -1)
+	if (watchdog_enabled_setting == -1)
 	{
 		use_watchdog = !LLFeatureManager::getInstance()->isFeatureAvailable("WatchdogDisabled");
 	}
@@ -2833,8 +2833,7 @@ bool LLAppViewer::initWindow()
 		use_watchdog = bool(watchdog_enabled_setting);
 	}
 
-	bool send_reports = gCrashSettings.getS32("CrashSubmitBehavior") != CRASH_BEHAVIOR_NEVER_SEND;
-	if(use_watchdog && send_reports)
+	if (use_watchdog)
 	{
 		LLWatchdog::getInstance()->init(watchdog_killer_callback);
 	}
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index 08d4f49147..48d02dfeaa 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -361,46 +361,35 @@ void LLAppViewerLinux::handleCrashReporting(bool reportFreeze)
 	}
 	else
 	{
-		const S32 cb = gCrashSettings.getS32("CrashSubmitBehavior");
-
-		// Always generate the report, have the logger do the asking, and
-		// don't wait for the logger before exiting (-> total cleanup).
-		if (CRASH_BEHAVIOR_NEVER_SEND != cb)
-		{	
-			// launch the actual crash logger
-			const char* ask_dialog = "-dialog";
-			if (CRASH_BEHAVIOR_ASK != cb)
-				ask_dialog = ""; // omit '-dialog' option
-			const char * cmdargv[] =
-				{cmd.c_str(),
-				 ask_dialog,
-				 "-user",
-				 (char*)LLGridManager::getInstance()->getGridLabel().c_str(),
-				 "-name",
-				 LLAppViewer::instance()->getSecondLifeTitle().c_str(),
-				 NULL};
-			fflush(NULL);
-			pid_t pid = fork();
-			if (pid == 0)
-			{ // child
-				execv(cmd.c_str(), (char* const*) cmdargv);		/* Flawfinder: ignore */
-				llwarns << "execv failure when trying to start " << cmd << llendl;
-				_exit(1); // avoid atexit()
+		// launch the actual crash logger
+		const char * cmdargv[] =
+			{cmd.c_str(),
+			 "-user",
+			 (char*)LLGridManager::getInstance()->getGridLabel().c_str(),
+			 "-name",
+			 LLAppViewer::instance()->getSecondLifeTitle().c_str(),
+			 NULL};
+		fflush(NULL);
+		pid_t pid = fork();
+		if (pid == 0)
+		{ // child
+			execv(cmd.c_str(), (char* const*) cmdargv);		/* Flawfinder: ignore */
+			llwarns << "execv failure when trying to start " << cmd << llendl;
+			_exit(1); // avoid atexit()
+		} 
+		else
+		{
+			if (pid > 0)
+			{
+				// DO NOT wait for child proc to die; we want
+				// the logger to outlive us while we quit to
+				// free up the screen/keyboard/etc.
+				////int childExitStatus;
+				////waitpid(pid, &childExitStatus, 0);
 			} 
 			else
 			{
-				if (pid > 0)
-				{
-					// DO NOT wait for child proc to die; we want
-					// the logger to outlive us while we quit to
-					// free up the screen/keyboard/etc.
-					////int childExitStatus;
-					////waitpid(pid, &childExitStatus, 0);
-				} 
-				else
-				{
-					llwarns << "fork failure." << llendl;
-				}
+				llwarns << "fork failure." << llendl;
 			}
 		}
 		// Sometimes signals don't seem to quit the viewer.  Also, we may
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 9280234ac3..f94c843ad9 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -518,11 +518,7 @@ void LLAppViewerWin32::handleCrashReporting(bool reportFreeze)
 	}
 	else
 	{
-		S32 cb = gCrashSettings.getS32("CrashSubmitBehavior");
-		if(cb != CRASH_BEHAVIOR_NEVER_SEND)
-		{
-			_spawnl(_P_NOWAIT, exe_path.c_str(), arg_str, NULL);
-		}
+		_spawnl(_P_NOWAIT, exe_path.c_str(), arg_str, NULL);
 	}
 }
 
-- 
cgit v1.2.3


From 86a806137be05b4be812a121fb6dc91dfacd037f Mon Sep 17 00:00:00 2001
From: jenn <jenn@lindenlab.com>
Date: Fri, 15 Jul 2011 23:26:19 +0000
Subject: After review and testing, realized that 'WatchdogEnabled' is actually
 true to its name, and is a boolean, not a timeout value.
 'MainloopTimeoutDefault' is the actual timeout value.

Updated descriptions and values accordingly to set Watchdog timeout to 60 seconds.
---
 indra/newview/app_settings/settings.xml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 2bd106a42e..1dfc84a4f7 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4894,7 +4894,7 @@
       <key>Type</key>
       <string>F32</string>
       <key>Value</key>
-      <real>20.0</real>
+      <real>60.0</real>
     </map>
     <key>MapOverlayIndex</key>
     <map>
@@ -12578,13 +12578,13 @@
     <key>WatchdogEnabled</key>
     <map>
       <key>Comment</key>
-      <string>Controls whether the thread watchdog timer is activated. Value is watchdog timeout in seconds. Set to -1 to disable.</string>
+      <string>Controls whether the thread watchdog timer is activated. Value is boolean. Set to -1 to defer to built-in default.</string>
       <key>Persist</key>
       <integer>0</integer>
       <key>Type</key>
       <string>S32</string>
       <key>Value</key>
-      <integer>60</integer>
+      <integer>1</integer>
     </map>
     <key>WaterGLFogDensityScale</key>
     <map>
-- 
cgit v1.2.3


From ec2d528952b15eb7d74202246d4841867c6e3a60 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Mon, 18 Jul 2011 08:30:21 -0400
Subject: re-enable the watchdog

---
 indra/newview/app_settings/settings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 91cbfde07f..4b62e376b5 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -12584,7 +12584,7 @@
       <key>Type</key>
       <string>S32</string>
       <key>Value</key>
-      <integer>-1</integer>
+      <integer>20</integer>
     </map>
     <key>WaterGLFogDensityScale</key>
     <map>
-- 
cgit v1.2.3


From 50d271a2ae28334b7dc1170d6222b3b4125fac6b Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Mon, 18 Jul 2011 08:31:32 -0400
Subject: increment viewer version to 2.8.2

---
 indra/llcommon/llversionviewer.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
index 0018b8e844..6c1d233425 100644
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -29,7 +29,7 @@
 
 const S32 LL_VERSION_MAJOR = 2;
 const S32 LL_VERSION_MINOR = 8;
-const S32 LL_VERSION_PATCH = 1;
+const S32 LL_VERSION_PATCH = 2;
 const S32 LL_VERSION_BUILD = 0;
 
 const char * const LL_CHANNEL = "Second Life Developer";
-- 
cgit v1.2.3


From 030b24188a290f63bec70cf4072f463e5dc6ee6a Mon Sep 17 00:00:00 2001
From: eli <none@none>
Date: Mon, 18 Jul 2011 11:09:58 -0700
Subject: sync with viewer-development

---
 indra/newview/skins/default/xui/en/panel_preferences_setup.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
index 1c22a5c02e..e639f0dc9d 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -268,7 +268,7 @@
      height="23"
      layout="topleft"
      left_delta="50"
-	 top_pad="5"
+     top_pad="5"
      name="updater_service_combobox"
      width="300">
         <combo_box.item
-- 
cgit v1.2.3