llpidlock.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:6k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llformat.cpp
  3.  * @date   January 2007
  4.  * @brief string formatting utility
  5.  *
  6.  * $LicenseInfo:firstyear=2007&license=viewergpl$
  7.  * 
  8.  * Copyright (c) 2007-2010, Linden Research, Inc.
  9.  * 
  10.  * Second Life Viewer Source Code
  11.  * The source code in this file ("Source Code") is provided by Linden Lab
  12.  * to you under the terms of the GNU General Public License, version 2.0
  13.  * ("GPL"), unless you have obtained a separate licensing agreement
  14.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  15.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17.  * 
  18.  * There are special exceptions to the terms and conditions of the GPL as
  19.  * it is applied to this Source Code. View the full text of the exception
  20.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  21.  * online at
  22.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23.  * 
  24.  * By copying, modifying or distributing this software, you acknowledge
  25.  * that you have read and understood your obligations described above,
  26.  * and agree to abide by those obligations.
  27.  * 
  28.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30.  * COMPLETENESS OR PERFORMANCE.
  31.  * $/LicenseInfo$
  32.  */
  33. #include "linden_common.h"
  34. #include "llpidlock.h"
  35. #include "lldir.h"
  36. #include "llsd.h"
  37. #include "llsdserialize.h"
  38. #include "llnametable.h"
  39. #include "llframetimer.h"
  40. #if LL_WINDOWS   //For windows platform.
  41. #include <windows.h>
  42. namespace {
  43. inline DWORD getpid() {
  44. return GetCurrentProcessId();
  45. }
  46. }
  47. bool isProcessAlive(U32 pid)
  48. {
  49. return (bool) GetProcessVersion((DWORD)pid);
  50. }
  51. #else   //Everyone Else
  52. bool isProcessAlive(U32 pid)
  53. {   
  54. return (bool) kill( (pid_t)pid, 0);
  55. }
  56. #endif //Everyone else.
  57. class LLPidLockFile
  58. {
  59. public:
  60. LLPidLockFile( ) :
  61. mAutosave(false),
  62. mSaving(false),
  63. mWaiting(false),
  64. mPID(getpid()),
  65. mNameTable(NULL),
  66. mClean(true)
  67. {
  68. mLockName = gDirUtilp->getTempDir() + gDirUtilp->getDirDelimiter() + "savelock";
  69. }
  70. bool requestLock(LLNameTable<void *> *name_table, bool autosave,
  71. bool force_immediate=FALSE, F32 timeout=300.0);
  72. bool checkLock();
  73. void releaseLock();
  74. private:
  75. void writeLockFile(LLSD pids);
  76. public:
  77. static LLPidLockFile& instance(); // return the singleton black list file
  78.  
  79. bool mAutosave;
  80. bool mSaving;
  81. bool mWaiting;
  82. LLFrameTimer mTimer;
  83. U32  mPID;
  84. std::string mLockName;
  85. std::string mSaveName;
  86. LLSD mPIDS_sd;
  87. LLNameTable<void*> *mNameTable;
  88. bool mClean;
  89. };
  90. LLPidLockFile& LLPidLockFile::instance()
  91. {   
  92. static LLPidLockFile the_file;
  93. return the_file;
  94. }
  95. void LLPidLockFile::writeLockFile(LLSD pids)
  96. {
  97. llofstream ofile(mLockName);
  98. if (!LLSDSerialize::toXML(pids,ofile))
  99. {
  100. llwarns << "Unable to write concurrent save lock file." << llendl;
  101. }
  102. ofile.close();
  103. }
  104. bool LLPidLockFile::requestLock(LLNameTable<void *> *name_table, bool autosave,
  105. bool force_immediate, F32 timeout)
  106. {
  107. bool readyToSave = FALSE;
  108. if (mSaving) return FALSE; //Bail out if we're currently saving.  Will not queue another save.
  109. if (!mWaiting){
  110. mNameTable=name_table;
  111. mAutosave = autosave;
  112. }
  113. LLSD out_pids;
  114. out_pids.append( (LLSD::Integer)mPID );
  115. llifstream ifile(mLockName);
  116. if (ifile.is_open()) 
  117. { //If file exists, we need to decide whether or not to continue.
  118. if ( force_immediate
  119. || mTimer.hasExpired() ) //Only deserialize if we REALLY need to.
  120. {
  121. LLSD in_pids;
  122. LLSDSerialize::fromXML(in_pids, ifile);
  123. //Clean up any dead PIDS that might be in there.
  124. for (LLSD::array_iterator i=in_pids.beginArray();
  125. i !=in_pids.endArray();
  126. ++i)
  127. {
  128. U32 stored_pid=(*i).asInteger();
  129. if (isProcessAlive(stored_pid))
  130. {
  131. out_pids.append( (*i) );
  132. }
  133. }
  134. readyToSave=TRUE;
  135. }
  136. ifile.close();
  137. }
  138. else
  139. {
  140. readyToSave=TRUE;
  141. }
  142. if (!mWaiting) //Not presently waiting to save.  Queue up.
  143. {
  144. mTimer.resetWithExpiry(timeout);
  145. mWaiting=TRUE;
  146. }
  147. if (readyToSave)
  148. { //Potential race condition won't kill us. Ignore it.
  149. writeLockFile(out_pids);
  150. mSaving=TRUE;
  151. }
  152. return readyToSave;
  153. }
  154. bool LLPidLockFile::checkLock()
  155. {
  156. return mWaiting;
  157. }
  158. void LLPidLockFile::releaseLock()
  159. {
  160. llifstream ifile(mLockName);
  161. LLSD in_pids;
  162. LLSD out_pids;
  163. bool write_file=FALSE;
  164. LLSDSerialize::fromXML(in_pids, ifile);
  165. //Clean up this PID and any dead ones.
  166. for (LLSD::array_iterator i=in_pids.beginArray();
  167. i !=in_pids.endArray();
  168. ++i)
  169. {
  170. U32 stored_pid=(*i).asInteger();
  171. if (stored_pid != mPID && isProcessAlive(stored_pid))
  172. {
  173. out_pids.append( (*i) );
  174. write_file=TRUE;
  175. }
  176. }
  177. ifile.close();
  178. if (write_file)
  179. {
  180. writeLockFile(out_pids);
  181. }
  182. else
  183. {
  184. unlink(mLockName.c_str());
  185. }
  186. mSaving=FALSE;
  187. mWaiting=FALSE;
  188. }
  189. //LLPidLock
  190. void LLPidLock::initClass() { 
  191. (void) LLPidLockFile::instance(); 
  192. }
  193. bool LLPidLock::checkLock() 
  194. {
  195. return LLPidLockFile::instance().checkLock();
  196. }
  197. bool LLPidLock::requestLock(LLNameTable<void *> *name_table, bool autosave,
  198. bool force_immediate, F32 timeout)
  199. {
  200. return LLPidLockFile::instance().requestLock(name_table,autosave,force_immediate,timeout);
  201. }
  202. void LLPidLock::releaseLock() 
  203. return LLPidLockFile::instance().releaseLock(); 
  204. }
  205. bool LLPidLock::isClean() 
  206. return LLPidLockFile::instance().mClean; 
  207. }
  208. //getters
  209. LLNameTable<void *> * LLPidLock::getNameTable() 
  210.     return LLPidLockFile::instance().mNameTable; 
  211. }
  212. bool LLPidLock::getAutosave() 
  213. return LLPidLockFile::instance().mAutosave; 
  214. }
  215. bool LLPidLock::getClean() 
  216. return LLPidLockFile::instance().mClean; 
  217. }
  218. std::string LLPidLock::getSaveName() 
  219. return LLPidLockFile::instance().mSaveName; 
  220. }
  221. //setters
  222. void LLPidLock::setClean(bool clean) 
  223. LLPidLockFile::instance().mClean=clean; 
  224. }
  225. void LLPidLock::setSaveName(std::string savename) 
  226. LLPidLockFile::instance().mSaveName=savename; 
  227. }