From 15a6d273cc00e1f4f9f9d56d8c878b46b283b289 Mon Sep 17 00:00:00 2001
From: Andrew Meadows <andrew@lindenlab.com>
Date: Sat, 17 Jan 2009 01:29:45 +0000
Subject: [PATCH] svn merge -r108142:108148
 svn+ssh://svn.lindenlab.com/svn/linden/qa/maint-server/maint-server-5-r108113

---
 indra/lib/python/indra/base/llsd.py           |   2 +
 indra/llcommon/llapp.h                        |   2 +
 indra/llcommon/lluuid.cpp                     |   7 +-
 indra/llinventory/llpermissions.cpp           |   9 +
 indra/llinventory/llpermissions.h             |   5 +
 indra/llmessage/llpumpio.cpp                  |  11 +-
 indra/llvfs/CMakeLists.txt                    |   2 +
 indra/llvfs/llpidlock.cpp                     | 268 ++++++++++++++++++
 indra/llvfs/llpidlock.h                       |  72 +++++
 indra/lscript/lscript_execute.h               |   7 +
 .../lscript_execute/lscript_execute.cpp       |   9 +-
 indra/newview/lltooldraganddrop.cpp           |   1 +
 install.xml                                   |   2 +-
 13 files changed, 385 insertions(+), 12 deletions(-)
 create mode 100755 indra/llvfs/llpidlock.cpp
 create mode 100755 indra/llvfs/llpidlock.h

diff --git a/indra/lib/python/indra/base/llsd.py b/indra/lib/python/indra/base/llsd.py
index 05fbc81b9c6..9534d5935eb 100644
--- a/indra/lib/python/indra/base/llsd.py
+++ b/indra/lib/python/indra/base/llsd.py
@@ -28,6 +28,7 @@
 
 import datetime
 import base64
+import string
 import struct
 import time
 import types
@@ -940,6 +941,7 @@ def parse_notation(something):
 
 def parse(something):
     try:
+        something = string.lstrip(something)   #remove any pre-trailing whitespace
         if something.startswith('<?llsd/binary?>'):
             return parse_binary(something)
         # This should be better.
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index d3bd438872e..f8a593c33d7 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -189,6 +189,8 @@ class LLApp
 #if !LL_WINDOWS
 	static U32  getSigChildCount();
 	static void incSigChildCount();
+#else
+#define getpid GetCurrentProcessId
 #endif
 	static int getPid();
 
diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp
index 3fd0d042b90..bcbae06ec56 100644
--- a/indra/llcommon/lluuid.cpp
+++ b/indra/llcommon/lluuid.cpp
@@ -209,7 +209,7 @@ std::string LLUUID::asString() const
 
 BOOL LLUUID::set(const char* in_string, BOOL emit)
 {
-	return set(ll_safe_string(in_string));
+	return set(ll_safe_string(in_string),emit);
 }
 
 BOOL LLUUID::set(const std::string& in_string, BOOL emit)
@@ -231,7 +231,7 @@ BOOL LLUUID::set(const std::string& in_string, BOOL emit)
 		{
 			if(emit)
 			{
-				llinfos << "Warning! Using broken UUID string format" << llendl;
+				llwarns << "Warning! Using broken UUID string format" << llendl;
 			}
 			broken_format = TRUE;
 		}
@@ -240,7 +240,8 @@ BOOL LLUUID::set(const std::string& in_string, BOOL emit)
 			// Bad UUID string.  Spam as INFO, as most cases we don't care.
 			if(emit)
 			{
-				llinfos << "Bad UUID string: " << in_string << llendl;
+				//don't spam the logs because a resident can't spell.
+				llwarns << "Bad UUID string: " << in_string << llendl;
 			}
 			setNull();
 			return FALSE;
diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp
index b610b2b54e6..328ed4588bf 100644
--- a/indra/llinventory/llpermissions.cpp
+++ b/indra/llinventory/llpermissions.cpp
@@ -277,6 +277,15 @@ BOOL LLPermissions::setOwnerAndGroup(
 	return allowed;
 }
 
+// only call this if you know what you're doing
+// there are usually perm-bit consequences when the 
+// ownerhsip changes
+void LLPermissions::yesReallySetOwner(const LLUUID& owner, bool group_owned)
+{
+	mOwner = owner;
+	mIsGroupOwned = group_owned;
+}
+
 BOOL LLPermissions::deedToGroup(const LLUUID& agent, const LLUUID& group)
 {
 	if(group.notNull() && (agent.isNull() || ((group == mGroup)
diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h
index 1c70ddb168a..5587f8c3c83 100644
--- a/indra/llinventory/llpermissions.h
+++ b/indra/llinventory/llpermissions.h
@@ -224,6 +224,11 @@ class LLPermissions : public LLReflective
 	// item.
 	BOOL setOwnerAndGroup(const LLUUID& agent, const LLUUID& owner, const LLUUID& group, bool is_atomic);	
 
+	// only call this if you know what you're doing
+	// there are usually perm-bit consequences when the 
+	// ownerhsip changes
+	void yesReallySetOwner(const LLUUID& owner, bool group_owned);
+
 	// saves last owner, sets owner to uuid null, sets group
 	// owned. group_id must be the group of the object (that's who it
 	// is being deeded to) and the object must be group
diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp
index 70f28f3a3e4..3e3f0b37a7d 100644
--- a/indra/llmessage/llpumpio.cpp
+++ b/indra/llmessage/llpumpio.cpp
@@ -181,6 +181,8 @@ LLPumpIO::LLPumpIO(apr_pool_t* pool) :
 	mCallbackMutex(NULL),
 	mCurrentChain(mRunningChains.end())
 {
+	mCurrentChain = mRunningChains.end();
+
 	LLMemType m1(LLMemType::MTYPE_IO_PUMP);
 	initialize(pool);
 }
@@ -274,12 +276,11 @@ bool LLPumpIO::setTimeoutSeconds(F32 timeout)
 
 void LLPumpIO::adjustTimeoutSeconds(F32 delta)
 {
-	// If no chain is running, bail
-	if(mRunningChains.end() == mCurrentChain) 
+	// Ensure a chain is running
+	if(mRunningChains.end() != mCurrentChain)
 	{
-		return;
+		(*mCurrentChain).adjustTimeoutSeconds(delta);
 	}
-	(*mCurrentChain).adjustTimeoutSeconds(delta);
 }
 
 static std::string events_2_string(apr_int16_t events)
@@ -549,7 +550,7 @@ void LLPumpIO::pump(const S32& poll_timeout)
 	//lldebugs << "Running chain count: " << mRunningChains.size() << llendl;
 	running_chains_t::iterator run_chain = mRunningChains.begin();
 	bool process_this_chain = false;
-	for(; run_chain != mRunningChains.end(); )
+	while( run_chain != mRunningChains.end() )
 	{
 		PUMP_DEBUG;
 		if((*run_chain).mInit
diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt
index c3c12efdd02..cc0297e3dc9 100644
--- a/indra/llvfs/CMakeLists.txt
+++ b/indra/llvfs/CMakeLists.txt
@@ -13,6 +13,7 @@ include_directories(
 set(llvfs_SOURCE_FILES
     lldir.cpp
     lllfsthread.cpp
+    llpidlock.cpp
     llvfile.cpp
     llvfs.cpp
     llvfsthread.cpp
@@ -23,6 +24,7 @@ set(llvfs_HEADER_FILES
 
     lldir.h
     lllfsthread.h
+    llpidlock.h
     llvfile.h
     llvfs.h
     llvfsthread.h
diff --git a/indra/llvfs/llpidlock.cpp b/indra/llvfs/llpidlock.cpp
new file mode 100755
index 00000000000..e231002a527
--- /dev/null
+++ b/indra/llvfs/llpidlock.cpp
@@ -0,0 +1,268 @@
+/** 
+ * @file llformat.cpp
+ * @date   January 2007
+ * @brief string formatting utility
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ * 
+ * Copyright (c) 2007, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llpidlock.h"
+#include "lldir.h"
+#include "llsd.h"
+#include "llsdserialize.h"
+#include "llnametable.h"
+#include "llframetimer.h"
+
+#if LL_WINDOWS   //For windows platform.
+bool isProcessAlive(U32 pid)
+{
+	return (bool) GetProcessVersion((DWORD)pid);
+}
+
+#else   //Everyone Else
+bool isProcessAlive(U32 pid)
+{   
+	return (bool) kill( (pid_t)pid, 0);
+}
+#endif //Everyone else.
+
+
+	
+class LLPidLockFile
+{
+	public:
+		LLPidLockFile( ) :
+			mSaving(FALSE), mWaiting(FALSE), 
+			mClean(TRUE), mPID(getpid())
+		{
+			mLockName = gDirUtilp->getTempDir() + "/savelock";
+		}
+		bool requestLock(LLNameTable<void *> *name_table, bool autosave,
+						bool force_immediate=FALSE, F32 timeout=300.0);
+		bool checkLock();
+		void releaseLock();
+
+	private:
+		void writeLockFile(LLSD pids);
+	public:
+		static LLPidLockFile& instance(); // return the singleton black list file
+			 
+		bool mAutosave;
+		bool mSaving;
+		bool mWaiting;
+		LLFrameTimer mTimer;
+		U32  mPID;
+		std::string mLockName;
+		std::string mSaveName;
+		LLSD mPIDS_sd;
+		LLNameTable<void*> *mNameTable;
+		bool mClean;
+};
+
+LLPidLockFile& LLPidLockFile::instance()
+{   
+	static LLPidLockFile the_file;
+	return the_file;
+}
+
+void LLPidLockFile::writeLockFile(LLSD pids)
+{
+	llofstream ofile(mLockName);
+
+	if (!LLSDSerialize::toXML(pids,ofile))
+	{
+		llwarns << "Unable to write concurrent save lock file." << llendl;
+	}
+	ofile.close();
+}
+
+bool LLPidLockFile::requestLock(LLNameTable<void *> *name_table, bool autosave,
+								bool force_immediate, F32 timeout)
+{
+	bool readyToSave = FALSE;
+
+	if (mSaving) return FALSE;	//Bail out if we're currently saving.  Will not queue another save.
+	
+	if (!mWaiting){
+		mNameTable=name_table;
+		mAutosave = autosave;
+	}
+
+	LLSD out_pids;
+	out_pids.append( (LLSD::Integer)mPID );
+
+	llifstream ifile(mLockName);
+
+	if (ifile.is_open()) 
+	{									//If file exists, we need to decide whether or not to continue.
+		if ( force_immediate
+			|| mTimer.hasExpired() )	//Only deserialize if we REALLY need to.
+		{
+
+			LLSD in_pids;
+
+			LLSDSerialize::fromXML(in_pids, ifile);	
+
+			//Clean up any dead PIDS that might be in there.
+			for (LLSD::array_iterator i=in_pids.beginArray();
+				i !=in_pids.endArray();
+				++i)
+			{
+				U32 stored_pid=(*i).asInteger();
+
+				if (isProcessAlive(stored_pid))
+				{
+					out_pids.append( (*i) );
+				}
+			}
+
+			readyToSave=TRUE;
+		}
+		ifile.close();
+	}
+	else
+	{
+		readyToSave=TRUE;
+	}
+
+	if (!mWaiting)				//Not presently waiting to save.  Queue up.
+	{
+		mTimer.resetWithExpiry(timeout);
+		mWaiting=TRUE;
+	}
+
+	if (readyToSave)
+	{	//Potential race condition won't kill us. Ignore it.
+		writeLockFile(out_pids);
+		mSaving=TRUE;
+	}
+	
+	return readyToSave;
+}
+
+bool LLPidLockFile::checkLock()
+{
+	return mWaiting;
+}
+
+void LLPidLockFile::releaseLock()
+{
+	llifstream ifile(mLockName);
+	LLSD in_pids;
+	LLSD out_pids;
+	bool write_file=FALSE;
+
+	LLSDSerialize::fromXML(in_pids, ifile);	
+
+	//Clean up this PID and any dead ones.
+	for (LLSD::array_iterator i=in_pids.beginArray();
+		i !=in_pids.endArray();
+		++i)
+	{
+		U32 stored_pid=(*i).asInteger();
+
+		if (stored_pid != mPID && isProcessAlive(stored_pid))
+		{
+			out_pids.append( (*i) );
+			write_file=TRUE;
+		}
+	}
+	ifile.close();
+
+	if (write_file)
+	{
+		writeLockFile(out_pids);
+	}
+	else
+	{
+		unlink(mLockName.c_str());
+	}
+
+	mSaving=FALSE;
+	mWaiting=FALSE;
+}
+
+//LLPidLock
+
+void LLPidLock::initClass() { 
+	(void) LLPidLockFile::instance(); 
+}
+
+bool LLPidLock::checkLock() 
+{
+	return LLPidLockFile::instance().checkLock();
+}
+
+bool LLPidLock::requestLock(LLNameTable<void *> *name_table, bool autosave,
+								bool force_immediate, F32 timeout)
+{
+	return LLPidLockFile::instance().requestLock(name_table,autosave,force_immediate,timeout);
+}
+
+void LLPidLock::releaseLock() 
+{ 
+	return LLPidLockFile::instance().releaseLock(); 
+}
+
+bool LLPidLock::isClean() 
+{ 
+	return LLPidLockFile::instance().mClean; 
+}
+
+//getters
+LLNameTable<void *> * LLPidLock::getNameTable() 
+{ 
+    return LLPidLockFile::instance().mNameTable; 
+}
+
+bool LLPidLock::getAutosave() 
+{ 
+	return LLPidLockFile::instance().mAutosave; 
+}
+
+bool LLPidLock::getClean() 
+{ 
+	return LLPidLockFile::instance().mClean; 
+}
+
+std::string LLPidLock::getSaveName() 
+{ 
+	return LLPidLockFile::instance().mSaveName; 
+}
+
+//setters
+void LLPidLock::setClean(bool clean) 
+{ 
+	LLPidLockFile::instance().mClean=clean; 
+}
+
+void LLPidLock::setSaveName(std::string savename) 
+{ 
+	LLPidLockFile::instance().mSaveName=savename; 
+}
diff --git a/indra/llvfs/llpidlock.h b/indra/llvfs/llpidlock.h
new file mode 100755
index 00000000000..44ed8caf463
--- /dev/null
+++ b/indra/llvfs/llpidlock.h
@@ -0,0 +1,72 @@
+/** 
+ * @file llpidlock.h
+ * @brief System information debugging classes.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-2007, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_PIDLOCK_H
+#define LL_PIDLOCK_H
+#include "llnametable.h"
+
+class LLSD;
+class LLFrameTimer;
+
+#if LL_WINDOWS	//For windows platform.
+
+#include <windows.h>
+
+#define getpid GetCurrentProcessId
+
+#else	//Everyone Else
+
+#include <signal.h>
+
+#endif //Everyone else.
+
+namespace LLPidLock
+{
+    void initClass(); // { (void) LLPidLockFile::instance(); }
+
+	bool requestLock( LLNameTable<void *> *name_table=NULL, bool autosave=TRUE,
+					  bool force_immediate=FALSE, F32 timeout=300.0);
+	bool checkLock(); 
+	void releaseLock(); 
+	bool isClean(); 
+
+	//getters
+	LLNameTable<void *> * getNameTable(); 
+	bool getAutosave(); 
+	bool getClean(); 
+	std::string getSaveName(); 
+
+	//setters
+	void setClean(bool clean); 
+	void setSaveName(std::string savename); 
+};
+
+#endif // LL_PIDLOCK_H
diff --git a/indra/lscript/lscript_execute.h b/indra/lscript/lscript_execute.h
index b1b866570cd..a22c37cfe9e 100644
--- a/indra/lscript/lscript_execute.h
+++ b/indra/lscript/lscript_execute.h
@@ -452,9 +452,16 @@ class LLScriptExecute
 	// Called when the script is scheduled to be stopped from newsim/LLScriptData
 	virtual void stopRunning() = 0;
 	
+	// A timer is regularly checked to see if script takes too long, but we
+	// don't do it every opcode due to performance hits.
+	static void		setTimerCheckSkip( S32 value )			{ sTimerCheckSkip = value;		}
+	static S32		getTimerCheckSkip()						{ return sTimerCheckSkip;		}
+
 private:
 
 	BOOL mReset;
+
+	static	S32		sTimerCheckSkip;		// Number of times to skip the timer check for performance reasons
 };
 
 class LLScriptExecuteLSL2 : public LLScriptExecute
diff --git a/indra/lscript/lscript_execute/lscript_execute.cpp b/indra/lscript/lscript_execute/lscript_execute.cpp
index 43834758f13..5630f2de0b5 100644
--- a/indra/lscript/lscript_execute/lscript_execute.cpp
+++ b/indra/lscript/lscript_execute/lscript_execute.cpp
@@ -42,6 +42,10 @@
 #include "lscript_heapruntime.h"
 #include "lscript_alloc.h"
 
+// Static
+const	S32	DEFAULT_SCRIPT_TIMER_CHECK_SKIP = 4;
+S32		LLScriptExecute::sTimerCheckSkip = DEFAULT_SCRIPT_TIMER_CHECK_SKIP;
+
 void (*binary_operations[LST_EOF][LST_EOF])(U8 *buffer, LSCRIPTOpCodesEnum opcode);
 void (*unary_operations[LST_EOF])(U8 *buffer, LSCRIPTOpCodesEnum opcode);
 
@@ -924,7 +928,7 @@ void LLScriptExecute::runInstructions(BOOL b_print, const LLUUID &id,
 // Run for a single timeslice, or until a yield or state transition is due
 F32 LLScriptExecute::runQuanta(BOOL b_print, const LLUUID &id, const char **errorstr, F32 quanta, U32& events_processed, LLTimer& timer)
 {
-	U32 timer_checks = 0;
+	S32 timer_checks = 0;
 	F32 inloop = 0;
 
 	// Loop while not finished, yield not due and time remaining
@@ -936,12 +940,11 @@ F32 LLScriptExecute::runQuanta(BOOL b_print, const LLUUID &id, const char **erro
 		runInstructions(b_print, id, errorstr,
 						events_processed, quanta);
 		
-		static const S32 lsl_timer_check_skip = 4;
 		if(isYieldDue())
 		{
 			break;
 		}
-		else if(timer_checks++ == lsl_timer_check_skip)
+		else if(timer_checks++ >= LLScriptExecute::sTimerCheckSkip)
 		{
 			inloop = timer.getElapsedTimeF32();
 			if(inloop > quanta)
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 5f9d88fb31e..db864765b17 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -2902,6 +2902,7 @@ LLInventoryObject* LLToolDragAndDrop::locateMultipleInventory(LLViewerInventoryC
 
 void pack_permissions_slam(LLMessageSystem* msg, U32 flags, const LLPermissions& perms)
 {
+	// CRUFT -- the server no longer pays attention to this data
 	U32 group_mask		= perms.getMaskGroup();
 	U32 everyone_mask	= perms.getMaskEveryone();
 	U32 next_owner_mask	= perms.getMaskNextOwner();
diff --git a/install.xml b/install.xml
index 659076bf286..07b5f781442 100644
--- a/install.xml
+++ b/install.xml
@@ -867,7 +867,7 @@ anguage Infrstructure (CLI) international standard</string>
             <key>md5sum</key>
             <string>6712a09311a914752f47d5d62562a239</string>
             <key>url</key>
-            <uri>https://s3.amazonaws.com/viewer-source-downloads/install_pkgs/libmono-1.2.6-windows-20080903.tar.bz2</uri>
+            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/libmono-1.2.6-windows-20080903.tar.bz2</uri>
           </map>
         </map>
       </map>
-- 
GitLab