aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llvfs/llpidlock.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2009-04-30 13:04:20 -0500
committerJacek Antonelli2009-04-30 13:07:16 -0500
commitca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e (patch)
tree8348301d0ac44a524f1819b777686bf086907d76 /linden/indra/llvfs/llpidlock.cpp
parentSecond Life viewer sources 1.22.11 (diff)
downloadmeta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.zip
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.gz
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.bz2
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.xz
Second Life viewer sources 1.23.0-RC
Diffstat (limited to 'linden/indra/llvfs/llpidlock.cpp')
-rwxr-xr-xlinden/indra/llvfs/llpidlock.cpp269
1 files changed, 269 insertions, 0 deletions
diff --git a/linden/indra/llvfs/llpidlock.cpp b/linden/indra/llvfs/llpidlock.cpp
new file mode 100755
index 0000000..93ac120
--- /dev/null
+++ b/linden/indra/llvfs/llpidlock.cpp
@@ -0,0 +1,269 @@
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-2009, 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
34#include "linden_common.h"
35
36#include "llpidlock.h"
37#include "lldir.h"
38#include "llsd.h"
39#include "llsdserialize.h"
40#include "llnametable.h"
41#include "llframetimer.h"
42
43#if LL_WINDOWS //For windows platform.
44bool isProcessAlive(U32 pid)
45{
46 return (bool) GetProcessVersion((DWORD)pid);
47}
48
49#else //Everyone Else
50bool isProcessAlive(U32 pid)
51{
52 return (bool) kill( (pid_t)pid, 0);
53}
54#endif //Everyone else.
55
56
57
58class LLPidLockFile
59{
60 public:
61 LLPidLockFile( ) :
62 mSaving(FALSE), mWaiting(FALSE),
63 mClean(TRUE), mPID(getpid())
64 {
65 mLockName = gDirUtilp->getTempDir() + "/savelock";
66 }
67 bool requestLock(LLNameTable<void *> *name_table, bool autosave,
68 bool force_immediate=FALSE, F32 timeout=300.0);
69 bool checkLock();
70 void releaseLock();
71
72 private:
73 void writeLockFile(LLSD pids);
74 public:
75 static LLPidLockFile& instance(); // return the singleton black list file
76
77 bool mAutosave;
78 bool mSaving;
79 bool mWaiting;
80 LLFrameTimer mTimer;
81 U32 mPID;
82 std::string mLockName;
83 std::string mSaveName;
84 LLSD mPIDS_sd;
85 LLNameTable<void*> *mNameTable;
86 bool mClean;
87};
88
89LLPidLockFile& LLPidLockFile::instance()
90{
91 static LLPidLockFile the_file;
92 return the_file;
93}
94
95void LLPidLockFile::writeLockFile(LLSD pids)
96{
97 llofstream ofile(mLockName);
98
99 if (!LLSDSerialize::toXML(pids,ofile))
100 {
101 llwarns << "Unable to write concurrent save lock file." << llendl;
102 }
103 ofile.close();
104}
105
106bool LLPidLockFile::requestLock(LLNameTable<void *> *name_table, bool autosave,
107 bool force_immediate, F32 timeout)
108{
109 bool readyToSave = FALSE;
110
111 if (mSaving) return FALSE; //Bail out if we're currently saving. Will not queue another save.
112
113 if (!mWaiting){
114 mNameTable=name_table;
115 mAutosave = autosave;
116 }
117
118 LLSD out_pids;
119 out_pids.append( (LLSD::Integer)mPID );
120
121 llifstream ifile(mLockName);
122
123 if (ifile.is_open())
124 { //If file exists, we need to decide whether or not to continue.
125 if ( force_immediate
126 || mTimer.hasExpired() ) //Only deserialize if we REALLY need to.
127 {
128
129 LLSD in_pids;
130
131 LLSDSerialize::fromXML(in_pids, ifile);
132
133 //Clean up any dead PIDS that might be in there.
134 for (LLSD::array_iterator i=in_pids.beginArray();
135 i !=in_pids.endArray();
136 ++i)
137 {
138 U32 stored_pid=(*i).asInteger();
139
140 if (isProcessAlive(stored_pid))
141 {
142 out_pids.append( (*i) );
143 }
144 }
145
146 readyToSave=TRUE;
147 }
148 ifile.close();
149 }
150 else
151 {
152 readyToSave=TRUE;
153 }
154
155 if (!mWaiting) //Not presently waiting to save. Queue up.
156 {
157 mTimer.resetWithExpiry(timeout);
158 mWaiting=TRUE;
159 }
160
161 if (readyToSave)
162 { //Potential race condition won't kill us. Ignore it.
163 writeLockFile(out_pids);
164 mSaving=TRUE;
165 }
166
167 return readyToSave;
168}
169
170bool LLPidLockFile::checkLock()
171{
172 return mWaiting;
173}
174
175void LLPidLockFile::releaseLock()
176{
177 llifstream ifile(mLockName);
178 LLSD in_pids;
179 LLSD out_pids;
180 bool write_file=FALSE;
181
182 LLSDSerialize::fromXML(in_pids, ifile);
183
184 //Clean up this PID and any dead ones.
185 for (LLSD::array_iterator i=in_pids.beginArray();
186 i !=in_pids.endArray();
187 ++i)
188 {
189 U32 stored_pid=(*i).asInteger();
190
191 if (stored_pid != mPID && isProcessAlive(stored_pid))
192 {
193 out_pids.append( (*i) );
194 write_file=TRUE;
195 }
196 }
197 ifile.close();
198
199 if (write_file)
200 {
201 writeLockFile(out_pids);
202 }
203 else
204 {
205 unlink(mLockName.c_str());
206 }
207
208 mSaving=FALSE;
209 mWaiting=FALSE;
210}
211
212//LLPidLock
213
214void LLPidLock::initClass() {
215 (void) LLPidLockFile::instance();
216}
217
218bool LLPidLock::checkLock()
219{
220 return LLPidLockFile::instance().checkLock();
221}
222
223bool LLPidLock::requestLock(LLNameTable<void *> *name_table, bool autosave,
224 bool force_immediate, F32 timeout)
225{
226 return LLPidLockFile::instance().requestLock(name_table,autosave,force_immediate,timeout);
227}
228
229void LLPidLock::releaseLock()
230{
231 return LLPidLockFile::instance().releaseLock();
232}
233
234bool LLPidLock::isClean()
235{
236 return LLPidLockFile::instance().mClean;
237}
238
239//getters
240LLNameTable<void *> * LLPidLock::getNameTable()
241{
242 return LLPidLockFile::instance().mNameTable;
243}
244
245bool LLPidLock::getAutosave()
246{
247 return LLPidLockFile::instance().mAutosave;
248}
249
250bool LLPidLock::getClean()
251{
252 return LLPidLockFile::instance().mClean;
253}
254
255std::string LLPidLock::getSaveName()
256{
257 return LLPidLockFile::instance().mSaveName;
258}
259
260//setters
261void LLPidLock::setClean(bool clean)
262{
263 LLPidLockFile::instance().mClean=clean;
264}
265
266void LLPidLock::setSaveName(std::string savename)
267{
268 LLPidLockFile::instance().mSaveName=savename;
269}