diff options
Diffstat (limited to 'indra/llvfs')
| -rw-r--r-- | indra/llvfs/CMakeLists.txt | 2 | ||||
| -rwxr-xr-x | indra/llvfs/llpidlock.cpp | 268 | ||||
| -rwxr-xr-x | indra/llvfs/llpidlock.h | 72 | 
3 files changed, 342 insertions, 0 deletions
| diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt index c3c12efdd0..cc0297e3dc 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 0000000000..e231002a52 --- /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 0000000000..44ed8caf46 --- /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 | 
