diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index cc545243204ed519860f213fcdf9b64765f70b83..5856e06b67510e9686a0eeaefa07ece22a094cf4 100755
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -174,7 +174,7 @@ set(llcommon_HEADER_FILES
     llmetrics.h
     llmetricperformancetester.h
     llmortician.h
-    llmutex.h
+    llnametable.h
     llpointer.h
     llpredicate.h
     llpreprocessor.h
diff --git a/indra/llcommon/llnametable.h b/indra/llcommon/llnametable.h
new file mode 100644
index 0000000000000000000000000000000000000000..d3283543f3921f2d00e23ee5e1c06a6b3c2dbb64
--- /dev/null
+++ b/indra/llcommon/llnametable.h
@@ -0,0 +1,105 @@
+/** 
+ * @file llnametable.h
+ * @brief LLNameTable class is a table to associate pointers with string names
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, 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_LLNAMETABLE_H
+#define LL_LLNAMETABLE_H
+
+#include <map>
+
+#include "string_table.h"
+
+template <class DATA>
+class LLNameTable
+{
+public:
+	LLNameTable()
+	:	mNameMap()
+	{
+	}
+
+	~LLNameTable() 
+	{ 
+	}
+
+	void addEntry(const std::string& name, DATA data)
+	{
+		addEntry(name.c_str(), data);
+	}
+
+	void addEntry(const char *name, DATA data)
+	{
+		char *tablename = gStringTable.addString(name);
+		mNameMap[tablename] = data;
+	}
+
+	BOOL checkName(const std::string& name) const
+	{
+		return checkName(name.c_str());
+	}
+
+	// "logically const" even though it modifies the global nametable
+	BOOL checkName(const char *name) const
+	{
+		char *tablename = gStringTable.addString(name);
+		return mNameMap.count(tablename) ? TRUE : FALSE;
+	}
+
+	DATA resolveName(const std::string& name) const
+	{
+		return resolveName(name.c_str());
+	}
+
+	// "logically const" even though it modifies the global nametable
+	DATA resolveName(const char *name) const
+	{
+		char *tablename = gStringTable.addString(name);
+		const_iter_t iter = mNameMap.find(tablename);
+		if (iter != mNameMap.end())
+			return iter->second;
+		else
+			return 0;
+	}
+
+	// O(N)! (currently only used in one place... (newsim/llstate.cpp))
+	const char *resolveData(const DATA &data) const
+	{
+		const_iter_t iter = mNameMap.begin();
+		const_iter_t end = mNameMap.end();
+		for (; iter != end; ++iter)
+		{
+			if (iter->second == data)
+				return iter->first;
+		}
+   		return NULL;
+	}		
+
+	typedef std::map<const char *, DATA> name_map_t;
+	typedef typename std::map<const char *,DATA>::iterator iter_t;
+	typedef typename std::map<const char *,DATA>::const_iterator const_iter_t;
+	name_map_t		mNameMap;
+};
+
+#endif
diff --git a/indra/llcommon/string_table.h b/indra/llcommon/string_table.h
new file mode 100644
index 0000000000000000000000000000000000000000..fe6416fb5066aa1d60ab390675794a99a31aee5b
--- /dev/null
+++ b/indra/llcommon/string_table.h
@@ -0,0 +1,26 @@
+/** 
+ * @file string_table.h
+ * @brief Legacy wrapper header.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, 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 "llstringtable.h"
diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt
index f19fdf48902189137afeefa0df7b8ac0114110fb..67dce8c0737e7fda21ff4fb057451aeac2e1bc0f 100755
--- a/indra/llvfs/CMakeLists.txt
+++ b/indra/llvfs/CMakeLists.txt
@@ -15,6 +15,7 @@ set(llvfs_SOURCE_FILES
     lldir.cpp
     lldiriterator.cpp
     lllfsthread.cpp
+    llpidlock.cpp
     llvfile.cpp
     llvfs.cpp
     llvfsthread.cpp
@@ -27,6 +28,7 @@ set(llvfs_HEADER_FILES
     lldirguard.h
     lldiriterator.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 100644
index 0000000000000000000000000000000000000000..e64368e8d771e207323371f769b39de81ae300b1
--- /dev/null
+++ b/indra/llvfs/llpidlock.cpp
@@ -0,0 +1,275 @@
+/** 
+ * @file llformat.cpp
+ * @date   January 2007
+ * @brief string formatting utility
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, 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 "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.
+
+#include <windows.h>
+
+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( ) :
+			mAutosave(false),
+			mSaving(false),
+			mWaiting(false),
+			mPID(getpid()),
+			mNameTable(NULL),
+			mClean(true)
+		{
+			mLockName = gDirUtilp->getTempDir() + gDirUtilp->getDirDelimiter() + "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))
+	{
+		LL_WARNS() << "Unable to write concurrent save lock file." << LL_ENDL;
+	}
+	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; 
+}
+
+S32 LLPidLock::getPID()
+{
+    return (S32)getpid();
+}
diff --git a/indra/llvfs/llpidlock.h b/indra/llvfs/llpidlock.h
new file mode 100644
index 0000000000000000000000000000000000000000..334f26bb294b13a4bd2c30e16ad581bd97a9c693
--- /dev/null
+++ b/indra/llvfs/llpidlock.h
@@ -0,0 +1,60 @@
+/** 
+ * @file llpidlock.h
+ * @brief System information debugging classes.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, 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_PIDLOCK_H
+#define LL_PIDLOCK_H
+#include "llnametable.h"
+
+class LLSD;
+class LLFrameTimer;
+
+#if !LL_WINDOWS	//For non-windows platforms.
+#include <signal.h>
+#endif
+
+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();
+    S32 getPID();
+
+    //setters
+    void setClean(bool clean);
+    void setSaveName(std::string savename);
+};
+
+#endif // LL_PIDLOCK_H