lllfsthread.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:7k
- /**
- * @file lllfsthread.cpp
- * @brief LLLFSThread base class
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2010, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "linden_common.h"
- #include "lllfsthread.h"
- #include "llstl.h"
- #include "llapr.h"
- //============================================================================
- /*static*/ LLLFSThread* LLLFSThread::sLocal = NULL;
- //============================================================================
- // Run on MAIN thread
- //static
- void LLLFSThread::initClass(bool local_is_threaded)
- {
- llassert(sLocal == NULL);
- sLocal = new LLLFSThread(local_is_threaded);
- }
- //static
- S32 LLLFSThread::updateClass(U32 ms_elapsed)
- {
- sLocal->update(ms_elapsed);
- return sLocal->getPending();
- }
- //static
- void LLLFSThread::cleanupClass()
- {
- sLocal->setQuitting();
- while (sLocal->getPending())
- {
- sLocal->update(0);
- }
- delete sLocal;
- sLocal = 0;
- }
- //----------------------------------------------------------------------------
- LLLFSThread::LLLFSThread(bool threaded) :
- LLQueuedThread("LFS", threaded),
- mPriorityCounter(PRIORITY_LOWBITS)
- {
- if(!mLocalAPRFilePoolp)
- {
- mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
- }
- }
- LLLFSThread::~LLLFSThread()
- {
- // ~LLQueuedThread() will be called here
- }
- //----------------------------------------------------------------------------
- LLLFSThread::handle_t LLLFSThread::read(const std::string& filename, /* Flawfinder: ignore */
- U8* buffer, S32 offset, S32 numbytes,
- Responder* responder, U32 priority)
- {
- handle_t handle = generateHandle();
- 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,
- responder);
- bool res = addRequest(req);
- if (!res)
- {
- llerrs << "LLLFSThread::read called after LLLFSThread::cleanupClass()" << llendl;
- }
- return handle;
- }
- LLLFSThread::handle_t LLLFSThread::write(const std::string& filename,
- U8* buffer, S32 offset, S32 numbytes,
- Responder* responder, U32 priority)
- {
- handle_t handle = generateHandle();
- if (priority == 0) priority = PRIORITY_LOW | priorityCounter();
-
- Request* req = new Request(this, handle, priority,
- FILE_WRITE, filename,
- buffer, offset, numbytes,
- responder);
- bool res = addRequest(req);
- if (!res)
- {
- llerrs << "LLLFSThread::read called after LLLFSThread::cleanupClass()" << llendl;
- }
-
- return handle;
- }
- //============================================================================
- LLLFSThread::Request::Request(LLLFSThread* thread,
- handle_t handle, U32 priority,
- operation_t op, const std::string& filename,
- 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),
- mResponder(responder)
- {
- if (numbytes <= 0)
- {
- llwarns << "LLLFSThread: Request with numbytes = " << numbytes << llendl;
- }
- }
- 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)
- {
- llerrs << "Attempt to delete a queued LLLFSThread::Request!" << llendl;
- }
- if (mResponder.notNull())
- {
- mResponder->completed(0);
- mResponder = NULL;
- }
- LLQueuedThread::QueuedRequest::deleteRequest();
- }
- bool LLLFSThread::Request::processRequest()
- {
- bool complete = false;
- if (mOperation == FILE_READ)
- {
- llassert(mOffset >= 0);
- LLAPRFile infile ;
- infile.open(mFileName, LL_APR_RB, mThread->getLocalAPRFilePool());
- if (!infile.getFileHandle())
- {
- llwarns << "LLLFS: Unable to read file: " << mFileName << llendl;
- mBytesRead = 0; // fail
- return true;
- }
- S32 off;
- if (mOffset < 0)
- off = infile.seek(APR_END, 0);
- else
- off = infile.seek(APR_SET, mOffset);
- llassert_always(off >= 0);
- mBytesRead = infile.read(mBuffer, mBytes );
- complete = true;
- infile.close() ;
- // llinfos << "LLLFSThread::READ:" << mFileName << " Bytes: " << mBytesRead << llendl;
- }
- else if (mOperation == FILE_WRITE)
- {
- apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;
- if (mOffset < 0)
- flags |= APR_APPEND;
- LLAPRFile outfile ;
- outfile.open(mFileName, flags, mThread->getLocalAPRFilePool());
- if (!outfile.getFileHandle())
- {
- llwarns << "LLLFS: Unable to write file: " << mFileName << llendl;
- mBytesRead = 0; // fail
- return true;
- }
- if (mOffset >= 0)
- {
- S32 seek = outfile.seek(APR_SET, mOffset);
- if (seek < 0)
- {
- llwarns << "LLLFS: Unable to write file (seek failed): " << mFileName << llendl;
- mBytesRead = 0; // fail
- return true;
- }
- }
- mBytesRead = outfile.write(mBuffer, mBytes );
- complete = true;
- // llinfos << "LLLFSThread::WRITE:" << mFileName << " Bytes: " << mBytesRead << "/" << mBytes << " Offset:" << mOffset << llendl;
- }
- else
- {
- llerrs << "LLLFSThread::unknown operation: " << (S32)mOperation << llendl;
- }
- return complete;
- }
- //============================================================================
- LLLFSThread::Responder::~Responder()
- {
- }
- //============================================================================