diff options
author | Jacek Antonelli | 2008-08-15 23:44:50 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:50 -0500 |
commit | 89fe5dab825a62a0e3fd8d248cbc91c65eb2a426 (patch) | |
tree | bcff14b7888d04a2fec799c59369f6095224bd08 /linden/indra/llvfs/lllfsthread.cpp | |
parent | Second Life viewer sources 1.13.3.2 (diff) | |
download | meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.zip meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.gz meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.bz2 meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.xz |
Second Life viewer sources 1.14.0.0
Diffstat (limited to 'linden/indra/llvfs/lllfsthread.cpp')
-rw-r--r-- | linden/indra/llvfs/lllfsthread.cpp | 235 |
1 files changed, 75 insertions, 160 deletions
diff --git a/linden/indra/llvfs/lllfsthread.cpp b/linden/indra/llvfs/lllfsthread.cpp index b7335e2..25edb52 100644 --- a/linden/indra/llvfs/lllfsthread.cpp +++ b/linden/indra/llvfs/lllfsthread.cpp | |||
@@ -38,10 +38,10 @@ | |||
38 | //============================================================================ | 38 | //============================================================================ |
39 | // Run on MAIN thread | 39 | // Run on MAIN thread |
40 | //static | 40 | //static |
41 | void LLLFSThread::initClass(bool local_is_threaded, bool local_run_always) | 41 | void LLLFSThread::initClass(bool local_is_threaded) |
42 | { | 42 | { |
43 | llassert(sLocal == NULL); | 43 | llassert(sLocal == NULL); |
44 | sLocal = new LLLFSThread(local_is_threaded, local_run_always); | 44 | sLocal = new LLLFSThread(local_is_threaded); |
45 | } | 45 | } |
46 | 46 | ||
47 | //static | 47 | //static |
@@ -65,8 +65,9 @@ void LLLFSThread::cleanupClass() | |||
65 | 65 | ||
66 | //---------------------------------------------------------------------------- | 66 | //---------------------------------------------------------------------------- |
67 | 67 | ||
68 | LLLFSThread::LLLFSThread(bool threaded, bool runalways) : | 68 | LLLFSThread::LLLFSThread(bool threaded) : |
69 | LLQueuedThread("LFS", threaded, runalways) | 69 | LLQueuedThread("LFS", threaded), |
70 | mPriorityCounter(PRIORITY_LOWBITS) | ||
70 | { | 71 | { |
71 | } | 72 | } |
72 | 73 | ||
@@ -77,251 +78,165 @@ LLLFSThread::~LLLFSThread() | |||
77 | 78 | ||
78 | //---------------------------------------------------------------------------- | 79 | //---------------------------------------------------------------------------- |
79 | 80 | ||
80 | LLLFSThread::handle_t LLLFSThread::read(const LLString& filename, | 81 | LLLFSThread::handle_t LLLFSThread::read(const LLString& filename, /* Flawfinder: ignore */ |
81 | U8* buffer, S32 offset, S32 numbytes, U32 priority, U32 flags) | 82 | U8* buffer, S32 offset, S32 numbytes, |
83 | Responder* responder, U32 priority) | ||
82 | { | 84 | { |
83 | handle_t handle = generateHandle(); | 85 | handle_t handle = generateHandle(); |
84 | 86 | ||
85 | priority = llmax(priority, (U32)PRIORITY_LOW); // All reads are at least PRIORITY_LOW | 87 | if (priority == 0) priority = PRIORITY_NORMAL | priorityCounter(); |
86 | Request* req = new Request(handle, priority, flags, | 88 | else if (priority < PRIORITY_LOW) priority |= PRIORITY_LOW; // All reads are at least PRIORITY_LOW |
89 | |||
90 | Request* req = new Request(this, handle, priority, | ||
87 | FILE_READ, filename, | 91 | FILE_READ, filename, |
88 | buffer, offset, numbytes); | 92 | buffer, offset, numbytes, |
93 | responder); | ||
89 | 94 | ||
90 | bool res = addRequest(req); | 95 | bool res = addRequest(req); |
91 | if (!res) | 96 | if (!res) |
92 | { | 97 | { |
93 | llerrs << "LLLFSThread::read called after LLLFSThread::cleanupClass()" << llendl; | 98 | llerrs << "LLLFSThread::read called after LLLFSThread::cleanupClass()" << llendl; |
94 | req->deleteRequest(); | ||
95 | handle = nullHandle(); | ||
96 | } | 99 | } |
97 | 100 | ||
98 | return handle; | 101 | return handle; |
99 | } | 102 | } |
100 | 103 | ||
101 | S32 LLLFSThread::readImmediate(const LLString& filename, | ||
102 | U8* buffer, S32 offset, S32 numbytes) | ||
103 | { | ||
104 | handle_t handle = generateHandle(); | ||
105 | |||
106 | Request* req = new Request(handle, PRIORITY_IMMEDIATE, 0, | ||
107 | FILE_READ, filename, | ||
108 | buffer, offset, numbytes); | ||
109 | |||
110 | S32 res = addRequest(req) ? 1 : 0; | ||
111 | if (res == 0) | ||
112 | { | ||
113 | llerrs << "LLLFSThread::read called after LLLFSThread::cleanupClass()" << llendl; | ||
114 | req->deleteRequest(); | ||
115 | } | ||
116 | else | ||
117 | { | ||
118 | llverify(waitForResult(handle, false) == true); | ||
119 | res = req->getBytesRead(); | ||
120 | completeRequest(handle); | ||
121 | } | ||
122 | return res; | ||
123 | } | ||
124 | |||
125 | LLLFSThread::handle_t LLLFSThread::write(const LLString& filename, | 104 | LLLFSThread::handle_t LLLFSThread::write(const LLString& filename, |
126 | U8* buffer, S32 offset, S32 numbytes, U32 flags) | 105 | U8* buffer, S32 offset, S32 numbytes, |
106 | Responder* responder, U32 priority) | ||
127 | { | 107 | { |
128 | handle_t handle = generateHandle(); | 108 | handle_t handle = generateHandle(); |
129 | 109 | ||
130 | Request* req = new Request(handle, 0, flags, | 110 | if (priority == 0) priority = PRIORITY_LOW | priorityCounter(); |
131 | FILE_WRITE, filename, | ||
132 | buffer, offset, numbytes); | ||
133 | |||
134 | bool res = addRequest(req); | ||
135 | if (!res) | ||
136 | { | ||
137 | llerrs << "LLLFSThread::read called after LLLFSThread::cleanupClass()" << llendl; | ||
138 | req->deleteRequest(); | ||
139 | handle = nullHandle(); | ||
140 | } | ||
141 | 111 | ||
142 | return handle; | 112 | Request* req = new Request(this, handle, priority, |
143 | } | ||
144 | |||
145 | S32 LLLFSThread::writeImmediate(const LLString& filename, | ||
146 | U8* buffer, S32 offset, S32 numbytes) | ||
147 | { | ||
148 | handle_t handle = generateHandle(); | ||
149 | |||
150 | Request* req = new Request(handle, PRIORITY_IMMEDIATE, 0, | ||
151 | FILE_WRITE, filename, | 113 | FILE_WRITE, filename, |
152 | buffer, offset, numbytes); | 114 | buffer, offset, numbytes, |
153 | 115 | responder); | |
154 | S32 res = addRequest(req) ? 1 : 0; | ||
155 | if (res == 0) | ||
156 | { | ||
157 | llerrs << "LLLFSThread::write called after LLLFSThread::cleanupClass()" << llendl; | ||
158 | req->deleteRequest(); | ||
159 | } | ||
160 | else | ||
161 | { | ||
162 | llverify(waitForResult(handle, false) == true); | ||
163 | res = req->getBytesRead(); | ||
164 | completeRequest(handle); | ||
165 | } | ||
166 | return res; | ||
167 | } | ||
168 | |||
169 | |||
170 | LLLFSThread::handle_t LLLFSThread::rename(const LLString& filename, const LLString& newname, U32 flags) | ||
171 | { | ||
172 | handle_t handle = generateHandle(); | ||
173 | |||
174 | LLString* new_name_str = new LLString(newname); // deleted with Request | ||
175 | Request* req = new Request(handle, 0, flags, | ||
176 | FILE_RENAME, filename, | ||
177 | (U8*)new_name_str, 0, 0); | ||
178 | |||
179 | bool res = addRequest(req); | ||
180 | if (!res) | ||
181 | { | ||
182 | llerrs << "LLLFSThread::rename called after LLLFSThread::cleanupClass()" << llendl; | ||
183 | req->deleteRequest(); | ||
184 | handle = nullHandle(); | ||
185 | } | ||
186 | |||
187 | return handle; | ||
188 | } | ||
189 | |||
190 | LLLFSThread::handle_t LLLFSThread::remove(const LLString& filename, U32 flags) | ||
191 | { | ||
192 | handle_t handle = generateHandle(); | ||
193 | |||
194 | Request* req = new Request(handle, 0, flags, | ||
195 | FILE_RENAME, filename, | ||
196 | NULL, 0, 0); | ||
197 | 116 | ||
198 | bool res = addRequest(req); | 117 | bool res = addRequest(req); |
199 | if (!res) | 118 | if (!res) |
200 | { | 119 | { |
201 | llerrs << "LLLFSThread::remove called after LLLFSThread::cleanupClass()" << llendl; | 120 | llerrs << "LLLFSThread::read called after LLLFSThread::cleanupClass()" << llendl; |
202 | req->deleteRequest(); | ||
203 | handle = nullHandle(); | ||
204 | } | 121 | } |
205 | 122 | ||
206 | return handle; | 123 | return handle; |
207 | } | 124 | } |
208 | 125 | ||
209 | //============================================================================ | 126 | //============================================================================ |
210 | // Runs on its OWN thread | ||
211 | |||
212 | bool LLLFSThread::processRequest(QueuedRequest* qreq) | ||
213 | { | ||
214 | Request *req = (Request*)qreq; | ||
215 | |||
216 | bool complete = req->processIO(); | ||
217 | |||
218 | return complete; | ||
219 | } | ||
220 | |||
221 | //============================================================================ | ||
222 | 127 | ||
223 | LLLFSThread::Request::Request(handle_t handle, U32 priority, U32 flags, | 128 | LLLFSThread::Request::Request(LLLFSThread* thread, |
129 | handle_t handle, U32 priority, | ||
224 | operation_t op, const LLString& filename, | 130 | operation_t op, const LLString& filename, |
225 | U8* buffer, S32 offset, S32 numbytes) : | 131 | U8* buffer, S32 offset, S32 numbytes, |
226 | QueuedRequest(handle, priority, flags), | 132 | Responder* responder) : |
133 | QueuedRequest(handle, priority, FLAG_AUTO_COMPLETE), | ||
134 | mThread(thread), | ||
227 | mOperation(op), | 135 | mOperation(op), |
228 | mFileName(filename), | 136 | mFileName(filename), |
229 | mBuffer(buffer), | 137 | mBuffer(buffer), |
230 | mOffset(offset), | 138 | mOffset(offset), |
231 | mBytes(numbytes), | 139 | mBytes(numbytes), |
232 | mBytesRead(0) | 140 | mBytesRead(0), |
141 | mResponder(responder) | ||
233 | { | 142 | { |
234 | llassert(mBuffer); | 143 | if (numbytes <= 0) |
235 | |||
236 | if (numbytes <= 0 && mOperation != FILE_RENAME && mOperation != FILE_REMOVE) | ||
237 | { | 144 | { |
238 | llwarns << "LLLFSThread: Request with numbytes = " << numbytes << llendl; | 145 | llwarns << "LLLFSThread: Request with numbytes = " << numbytes << llendl; |
239 | } | 146 | } |
240 | } | 147 | } |
241 | 148 | ||
242 | void LLLFSThread::Request::finishRequest() | 149 | LLLFSThread::Request::~Request() |
243 | { | 150 | { |
244 | } | 151 | } |
245 | 152 | ||
153 | // virtual, called from own thread | ||
154 | void LLLFSThread::Request::finishRequest(bool completed) | ||
155 | { | ||
156 | if (mResponder.notNull()) | ||
157 | { | ||
158 | mResponder->completed(completed ? mBytesRead : 0); | ||
159 | mResponder = NULL; | ||
160 | } | ||
161 | } | ||
162 | |||
246 | void LLLFSThread::Request::deleteRequest() | 163 | void LLLFSThread::Request::deleteRequest() |
247 | { | 164 | { |
248 | if (getStatus() == STATUS_QUEUED || getStatus() == STATUS_ABORT) | 165 | if (getStatus() == STATUS_QUEUED) |
249 | { | 166 | { |
250 | llerrs << "Attempt to delete a queued LLLFSThread::Request!" << llendl; | 167 | llerrs << "Attempt to delete a queued LLLFSThread::Request!" << llendl; |
251 | } | 168 | } |
252 | if (mOperation == FILE_WRITE) | 169 | if (mResponder.notNull()) |
253 | { | ||
254 | if (mFlags & AUTO_DELETE) | ||
255 | { | ||
256 | delete mBuffer; | ||
257 | } | ||
258 | } | ||
259 | else if (mOperation == FILE_RENAME) | ||
260 | { | 170 | { |
261 | LLString* new_name = (LLString*)mBuffer; | 171 | mResponder->completed(0); |
262 | delete new_name; | 172 | mResponder = NULL; |
263 | } | 173 | } |
264 | LLQueuedThread::QueuedRequest::deleteRequest(); | 174 | LLQueuedThread::QueuedRequest::deleteRequest(); |
265 | } | 175 | } |
266 | 176 | ||
267 | bool LLLFSThread::Request::processIO() | 177 | bool LLLFSThread::Request::processRequest() |
268 | { | 178 | { |
269 | bool complete = false; | 179 | bool complete = false; |
270 | if (mOperation == FILE_READ) | 180 | if (mOperation == FILE_READ) |
271 | { | 181 | { |
272 | llassert(mOffset >= 0); | 182 | llassert(mOffset >= 0); |
273 | apr_file_t* filep = ll_apr_file_open(mFileName, LL_APR_RB); | 183 | apr_file_t* filep = ll_apr_file_open(mFileName, LL_APR_RB, mThread->mAPRPoolp); |
274 | if (!filep) | 184 | if (!filep) |
275 | { | 185 | { |
276 | llwarns << "LLLFS: Unable to read file: " << mFileName << llendl; | 186 | llwarns << "LLLFS: Unable to read file: " << mFileName << llendl; |
277 | mBytesRead = 0; // fail | 187 | mBytesRead = 0; // fail |
278 | return true; | 188 | return true; |
279 | } | 189 | } |
190 | S32 off; | ||
280 | if (mOffset < 0) | 191 | if (mOffset < 0) |
281 | ll_apr_file_seek(filep, APR_END, 0); | 192 | off = ll_apr_file_seek(filep, APR_END, 0); |
282 | else | 193 | else |
283 | ll_apr_file_seek(filep, APR_SET, mOffset); | 194 | off = ll_apr_file_seek(filep, APR_SET, mOffset); |
195 | llassert_always(off >= 0); | ||
284 | mBytesRead = ll_apr_file_read(filep, mBuffer, mBytes ); | 196 | mBytesRead = ll_apr_file_read(filep, mBuffer, mBytes ); |
285 | apr_file_close(filep); | 197 | apr_file_close(filep); |
286 | complete = true; | 198 | complete = true; |
287 | //llinfos << llformat("LLLFSThread::READ '%s': %d bytes",mFileName.c_str(),mBytesRead) << llendl; | 199 | // llinfos << "LLLFSThread::READ:" << mFileName << " Bytes: " << mBytesRead << llendl; |
288 | } | 200 | } |
289 | else if (mOperation == FILE_WRITE) | 201 | else if (mOperation == FILE_WRITE) |
290 | { | 202 | { |
291 | apr_file_t* filep = ll_apr_file_open(mFileName, LL_APR_WB); | 203 | apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY; |
204 | if (mOffset < 0) | ||
205 | flags |= APR_APPEND; | ||
206 | apr_file_t* filep = ll_apr_file_open(mFileName, flags, mThread->mAPRPoolp); | ||
292 | if (!filep) | 207 | if (!filep) |
293 | { | 208 | { |
294 | llwarns << "LLLFS: Unable to write file: " << mFileName << llendl; | 209 | llwarns << "LLLFS: Unable to write file: " << mFileName << llendl; |
295 | mBytesRead = 0; // fail | 210 | mBytesRead = 0; // fail |
296 | return true; | 211 | return true; |
297 | } | 212 | } |
298 | if (mOffset < 0) | 213 | if (mOffset >= 0) |
299 | ll_apr_file_seek(filep, APR_END, 0); | 214 | { |
300 | else | 215 | S32 seek = ll_apr_file_seek(filep, APR_SET, mOffset); |
301 | ll_apr_file_seek(filep, APR_SET, mOffset); | 216 | if (seek < 0) |
217 | { | ||
218 | apr_file_close(filep); | ||
219 | llwarns << "LLLFS: Unable to write file (seek failed): " << mFileName << llendl; | ||
220 | mBytesRead = 0; // fail | ||
221 | return true; | ||
222 | } | ||
223 | } | ||
302 | mBytesRead = ll_apr_file_write(filep, mBuffer, mBytes ); | 224 | mBytesRead = ll_apr_file_write(filep, mBuffer, mBytes ); |
303 | complete = true; | 225 | complete = true; |
304 | apr_file_close(filep); | 226 | apr_file_close(filep); |
305 | //llinfos << llformat("LLLFSThread::WRITE '%s': %d bytes",mFileName.c_str(),mBytesRead) << llendl; | 227 | // llinfos << "LLLFSThread::WRITE:" << mFileName << " Bytes: " << mBytesRead << "/" << mBytes << " Offset:" << mOffset << llendl; |
306 | } | ||
307 | else if (mOperation == FILE_RENAME) | ||
308 | { | ||
309 | LLString* new_name = (LLString*)mBuffer; | ||
310 | ll_apr_file_rename(mFileName, *new_name); | ||
311 | complete = true; | ||
312 | //llinfos << llformat("LLLFSThread::RENAME '%s': '%s'",mFileName.c_str(),new_name->c_str()) << llendl; | ||
313 | } | ||
314 | else if (mOperation == FILE_REMOVE) | ||
315 | { | ||
316 | ll_apr_file_remove(mFileName); | ||
317 | complete = true; | ||
318 | //llinfos << llformat("LLLFSThread::REMOVE '%s'",mFileName.c_str()) << llendl; | ||
319 | } | 228 | } |
320 | else | 229 | else |
321 | { | 230 | { |
322 | llerrs << llformat("LLLFSThread::unknown operation: %d", mOperation) << llendl; | 231 | llerrs << "LLLFSThread::unknown operation: " << (S32)mOperation << llendl; |
323 | } | 232 | } |
324 | return complete; | 233 | return complete; |
325 | } | 234 | } |
326 | 235 | ||
327 | //============================================================================ | 236 | //============================================================================ |
237 | |||
238 | LLLFSThread::Responder::~Responder() | ||
239 | { | ||
240 | } | ||
241 | |||
242 | //============================================================================ | ||