diff options
Diffstat (limited to 'indra/llvfs/lllfsthread.cpp')
-rw-r--r-- | indra/llvfs/lllfsthread.cpp | 233 |
1 files changed, 74 insertions, 159 deletions
diff --git a/indra/llvfs/lllfsthread.cpp b/indra/llvfs/lllfsthread.cpp index 6af638fd12..598de1d370 100644 --- a/indra/llvfs/lllfsthread.cpp +++ b/indra/llvfs/lllfsthread.cpp @@ -19,10 +19,10 @@ //============================================================================ // Run on MAIN thread //static -void LLLFSThread::initClass(bool local_is_threaded, bool local_run_always) +void LLLFSThread::initClass(bool local_is_threaded) { llassert(sLocal == NULL); - sLocal = new LLLFSThread(local_is_threaded, local_run_always); + sLocal = new LLLFSThread(local_is_threaded); } //static @@ -46,8 +46,9 @@ void LLLFSThread::cleanupClass() //---------------------------------------------------------------------------- -LLLFSThread::LLLFSThread(bool threaded, bool runalways) : - LLQueuedThread("LFS", threaded, runalways) +LLLFSThread::LLLFSThread(bool threaded) : + LLQueuedThread("LFS", threaded), + mPriorityCounter(PRIORITY_LOWBITS) { } @@ -59,250 +60,164 @@ LLLFSThread::~LLLFSThread() //---------------------------------------------------------------------------- LLLFSThread::handle_t LLLFSThread::read(const LLString& filename, /* Flawfinder: ignore */ - U8* buffer, S32 offset, S32 numbytes, U32 priority, U32 flags) + U8* buffer, S32 offset, S32 numbytes, + Responder* responder, U32 priority) { handle_t handle = generateHandle(); - priority = llmax(priority, (U32)PRIORITY_LOW); // All reads are at least PRIORITY_LOW - Request* req = new Request(handle, priority, flags, + if (priority == 0) priority = PRIORITY_NORMAL | priorityCounter(); + else if (priority < PRIORITY_LOW) priority |= PRIORITY_LOW; // All reads are at least PRIORITY_LOW + + Request* req = new Request(this, handle, priority, FILE_READ, filename, - buffer, offset, numbytes); + buffer, offset, numbytes, + responder); bool res = addRequest(req); if (!res) { llerrs << "LLLFSThread::read called after LLLFSThread::cleanupClass()" << llendl; - req->deleteRequest(); - handle = nullHandle(); } return handle; } -S32 LLLFSThread::readImmediate(const LLString& filename, - U8* buffer, S32 offset, S32 numbytes) -{ - handle_t handle = generateHandle(); - - Request* req = new Request(handle, PRIORITY_IMMEDIATE, 0, - FILE_READ, filename, - buffer, offset, numbytes); - - S32 res = addRequest(req) ? 1 : 0; - if (res == 0) - { - llerrs << "LLLFSThread::read called after LLLFSThread::cleanupClass()" << llendl; - req->deleteRequest(); - } - else - { - llverify(waitForResult(handle, false) == true); - res = req->getBytesRead(); - completeRequest(handle); - } - return res; -} - LLLFSThread::handle_t LLLFSThread::write(const LLString& filename, - U8* buffer, S32 offset, S32 numbytes, U32 flags) + U8* buffer, S32 offset, S32 numbytes, + Responder* responder, U32 priority) { handle_t handle = generateHandle(); - Request* req = new Request(handle, 0, flags, - FILE_WRITE, filename, - buffer, offset, numbytes); - - bool res = addRequest(req); - if (!res) - { - llerrs << "LLLFSThread::read called after LLLFSThread::cleanupClass()" << llendl; - req->deleteRequest(); - handle = nullHandle(); - } + if (priority == 0) priority = PRIORITY_LOW | priorityCounter(); - return handle; -} - -S32 LLLFSThread::writeImmediate(const LLString& filename, - U8* buffer, S32 offset, S32 numbytes) -{ - handle_t handle = generateHandle(); - - Request* req = new Request(handle, PRIORITY_IMMEDIATE, 0, + Request* req = new Request(this, handle, priority, FILE_WRITE, filename, - buffer, offset, numbytes); - - S32 res = addRequest(req) ? 1 : 0; - if (res == 0) - { - llerrs << "LLLFSThread::write called after LLLFSThread::cleanupClass()" << llendl; - req->deleteRequest(); - } - else - { - llverify(waitForResult(handle, false) == true); - res = req->getBytesRead(); - completeRequest(handle); - } - return res; -} - - -LLLFSThread::handle_t LLLFSThread::rename(const LLString& filename, const LLString& newname, U32 flags) -{ - handle_t handle = generateHandle(); - - LLString* new_name_str = new LLString(newname); // deleted with Request - Request* req = new Request(handle, 0, flags, - FILE_RENAME, filename, - (U8*)new_name_str, 0, 0); - - bool res = addRequest(req); - if (!res) - { - llerrs << "LLLFSThread::rename called after LLLFSThread::cleanupClass()" << llendl; - req->deleteRequest(); - handle = nullHandle(); - } - - return handle; -} - -LLLFSThread::handle_t LLLFSThread::remove(const LLString& filename, U32 flags) -{ - handle_t handle = generateHandle(); - - Request* req = new Request(handle, 0, flags, - FILE_RENAME, filename, - NULL, 0, 0); + buffer, offset, numbytes, + responder); bool res = addRequest(req); if (!res) { - llerrs << "LLLFSThread::remove called after LLLFSThread::cleanupClass()" << llendl; - req->deleteRequest(); - handle = nullHandle(); + llerrs << "LLLFSThread::read called after LLLFSThread::cleanupClass()" << llendl; } return handle; } //============================================================================ -// Runs on its OWN thread - -bool LLLFSThread::processRequest(QueuedRequest* qreq) -{ - Request *req = (Request*)qreq; - - bool complete = req->processIO(); - - return complete; -} - -//============================================================================ -LLLFSThread::Request::Request(handle_t handle, U32 priority, U32 flags, +LLLFSThread::Request::Request(LLLFSThread* thread, + handle_t handle, U32 priority, operation_t op, const LLString& filename, - U8* buffer, S32 offset, S32 numbytes) : - QueuedRequest(handle, priority, flags), + U8* buffer, S32 offset, S32 numbytes, + Responder* responder) : + QueuedRequest(handle, priority, FLAG_AUTO_COMPLETE), + mThread(thread), mOperation(op), mFileName(filename), mBuffer(buffer), mOffset(offset), mBytes(numbytes), - mBytesRead(0) + mBytesRead(0), + mResponder(responder) { - llassert(mBuffer); - - if (numbytes <= 0 && mOperation != FILE_RENAME && mOperation != FILE_REMOVE) + if (numbytes <= 0) { llwarns << "LLLFSThread: Request with numbytes = " << numbytes << llendl; } } -void LLLFSThread::Request::finishRequest() +LLLFSThread::Request::~Request() { } +// virtual, called from own thread +void LLLFSThread::Request::finishRequest(bool completed) +{ + if (mResponder.notNull()) + { + mResponder->completed(completed ? mBytesRead : 0); + mResponder = NULL; + } +} + void LLLFSThread::Request::deleteRequest() { - if (getStatus() == STATUS_QUEUED || getStatus() == STATUS_ABORT) + if (getStatus() == STATUS_QUEUED) { llerrs << "Attempt to delete a queued LLLFSThread::Request!" << llendl; } - if (mOperation == FILE_WRITE) - { - if (mFlags & AUTO_DELETE) - { - delete mBuffer; - } - } - else if (mOperation == FILE_RENAME) + if (mResponder.notNull()) { - LLString* new_name = (LLString*)mBuffer; - delete new_name; + mResponder->completed(0); + mResponder = NULL; } LLQueuedThread::QueuedRequest::deleteRequest(); } -bool LLLFSThread::Request::processIO() +bool LLLFSThread::Request::processRequest() { bool complete = false; if (mOperation == FILE_READ) { llassert(mOffset >= 0); - apr_file_t* filep = ll_apr_file_open(mFileName, LL_APR_RB); + apr_file_t* filep = ll_apr_file_open(mFileName, LL_APR_RB, mThread->mAPRPoolp); if (!filep) { llwarns << "LLLFS: Unable to read file: " << mFileName << llendl; mBytesRead = 0; // fail return true; } + S32 off; if (mOffset < 0) - ll_apr_file_seek(filep, APR_END, 0); + off = ll_apr_file_seek(filep, APR_END, 0); else - ll_apr_file_seek(filep, APR_SET, mOffset); + off = ll_apr_file_seek(filep, APR_SET, mOffset); + llassert_always(off >= 0); mBytesRead = ll_apr_file_read(filep, mBuffer, mBytes ); apr_file_close(filep); complete = true; - //llinfos << llformat("LLLFSThread::READ '%s': %d bytes",mFileName.c_str(),mBytesRead) << llendl; +// llinfos << "LLLFSThread::READ:" << mFileName << " Bytes: " << mBytesRead << llendl; } else if (mOperation == FILE_WRITE) { - apr_file_t* filep = ll_apr_file_open(mFileName, LL_APR_WB); + apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY; + if (mOffset < 0) + flags |= APR_APPEND; + apr_file_t* filep = ll_apr_file_open(mFileName, flags, mThread->mAPRPoolp); if (!filep) { llwarns << "LLLFS: Unable to write file: " << mFileName << llendl; mBytesRead = 0; // fail return true; } - if (mOffset < 0) - ll_apr_file_seek(filep, APR_END, 0); - else - ll_apr_file_seek(filep, APR_SET, mOffset); + if (mOffset >= 0) + { + S32 seek = ll_apr_file_seek(filep, APR_SET, mOffset); + if (seek < 0) + { + apr_file_close(filep); + llwarns << "LLLFS: Unable to write file (seek failed): " << mFileName << llendl; + mBytesRead = 0; // fail + return true; + } + } mBytesRead = ll_apr_file_write(filep, mBuffer, mBytes ); complete = true; apr_file_close(filep); - //llinfos << llformat("LLLFSThread::WRITE '%s': %d bytes",mFileName.c_str(),mBytesRead) << llendl; - } - else if (mOperation == FILE_RENAME) - { - LLString* new_name = (LLString*)mBuffer; - ll_apr_file_rename(mFileName, *new_name); - complete = true; - //llinfos << llformat("LLLFSThread::RENAME '%s': '%s'",mFileName.c_str(),new_name->c_str()) << llendl; - } - else if (mOperation == FILE_REMOVE) - { - ll_apr_file_remove(mFileName); - complete = true; - //llinfos << llformat("LLLFSThread::REMOVE '%s'",mFileName.c_str()) << llendl; +// llinfos << "LLLFSThread::WRITE:" << mFileName << " Bytes: " << mBytesRead << "/" << mBytes << " Offset:" << mOffset << llendl; } else { - llerrs << llformat("LLLFSThread::unknown operation: %d", mOperation) << llendl; + llerrs << "LLLFSThread::unknown operation: " << (S32)mOperation << llendl; } return complete; } //============================================================================ + +LLLFSThread::Responder::~Responder() +{ +} + +//============================================================================ |