aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llvfs/llvfsthread.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llvfs/llvfsthread.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llvfs/llvfsthread.cpp')
-rw-r--r--linden/indra/llvfs/llvfsthread.cpp314
1 files changed, 314 insertions, 0 deletions
diff --git a/linden/indra/llvfs/llvfsthread.cpp b/linden/indra/llvfs/llvfsthread.cpp
new file mode 100644
index 0000000..be23bd5
--- /dev/null
+++ b/linden/indra/llvfs/llvfsthread.cpp
@@ -0,0 +1,314 @@
1/**
2 * @file llvfsthread.cpp
3 * @brief LLVFSThread implementation
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29#include "llmath.h"
30#include "llvfsthread.h"
31#include "llstl.h"
32
33//============================================================================
34
35/*static*/ std::string LLVFSThread::sDataPath = "";
36
37/*static*/ LLVFSThread* LLVFSThread::sLocal = NULL;
38
39//============================================================================
40// Run on MAIN thread
41//static
42void LLVFSThread::initClass(bool local_is_threaded, bool local_run_always)
43{
44 llassert(sLocal == NULL);
45 sLocal = new LLVFSThread(local_is_threaded, local_run_always);
46}
47
48//static
49S32 LLVFSThread::updateClass(U32 ms_elapsed)
50{
51 sLocal->update(ms_elapsed);
52 return sLocal->getPending();
53}
54
55//static
56void LLVFSThread::cleanupClass()
57{
58 sLocal->setQuitting();
59 while (sLocal->getPending())
60 {
61 sLocal->update(0);
62 }
63 delete sLocal;
64 sLocal = 0;
65}
66
67//----------------------------------------------------------------------------
68
69LLVFSThread::LLVFSThread(bool threaded, bool runalways) :
70 LLQueuedThread("VFS", threaded, runalways)
71{
72}
73
74LLVFSThread::~LLVFSThread()
75{
76 // ~LLQueuedThread() will be called here
77}
78
79//----------------------------------------------------------------------------
80
81LLVFSThread::handle_t LLVFSThread::read(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
82 U8* buffer, S32 offset, S32 numbytes, U32 priority, U32 flags)
83{
84 handle_t handle = generateHandle();
85
86 priority = llmax(priority, (U32)PRIORITY_LOW); // All reads are at least PRIORITY_LOW
87 Request* req = new Request(handle, priority, flags, FILE_READ, vfs, file_id, file_type,
88 buffer, offset, numbytes);
89
90 bool res = addRequest(req);
91 if (!res)
92 {
93 llerrs << "LLVFSThread::read called after LLVFSThread::cleanupClass()" << llendl;
94 req->deleteRequest();
95 handle = nullHandle();
96 }
97
98 return handle;
99}
100
101S32 LLVFSThread::readImmediate(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
102 U8* buffer, S32 offset, S32 numbytes)
103{
104 handle_t handle = generateHandle();
105
106 Request* req = new Request(handle, PRIORITY_IMMEDIATE, 0, FILE_READ, vfs, file_id, file_type,
107 buffer, offset, numbytes);
108
109 S32 res = addRequest(req) ? 1 : 0;
110 if (res == 0)
111 {
112 llerrs << "LLVFSThread::read called after LLVFSThread::cleanupClass()" << llendl;
113 req->deleteRequest();
114 }
115 else
116 {
117 llverify(waitForResult(handle, false) == true);
118 res = req->getBytesRead();
119 completeRequest(handle);
120 }
121 return res;
122}
123
124LLVFSThread::handle_t LLVFSThread::write(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
125 U8* buffer, S32 offset, S32 numbytes, U32 flags)
126{
127 handle_t handle = generateHandle();
128
129 Request* req = new Request(handle, 0, flags, FILE_WRITE, vfs, file_id, file_type,
130 buffer, offset, numbytes);
131
132 bool res = addRequest(req);
133 if (!res)
134 {
135 llerrs << "LLVFSThread::read called after LLVFSThread::cleanupClass()" << llendl;
136 req->deleteRequest();
137 handle = nullHandle();
138 }
139
140 return handle;
141}
142
143S32 LLVFSThread::writeImmediate(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
144 U8* buffer, S32 offset, S32 numbytes)
145{
146 handle_t handle = generateHandle();
147
148 Request* req = new Request(handle, PRIORITY_IMMEDIATE, 0, FILE_WRITE, vfs, file_id, file_type,
149 buffer, offset, numbytes);
150
151 S32 res = addRequest(req) ? 1 : 0;
152 if (res == 0)
153 {
154 llerrs << "LLVFSThread::read called after LLVFSThread::cleanupClass()" << llendl;
155 req->deleteRequest();
156 }
157 else
158 {
159 llverify(waitForResult(handle, false) == true);
160 res = req->getBytesRead();
161 completeRequest(handle);
162 }
163 return res;
164}
165
166
167LLVFSThread::handle_t LLVFSThread::rename(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
168 const LLUUID &new_id, const LLAssetType::EType new_type, U32 flags)
169{
170 handle_t handle = generateHandle();
171
172 LLUUID* new_idp = new LLUUID(new_id); // deleted with Request
173 // new_type is passed as "numbytes"
174 Request* req = new Request(handle, 0, flags, FILE_RENAME, vfs, file_id, file_type,
175 (U8*)new_idp, 0, (S32)new_type);
176
177 bool res = addRequest(req);
178 if (!res)
179 {
180 llerrs << "LLVFSThread::read called after LLVFSThread::cleanupClass()" << llendl;
181 req->deleteRequest();
182 handle = nullHandle();
183 }
184
185 return handle;
186}
187
188//============================================================================
189// Runs on its OWN thread
190
191bool LLVFSThread::processRequest(QueuedRequest* qreq)
192{
193 Request *req = (Request*)qreq;
194
195 bool complete = req->processIO();
196
197 return complete;
198}
199
200//============================================================================
201
202LLVFSThread::Request::Request(handle_t handle, U32 priority, U32 flags,
203 operation_t op, LLVFS* vfs,
204 const LLUUID &file_id, const LLAssetType::EType file_type,
205 U8* buffer, S32 offset, S32 numbytes) :
206 QueuedRequest(handle, priority, flags),
207 mOperation(op),
208 mVFS(vfs),
209 mFileID(file_id),
210 mFileType(file_type),
211 mBuffer(buffer),
212 mOffset(offset),
213 mBytes(numbytes),
214 mBytesRead(0)
215{
216 llassert(mBuffer);
217
218 if (numbytes <= 0 && mOperation != FILE_RENAME)
219 {
220 llwarns << "LLVFSThread: Request with numbytes = " << numbytes
221 << " operation = " << op
222 << " offset " << offset
223 << " file_type " << file_type << llendl;
224 }
225 if (mOperation == FILE_WRITE)
226 {
227 S32 blocksize = mVFS->getMaxSize(mFileID, mFileType);
228 if (blocksize < 0)
229 {
230 llwarns << "VFS write to temporary block (shouldn't happen)" << llendl;
231 }
232 mVFS->incLock(mFileID, mFileType, VFSLOCK_APPEND);
233 }
234 else if (mOperation == FILE_RENAME)
235 {
236 mVFS->incLock(mFileID, mFileType, VFSLOCK_APPEND);
237 }
238 else // if (mOperation == FILE_READ)
239 {
240 mVFS->incLock(mFileID, mFileType, VFSLOCK_READ);
241 }
242}
243
244// dec locks as soon as a request finishes
245void LLVFSThread::Request::finishRequest()
246{
247 if (mOperation == FILE_WRITE)
248 {
249 mVFS->decLock(mFileID, mFileType, VFSLOCK_APPEND);
250 }
251 else if (mOperation == FILE_RENAME)
252 {
253 mVFS->decLock(mFileID, mFileType, VFSLOCK_APPEND);
254 }
255 else // if (mOperation == FILE_READ)
256 {
257 mVFS->decLock(mFileID, mFileType, VFSLOCK_READ);
258 }
259}
260
261void LLVFSThread::Request::deleteRequest()
262{
263 if (getStatus() == STATUS_QUEUED || getStatus() == STATUS_ABORT)
264 {
265 llerrs << "Attempt to delete a queued LLVFSThread::Request!" << llendl;
266 }
267 if (mOperation == FILE_WRITE)
268 {
269 if (mFlags & AUTO_DELETE)
270 {
271 delete [] mBuffer;
272 }
273 }
274 else if (mOperation == FILE_RENAME)
275 {
276 LLUUID* new_idp = (LLUUID*)mBuffer;
277 delete new_idp;
278 }
279 LLQueuedThread::QueuedRequest::deleteRequest();
280}
281
282bool LLVFSThread::Request::processIO()
283{
284 bool complete = false;
285 if (mOperation == FILE_READ)
286 {
287 llassert(mOffset >= 0);
288 mBytesRead = mVFS->getData(mFileID, mFileType, mBuffer, mOffset, mBytes);
289 complete = true;
290 //llinfos << llformat("LLVFSThread::READ '%s': %d bytes arg:%d",getFilename(),mBytesRead) << llendl;
291 }
292 else if (mOperation == FILE_WRITE)
293 {
294 mBytesRead = mVFS->storeData(mFileID, mFileType, mBuffer, mOffset, mBytes);
295 complete = true;
296 //llinfos << llformat("LLVFSThread::WRITE '%s': %d bytes arg:%d",getFilename(),mBytesRead) << llendl;
297 }
298 else if (mOperation == FILE_RENAME)
299 {
300 LLUUID* new_idp = (LLUUID*)mBuffer;
301 LLAssetType::EType new_type = (LLAssetType::EType)mBytes;
302 mVFS->renameFile(mFileID, mFileType, *new_idp, new_type);
303 mFileID = *new_idp;
304 complete = true;
305 //llinfos << llformat("LLVFSThread::WRITE '%s': %d bytes arg:%d",getFilename(),mBytesRead) << llendl;
306 }
307 else
308 {
309 llerrs << llformat("LLVFSThread::unknown operation: %d", mOperation) << llendl;
310 }
311 return complete;
312}
313
314//============================================================================