summaryrefslogtreecommitdiff
path: root/indra/llvfs/lllfsthread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llvfs/lllfsthread.cpp')
-rw-r--r--indra/llvfs/lllfsthread.cpp233
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()
+{
+}
+
+//============================================================================