From 8c289ec126edf510a542c86e4c9df1787a37acb6 Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Fri, 11 Sep 2020 10:00:17 -0700 Subject: Effective rename of DRTVWR-506-simple since there is no way to rename a branch. Cloned canonical viewer into DRTVWR-519, copied over the files that changed from DRTVWR-506-simple and pushed back. Once I am satisfied everything is correct, DRTVWR-506-simple will be removed --- indra/llvfs/llvfile.cpp | 751 +++++++++++++++++++++++++++++++----------------- 1 file changed, 487 insertions(+), 264 deletions(-) (limited to 'indra/llvfs/llvfile.cpp') diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp index b8588e99f4..797b431b93 100644 --- a/indra/llvfs/llvfile.cpp +++ b/indra/llvfs/llvfile.cpp @@ -35,6 +35,9 @@ #include "llmemory.h" #include "llvfs.h" +#include +#include "lldir.h" + const S32 LLVFile::READ = 0x00000001; const S32 LLVFile::WRITE = 0x00000002; const S32 LLVFile::READ_WRITE = 0x00000003; // LLVFile::READ & LLVFile::WRITE @@ -43,8 +46,8 @@ const S32 LLVFile::APPEND = 0x00000006; // 0x00000004 & LLVFile::WRITE static LLTrace::BlockTimerStatHandle FTM_VFILE_WAIT("VFile Wait"); //---------------------------------------------------------------------------- -LLVFSThread* LLVFile::sVFSThread = NULL; -BOOL LLVFile::sAllocdVFSThread = FALSE; +//CP LLVFSThread* LLVFile::sVFSThread = NULL; +//CP BOOL LLVFile::sAllocdVFSThread = FALSE; //---------------------------------------------------------------------------- //============================================================================ @@ -52,137 +55,256 @@ BOOL LLVFile::sAllocdVFSThread = FALSE; LLVFile::LLVFile(LLVFS *vfs, const LLUUID &file_id, const LLAssetType::EType file_type, S32 mode) { mFileType = file_type; - mFileID = file_id; mPosition = 0; + mBytesRead = 0; + mReadComplete = FALSE; mMode = mode; - mVFS = vfs; + //CP mVFS = vfs; - mBytesRead = 0; - mHandle = LLVFSThread::nullHandle(); - mPriority = 128.f; + //CP mHandle = LLVFSThread::nullHandle(); + //CP mPriority = 128.f; - mVFS->incLock(mFileID, mFileType, VFSLOCK_OPEN); + //CP mVFS->incLock(mFileID, mFileType, VFSLOCK_OPEN); } LLVFile::~LLVFile() { - if (!isReadComplete()) - { - if (mHandle != LLVFSThread::nullHandle()) - { - if (!(mMode & LLVFile::WRITE)) - { - //LL_WARNS() << "Destroying LLVFile with pending async read/write, aborting..." << LL_ENDL; - sVFSThread->setFlags(mHandle, LLVFSThread::FLAG_AUTO_COMPLETE | LLVFSThread::FLAG_ABORT); - } - else // WRITE - { - sVFSThread->setFlags(mHandle, LLVFSThread::FLAG_AUTO_COMPLETE); - } - } - } - mVFS->decLock(mFileID, mFileType, VFSLOCK_OPEN); + //CP BEGIN + //if (!isReadComplete()) + //{ + // if (mHandle != LLVFSThread::nullHandle()) + // { + // if (!(mMode & LLVFile::WRITE)) + // { + // //LL_WARNS() << "Destroying LLVFile with pending async read/write, aborting..." << LL_ENDL; + // sVFSThread->setFlags(mHandle, LLVFSThread::FLAG_AUTO_COMPLETE | LLVFSThread::FLAG_ABORT); + // } + // else // WRITE + // { + // sVFSThread->setFlags(mHandle, LLVFSThread::FLAG_AUTO_COMPLETE); + // } + // } + //} + //mVFS->decLock(mFileID, mFileType, VFSLOCK_OPEN); + //CP END +} + +const std::string assetTypeToString(LLAssetType::EType at) +{ + /** + * Make use of the C++17 (or is it 14) feature that allows + * for inline initialization of an std::map<> + */ + typedef std::map asset_type_to_name_t; + asset_type_to_name_t asset_type_to_name = + { + { LLAssetType::AT_TEXTURE, "TEXTURE" }, + { LLAssetType::AT_SOUND, "SOUND" }, + { LLAssetType::AT_CALLINGCARD, "CALLINGCARD" }, + { LLAssetType::AT_LANDMARK, "LANDMARK" }, + { LLAssetType::AT_SCRIPT, "SCRIPT" }, + { LLAssetType::AT_CLOTHING, "CLOTHING" }, + { LLAssetType::AT_OBJECT, "OBJECT" }, + { LLAssetType::AT_NOTECARD, "NOTECARD" }, + { LLAssetType::AT_CATEGORY, "CATEGORY" }, + { LLAssetType::AT_LSL_TEXT, "LSL_TEXT" }, + { LLAssetType::AT_LSL_BYTECODE, "LSL_BYTECODE" }, + { LLAssetType::AT_TEXTURE_TGA, "TEXTURE_TGA" }, + { LLAssetType::AT_BODYPART, "BODYPART" }, + { LLAssetType::AT_SOUND_WAV, "SOUND_WAV" }, + { LLAssetType::AT_IMAGE_TGA, "IMAGE_TGA" }, + { LLAssetType::AT_IMAGE_JPEG, "IMAGE_JPEG" }, + { LLAssetType::AT_ANIMATION, "ANIMATION" }, + { LLAssetType::AT_GESTURE, "GESTURE" }, + { LLAssetType::AT_SIMSTATE, "SIMSTATE" }, + { LLAssetType::AT_LINK, "LINK" }, + { LLAssetType::AT_LINK_FOLDER, "LINK_FOLDER" }, + { LLAssetType::AT_MARKETPLACE_FOLDER, "MARKETPLACE_FOLDER" }, + { LLAssetType::AT_WIDGET, "WIDGET" }, + { LLAssetType::AT_PERSON, "PERSON" }, + { LLAssetType::AT_MESH, "MESH" }, + { LLAssetType::AT_UNKNOWN, "UNKNOWN" } + }; + + asset_type_to_name_t::iterator iter = asset_type_to_name.find(at); + if (iter != asset_type_to_name.end()) + { + return iter->second; + } + + return std::string("UNKNOWN"); +} + +const std::string idToFilepath(const std::string id, LLAssetType::EType at) +{ + /** + * For the moment this is just {UUID}_{ASSET_TYPE}.txt but of + * course, will be greatly expanded upon + */ + std::ostringstream ss; + ss << "00vfs_"; + ss << id; + ss << "_"; + ss << assetTypeToString(at); + ss << ".txt"; + + const std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ss.str()); + + return filepath; } BOOL LLVFile::read(U8 *buffer, S32 bytes, BOOL async, F32 priority) { - if (! (mMode & READ)) - { - LL_WARNS() << "Attempt to read from file " << mFileID << " opened with mode " << std::hex << mMode << std::dec << LL_ENDL; - return FALSE; - } + //CP BEGIN + //if (! (mMode & READ)) + //{ + // LL_WARNS() << "Attempt to read from file " << mFileID << " opened with mode " << std::hex << mMode << std::dec << LL_ENDL; + // return FALSE; + //} + + //if (mHandle != LLVFSThread::nullHandle()) + //{ + // LL_WARNS() << "Attempt to read from vfile object " << mFileID << " with pending async operation" << LL_ENDL; + // return FALSE; + //} + //mPriority = priority; + //CP END - if (mHandle != LLVFSThread::nullHandle()) - { - LL_WARNS() << "Attempt to read from vfile object " << mFileID << " with pending async operation" << LL_ENDL; - return FALSE; - } - mPriority = priority; - BOOL success = TRUE; + mReadComplete = FALSE; + + std::string id; + mFileID.toString(id); + const std::string filename = idToFilepath(id, mFileType); + + std::ifstream file(filename, std::ios::binary); + if (file.is_open()) + { + file.seekg(mPosition, std::ios::beg); + + file.read((char*)buffer, bytes); + + if (file) + { + mBytesRead = bytes; + } + else + { + mBytesRead = file.gcount(); + } + + file.close(); + + mPosition += mBytesRead; + if (!mBytesRead) + { + success = FALSE; + } + + mReadComplete = TRUE; + } + + return success; + // We can't do a read while there are pending async writes - waitForLock(VFSLOCK_APPEND); - - // *FIX: (?) - if (async) - { - mHandle = sVFSThread->read(mVFS, mFileID, mFileType, buffer, mPosition, bytes, threadPri()); - } - else - { - // We can't do a read while there are pending async writes on this file - mBytesRead = sVFSThread->readImmediate(mVFS, mFileID, mFileType, buffer, mPosition, bytes); - mPosition += mBytesRead; - if (! mBytesRead) - { - success = FALSE; - } - } + //CP waitForLock(VFSLOCK_APPEND); - return success; + //CP BEGIN + // *FIX: (?) + //if (async) + //{ + // mHandle = sVFSThread->read(mVFS, mFileID, mFileType, buffer, mPosition, bytes, threadPri()); + //} + //else + //{ + // // We can't do a read while there are pending async writes on this file + // mBytesRead = sVFSThread->readImmediate(mVFS, mFileID, mFileType, buffer, mPosition, bytes); + // mPosition += mBytesRead; + // if (! mBytesRead) + // { + // success = FALSE; + // } + //} + + //return success; + + //CP END } -//static -U8* LLVFile::readFile(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, S32* bytes_read) -{ - U8 *data; - LLVFile file(vfs, uuid, type, LLVFile::READ); - S32 file_size = file.getSize(); - if (file_size == 0) - { - // File is empty. - data = NULL; - } - else - { - data = (U8*) ll_aligned_malloc<16>(file_size); - file.read(data, file_size); /* Flawfinder: ignore */ - - if (file.getLastBytesRead() != (S32)file_size) - { - ll_aligned_free<16>(data); - data = NULL; - file_size = 0; - } - } - if (bytes_read) - { - *bytes_read = file_size; - } - return data; -} - -void LLVFile::setReadPriority(const F32 priority) -{ - mPriority = priority; - if (mHandle != LLVFSThread::nullHandle()) - { - sVFSThread->setPriority(mHandle, threadPri()); - } -} +//CP BEGIN +////static +//U8* LLVFile::readFile(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, S32* bytes_read) +//{ +// U8 *data; +// LLVFile file(vfs, uuid, type, LLVFile::READ); +// S32 file_size = file.getSize(); +// if (file_size == 0) +// { +// // File is empty. +// data = NULL; +// } +// else +// { +// data = (U8*) ll_aligned_malloc<16>(file_size); +// file.read(data, file_size); /* Flawfinder: ignore */ +// +// if (file.getLastBytesRead() != (S32)file_size) +// { +// ll_aligned_free<16>(data); +// data = NULL; +// file_size = 0; +// } +// } +// if (bytes_read) +// { +// *bytes_read = file_size; +// } +// return data; +//} +//CP END + +//CP BEGIN +//void LLVFile::setReadPriority(const F32 priority) +//{ +// mPriority = priority; +// if (mHandle != LLVFSThread::nullHandle()) +// { +// sVFSThread->setPriority(mHandle, threadPri()); +// } +//} +//CP END BOOL LLVFile::isReadComplete() { - BOOL res = TRUE; - if (mHandle != LLVFSThread::nullHandle()) - { - LLVFSThread::Request* req = (LLVFSThread::Request*)sVFSThread->getRequest(mHandle); - LLVFSThread::status_t status = req->getStatus(); - if (status == LLVFSThread::STATUS_COMPLETE) - { - mBytesRead = req->getBytesRead(); - mPosition += mBytesRead; - sVFSThread->completeRequest(mHandle); - mHandle = LLVFSThread::nullHandle(); - } - else - { - res = FALSE; - } - } - return res; + if (mReadComplete) + { + return TRUE; + } + + return FALSE; + + //CP BEGIN + //BOOL res = TRUE; + //if (mHandle != LLVFSThread::nullHandle()) + //{ + // LLVFSThread::Request* req = (LLVFSThread::Request*)sVFSThread->getRequest(mHandle); + // LLVFSThread::status_t status = req->getStatus(); + // if (status == LLVFSThread::STATUS_COMPLETE) + // { + // mBytesRead = req->getBytesRead(); + // mPosition += mBytesRead; + // sVFSThread->completeRequest(mHandle); + // mHandle = LLVFSThread::nullHandle(); + // } + // else + // { + // res = FALSE; + // } + //} + //return res; + //CP END } S32 LLVFile::getLastBytesRead() @@ -197,48 +319,81 @@ BOOL LLVFile::eof() BOOL LLVFile::write(const U8 *buffer, S32 bytes) { - if (! (mMode & WRITE)) - { - LL_WARNS() << "Attempt to write to file " << mFileID << " opened with mode " << std::hex << mMode << std::dec << LL_ENDL; - } - if (mHandle != LLVFSThread::nullHandle()) - { - LL_ERRS() << "Attempt to write to vfile object " << mFileID << " with pending async operation" << LL_ENDL; - return FALSE; - } - BOOL success = TRUE; - - // *FIX: allow async writes? potential problem wit mPosition... - if (mMode == APPEND) // all appends are async (but WRITEs are not) - { - U8* writebuf = new U8[bytes]; - memcpy(writebuf, buffer, bytes); - S32 offset = -1; - mHandle = sVFSThread->write(mVFS, mFileID, mFileType, - writebuf, offset, bytes, - LLVFSThread::FLAG_AUTO_COMPLETE | LLVFSThread::FLAG_AUTO_DELETE); - mHandle = LLVFSThread::nullHandle(); // FLAG_AUTO_COMPLETE means we don't track this - } - else - { - // We can't do a write while there are pending reads or writes on this file - waitForLock(VFSLOCK_READ); - waitForLock(VFSLOCK_APPEND); - - S32 pos = (mMode & APPEND) == APPEND ? -1 : mPosition; - - S32 wrote = sVFSThread->writeImmediate(mVFS, mFileID, mFileType, (U8*)buffer, pos, bytes); - - mPosition += wrote; - - if (wrote < bytes) - { - LL_WARNS() << "Tried to write " << bytes << " bytes, actually wrote " << wrote << LL_ENDL; - - success = FALSE; - } - } - return success; + std::string id_str; + mFileID.toString(id_str); + const std::string filename = idToFilepath(id_str, mFileType); + + BOOL success = FALSE; + + if (mMode == APPEND) + { + std::ofstream ofs(filename, std::ios::app | std::ios::binary); + if (ofs) + { + ofs.write((const char*)buffer, bytes); + + success = TRUE; + } + } + else + { + std::ofstream ofs(filename, std::ios::binary); + if (ofs) + { + ofs.write((const char*)buffer, bytes); + + mPosition += bytes; + + success = TRUE; + } + } + + return success; + + //CP BEGIN + //if (! (mMode & WRITE)) + //{ + // LL_WARNS() << "Attempt to write to file " << mFileID << " opened with mode " << std::hex << mMode << std::dec << LL_ENDL; + //} + //if (mHandle != LLVFSThread::nullHandle()) + //{ + // LL_ERRS() << "Attempt to write to vfile object " << mFileID << " with pending async operation" << LL_ENDL; + // return FALSE; + //} + //BOOL success = TRUE; + // + //// *FIX: allow async writes? potential problem wit mPosition... + //if (mMode == APPEND) // all appends are async (but WRITEs are not) + //{ + // U8* writebuf = new U8[bytes]; + // memcpy(writebuf, buffer, bytes); + // S32 offset = -1; + // mHandle = sVFSThread->write(mVFS, mFileID, mFileType, + // writebuf, offset, bytes, + // LLVFSThread::FLAG_AUTO_COMPLETE | LLVFSThread::FLAG_AUTO_DELETE); + // mHandle = LLVFSThread::nullHandle(); // FLAG_AUTO_COMPLETE means we don't track this + //} + //else + //{ + // // We can't do a write while there are pending reads or writes on this file + // waitForLock(VFSLOCK_READ); + // waitForLock(VFSLOCK_APPEND); + + // S32 pos = (mMode & APPEND) == APPEND ? -1 : mPosition; + + // S32 wrote = sVFSThread->writeImmediate(mVFS, mFileID, mFileType, (U8*)buffer, pos, bytes); + + // mPosition += wrote; + // + // if (wrote < bytes) + // { + // LL_WARNS() << "Tried to write " << bytes << " bytes, actually wrote " << wrote << LL_ENDL; + + // success = FALSE; + // } + //} + //return success; + //CP END } //static @@ -251,11 +406,13 @@ BOOL LLVFile::writeFile(const U8 *buffer, S32 bytes, LLVFS *vfs, const LLUUID &u BOOL LLVFile::seek(S32 offset, S32 origin) { - if (mMode == APPEND) - { - LL_WARNS() << "Attempt to seek on append-only file" << LL_ENDL; - return FALSE; - } + //CP BEG + //if (mMode == APPEND) + //{ + // LL_WARNS() << "Attempt to seek on append-only file" << LL_ENDL; + // return FALSE; + //} + //CP END if (-1 == origin) { @@ -292,146 +449,212 @@ S32 LLVFile::tell() const S32 LLVFile::getSize() { - waitForLock(VFSLOCK_APPEND); - S32 size = mVFS->getSize(mFileID, mFileType); - - return size; + std::string id_str; + mFileID.toString(id_str); + const std::string filename = idToFilepath(id_str, mFileType); + + S32 file_size = 0; + std::ifstream file(filename, std::ios::binary); + if (file.is_open()) + { + file.seekg(0, std::ios::end); + file_size = file.tellg(); + } + return file_size; + + //CP BEG + //waitForLock(VFSLOCK_APPEND); + //S32 size = mVFS->getSize(mFileID, mFileType); + + //return size; + //CP END } S32 LLVFile::getMaxSize() { - S32 size = mVFS->getMaxSize(mFileID, mFileType); + // offer up a huge size since we don't care what the max is + return INT_MAX; + + //CP BEG + //S32 size = mVFS->getMaxSize(mFileID, mFileType); - return size; + //return size; + //CP END } BOOL LLVFile::setMaxSize(S32 size) { - if (! (mMode & WRITE)) - { - LL_WARNS() << "Attempt to change size of file " << mFileID << " opened with mode " << std::hex << mMode << std::dec << LL_ENDL; - - return FALSE; - } - - if (!mVFS->checkAvailable(size)) - { - //LL_RECORD_BLOCK_TIME(FTM_VFILE_WAIT); - S32 count = 0; - while (sVFSThread->getPending() > 1000) - { - if (count % 100 == 0) - { - LL_INFOS() << "VFS catching up... Pending: " << sVFSThread->getPending() << LL_ENDL; - } - if (sVFSThread->isPaused()) - { - sVFSThread->update(0); - } - ms_sleep(10); - } - } - return mVFS->setMaxSize(mFileID, mFileType, size); + // we don't care what the max size is so we do nothing + // and return true to indicate all was okay + return TRUE; + + //CP BEG + //if (! (mMode & WRITE)) + //{ + // LL_WARNS() << "Attempt to change size of file " << mFileID << " opened with mode " << std::hex << mMode << std::dec << LL_ENDL; + + // return FALSE; + //} + + //if (!mVFS->checkAvailable(size)) + //{ + // //LL_RECORD_BLOCK_TIME(FTM_VFILE_WAIT); + // S32 count = 0; + // while (sVFSThread->getPending() > 1000) + // { + // if (count % 100 == 0) + // { + // LL_INFOS() << "VFS catching up... Pending: " << sVFSThread->getPending() << LL_ENDL; + // } + // if (sVFSThread->isPaused()) + // { + // sVFSThread->update(0); + // } + // ms_sleep(10); + // } + //} + //return mVFS->setMaxSize(mFileID, mFileType, size); + //CP END } BOOL LLVFile::rename(const LLUUID &new_id, const LLAssetType::EType new_type) { - if (! (mMode & WRITE)) - { - LL_WARNS() << "Attempt to rename file " << mFileID << " opened with mode " << std::hex << mMode << std::dec << LL_ENDL; - - return FALSE; - } - - if (mHandle != LLVFSThread::nullHandle()) - { - LL_WARNS() << "Renaming file with pending async read" << LL_ENDL; - } - - waitForLock(VFSLOCK_READ); - waitForLock(VFSLOCK_APPEND); - - // we need to release / replace our own lock - // since the renamed file will inherit locks from the new name - mVFS->decLock(mFileID, mFileType, VFSLOCK_OPEN); - mVFS->renameFile(mFileID, mFileType, new_id, new_type); - mVFS->incLock(new_id, new_type, VFSLOCK_OPEN); - - mFileID = new_id; - mFileType = new_type; - - return TRUE; + std::string old_id_str; + mFileID.toString(old_id_str); + const std::string old_filename = idToFilepath(old_id_str, mFileType); + + std::string new_id_str; + new_id.toString(new_id_str); + const std::string new_filename = idToFilepath(new_id_str, new_type); + + if (std::rename(old_filename.c_str(), new_filename.c_str())) + { + // We would like to return FALSE here indicating the operation + // failed but the original code does not and doing so seems to + // break a lot of things so we go with the flow... + //return FALSE; + } + mFileID = new_id; + mFileType = new_type; + + return TRUE; + //CP BEG + //if (! (mMode & WRITE)) + //{ + // LL_WARNS() << "Attempt to rename file " << mFileID << " opened with mode " << std::hex << mMode << std::dec << LL_ENDL; + + // return FALSE; + //} + + //if (mHandle != LLVFSThread::nullHandle()) + //{ + // LL_WARNS() << "Renaming file with pending async read" << LL_ENDL; + //} + + //waitForLock(VFSLOCK_READ); + //waitForLock(VFSLOCK_APPEND); + + //// we need to release / replace our own lock + //// since the renamed file will inherit locks from the new name + //mVFS->decLock(mFileID, mFileType, VFSLOCK_OPEN); + //mVFS->renameFile(mFileID, mFileType, new_id, new_type); + //mVFS->incLock(new_id, new_type, VFSLOCK_OPEN); + // + //mFileID = new_id; + //mFileType = new_type; + + //return TRUE; + //CP END } BOOL LLVFile::remove() { -// LL_INFOS() << "Removing file " << mFileID << LL_ENDL; - - if (! (mMode & WRITE)) - { - // Leaving paranoia warning just because this should be a very infrequent - // operation. - LL_WARNS() << "Remove file " << mFileID << " opened with mode " << std::hex << mMode << std::dec << LL_ENDL; - } - - if (mHandle != LLVFSThread::nullHandle()) - { - LL_WARNS() << "Removing file with pending async read" << LL_ENDL; - } - - // why not seek back to the beginning of the file too? - mPosition = 0; - - waitForLock(VFSLOCK_READ); - waitForLock(VFSLOCK_APPEND); - mVFS->removeFile(mFileID, mFileType); - - return TRUE; + std::string id_str; + mFileID.toString(id_str); + const std::string filename = idToFilepath(id_str, mFileType); + + std::remove(filename.c_str()); + // TODO: check if file was not removed and return false - maybe we don't care? + + return TRUE; + + //CP BEG + // LL_INFOS() << "Removing file " << mFileID << LL_ENDL; + //if (! (mMode & WRITE)) + //{ + // // Leaving paranoia warning just because this should be a very infrequent + // // operation. + // LL_WARNS() << "Remove file " << mFileID << " opened with mode " << std::hex << mMode << std::dec << LL_ENDL; + //} + + //if (mHandle != LLVFSThread::nullHandle()) + //{ + // LL_WARNS() << "Removing file with pending async read" << LL_ENDL; + //} + // + //// why not seek back to the beginning of the file too? + //mPosition = 0; + + //waitForLock(VFSLOCK_READ); + //waitForLock(VFSLOCK_APPEND); + //mVFS->removeFile(mFileID, mFileType); + + //return TRUE; + //CP END } // static void LLVFile::initClass(LLVFSThread* vfsthread) { - if (!vfsthread) - { - if (LLVFSThread::sLocal != NULL) - { - vfsthread = LLVFSThread::sLocal; - } - else - { - vfsthread = new LLVFSThread(); - sAllocdVFSThread = TRUE; - } - } - sVFSThread = vfsthread; + //CP BEG + //if (!vfsthread) + //{ + // if (LLVFSThread::sLocal != NULL) + // { + // vfsthread = LLVFSThread::sLocal; + // } + // else + // { + // vfsthread = new LLVFSThread(); + // sAllocdVFSThread = TRUE; + // } + //} + //sVFSThread = vfsthread; + //CP END } // static void LLVFile::cleanupClass() { - if (sAllocdVFSThread) - { - delete sVFSThread; - } - sVFSThread = NULL; + //CP BEG + //if (sAllocdVFSThread) + //{ + // delete sVFSThread; + //} + //sVFSThread = NULL; + //CP END } bool LLVFile::isLocked(EVFSLock lock) { - return mVFS->isLocked(mFileID, mFileType, lock) ? true : false; + // I don't think we care about this test since there is no locking + return FALSE; + + //CP return mVFS->isLocked(mFileID, mFileType, lock) ? true : false; } void LLVFile::waitForLock(EVFSLock lock) { - //LL_RECORD_BLOCK_TIME(FTM_VFILE_WAIT); - // spin until the lock clears - while (isLocked(lock)) - { - if (sVFSThread->isPaused()) - { - sVFSThread->update(0); - } - ms_sleep(1); - } + //CP BEG + ////LL_RECORD_BLOCK_TIME(FTM_VFILE_WAIT); + //// spin until the lock clears + //while (isLocked(lock)) + //{ + // if (sVFSThread->isPaused()) + // { + // sVFSThread->update(0); + // } + // ms_sleep(1); + //} + //CP END } -- cgit v1.2.3 From 060dd2aeab72df26d6375f2e0fad619113fe7e13 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 16 Sep 2020 19:03:48 +0300 Subject: Check existence of local files instead of checking VFS --- indra/llvfs/llvfile.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'indra/llvfs/llvfile.cpp') diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp index 797b431b93..d05c419d89 100644 --- a/indra/llvfs/llvfile.cpp +++ b/indra/llvfs/llvfile.cpp @@ -124,6 +124,7 @@ const std::string assetTypeToString(LLAssetType::EType at) { LLAssetType::AT_WIDGET, "WIDGET" }, { LLAssetType::AT_PERSON, "PERSON" }, { LLAssetType::AT_MESH, "MESH" }, + { LLAssetType::AT_SETTINGS, "SETTINGS" }, { LLAssetType::AT_UNKNOWN, "UNKNOWN" } }; @@ -154,6 +155,21 @@ const std::string idToFilepath(const std::string id, LLAssetType::EType at) return filepath; } +bool LLVFile::getExists(const LLUUID &file_id, const LLAssetType::EType file_type) +{ + std::string id_str; + file_id.toString(id_str); + const std::string filename = idToFilepath(id_str, file_type); + + std::ifstream file(filename, std::ios::binary); + if (file.is_open()) + { + file.seekg(0, std::ios::end); + return file.tellg() > 0; + } + return false; +} + BOOL LLVFile::read(U8 *buffer, S32 bytes, BOOL async, F32 priority) { //CP BEGIN -- cgit v1.2.3 From 3fc07dea01795b31c37dcd093ec73d190a1e188a Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Wed, 16 Sep 2020 18:53:24 -0700 Subject: First part of change to remove LLVFS from the Viewer. Consists of code changes to remove LLVFS and LLVFSThread classes along with the associated source files. The existing llvfs folder is renamed to llcache. Also includes changes to CMake script in many places to reflect changes. Eventually, llvfile source file and class will be renamed but that is not in this change. --- indra/llvfs/llvfile.cpp | 676 ------------------------------------------------ 1 file changed, 676 deletions(-) delete mode 100644 indra/llvfs/llvfile.cpp (limited to 'indra/llvfs/llvfile.cpp') diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp deleted file mode 100644 index d05c419d89..0000000000 --- a/indra/llvfs/llvfile.cpp +++ /dev/null @@ -1,676 +0,0 @@ -/** - * @file llvfile.cpp - * @brief Implementation of virtual file - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "llvfile.h" - -#include "llerror.h" -#include "llthread.h" -#include "lltimer.h" -#include "llfasttimer.h" -#include "llmemory.h" -#include "llvfs.h" - -#include -#include "lldir.h" - -const S32 LLVFile::READ = 0x00000001; -const S32 LLVFile::WRITE = 0x00000002; -const S32 LLVFile::READ_WRITE = 0x00000003; // LLVFile::READ & LLVFile::WRITE -const S32 LLVFile::APPEND = 0x00000006; // 0x00000004 & LLVFile::WRITE - -static LLTrace::BlockTimerStatHandle FTM_VFILE_WAIT("VFile Wait"); - -//---------------------------------------------------------------------------- -//CP LLVFSThread* LLVFile::sVFSThread = NULL; -//CP BOOL LLVFile::sAllocdVFSThread = FALSE; -//---------------------------------------------------------------------------- - -//============================================================================ - -LLVFile::LLVFile(LLVFS *vfs, const LLUUID &file_id, const LLAssetType::EType file_type, S32 mode) -{ - mFileType = file_type; - mFileID = file_id; - mPosition = 0; - mBytesRead = 0; - mReadComplete = FALSE; - mMode = mode; - //CP mVFS = vfs; - - //CP mHandle = LLVFSThread::nullHandle(); - //CP mPriority = 128.f; - - //CP mVFS->incLock(mFileID, mFileType, VFSLOCK_OPEN); -} - -LLVFile::~LLVFile() -{ - //CP BEGIN - //if (!isReadComplete()) - //{ - // if (mHandle != LLVFSThread::nullHandle()) - // { - // if (!(mMode & LLVFile::WRITE)) - // { - // //LL_WARNS() << "Destroying LLVFile with pending async read/write, aborting..." << LL_ENDL; - // sVFSThread->setFlags(mHandle, LLVFSThread::FLAG_AUTO_COMPLETE | LLVFSThread::FLAG_ABORT); - // } - // else // WRITE - // { - // sVFSThread->setFlags(mHandle, LLVFSThread::FLAG_AUTO_COMPLETE); - // } - // } - //} - //mVFS->decLock(mFileID, mFileType, VFSLOCK_OPEN); - //CP END -} - -const std::string assetTypeToString(LLAssetType::EType at) -{ - /** - * Make use of the C++17 (or is it 14) feature that allows - * for inline initialization of an std::map<> - */ - typedef std::map asset_type_to_name_t; - asset_type_to_name_t asset_type_to_name = - { - { LLAssetType::AT_TEXTURE, "TEXTURE" }, - { LLAssetType::AT_SOUND, "SOUND" }, - { LLAssetType::AT_CALLINGCARD, "CALLINGCARD" }, - { LLAssetType::AT_LANDMARK, "LANDMARK" }, - { LLAssetType::AT_SCRIPT, "SCRIPT" }, - { LLAssetType::AT_CLOTHING, "CLOTHING" }, - { LLAssetType::AT_OBJECT, "OBJECT" }, - { LLAssetType::AT_NOTECARD, "NOTECARD" }, - { LLAssetType::AT_CATEGORY, "CATEGORY" }, - { LLAssetType::AT_LSL_TEXT, "LSL_TEXT" }, - { LLAssetType::AT_LSL_BYTECODE, "LSL_BYTECODE" }, - { LLAssetType::AT_TEXTURE_TGA, "TEXTURE_TGA" }, - { LLAssetType::AT_BODYPART, "BODYPART" }, - { LLAssetType::AT_SOUND_WAV, "SOUND_WAV" }, - { LLAssetType::AT_IMAGE_TGA, "IMAGE_TGA" }, - { LLAssetType::AT_IMAGE_JPEG, "IMAGE_JPEG" }, - { LLAssetType::AT_ANIMATION, "ANIMATION" }, - { LLAssetType::AT_GESTURE, "GESTURE" }, - { LLAssetType::AT_SIMSTATE, "SIMSTATE" }, - { LLAssetType::AT_LINK, "LINK" }, - { LLAssetType::AT_LINK_FOLDER, "LINK_FOLDER" }, - { LLAssetType::AT_MARKETPLACE_FOLDER, "MARKETPLACE_FOLDER" }, - { LLAssetType::AT_WIDGET, "WIDGET" }, - { LLAssetType::AT_PERSON, "PERSON" }, - { LLAssetType::AT_MESH, "MESH" }, - { LLAssetType::AT_SETTINGS, "SETTINGS" }, - { LLAssetType::AT_UNKNOWN, "UNKNOWN" } - }; - - asset_type_to_name_t::iterator iter = asset_type_to_name.find(at); - if (iter != asset_type_to_name.end()) - { - return iter->second; - } - - return std::string("UNKNOWN"); -} - -const std::string idToFilepath(const std::string id, LLAssetType::EType at) -{ - /** - * For the moment this is just {UUID}_{ASSET_TYPE}.txt but of - * course, will be greatly expanded upon - */ - std::ostringstream ss; - ss << "00vfs_"; - ss << id; - ss << "_"; - ss << assetTypeToString(at); - ss << ".txt"; - - const std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ss.str()); - - return filepath; -} - -bool LLVFile::getExists(const LLUUID &file_id, const LLAssetType::EType file_type) -{ - std::string id_str; - file_id.toString(id_str); - const std::string filename = idToFilepath(id_str, file_type); - - std::ifstream file(filename, std::ios::binary); - if (file.is_open()) - { - file.seekg(0, std::ios::end); - return file.tellg() > 0; - } - return false; -} - -BOOL LLVFile::read(U8 *buffer, S32 bytes, BOOL async, F32 priority) -{ - //CP BEGIN - //if (! (mMode & READ)) - //{ - // LL_WARNS() << "Attempt to read from file " << mFileID << " opened with mode " << std::hex << mMode << std::dec << LL_ENDL; - // return FALSE; - //} - - //if (mHandle != LLVFSThread::nullHandle()) - //{ - // LL_WARNS() << "Attempt to read from vfile object " << mFileID << " with pending async operation" << LL_ENDL; - // return FALSE; - //} - //mPriority = priority; - //CP END - - BOOL success = TRUE; - - mReadComplete = FALSE; - - std::string id; - mFileID.toString(id); - const std::string filename = idToFilepath(id, mFileType); - - std::ifstream file(filename, std::ios::binary); - if (file.is_open()) - { - file.seekg(mPosition, std::ios::beg); - - file.read((char*)buffer, bytes); - - if (file) - { - mBytesRead = bytes; - } - else - { - mBytesRead = file.gcount(); - } - - file.close(); - - mPosition += mBytesRead; - if (!mBytesRead) - { - success = FALSE; - } - - mReadComplete = TRUE; - } - - return success; - - // We can't do a read while there are pending async writes - //CP waitForLock(VFSLOCK_APPEND); - - //CP BEGIN - // *FIX: (?) - //if (async) - //{ - // mHandle = sVFSThread->read(mVFS, mFileID, mFileType, buffer, mPosition, bytes, threadPri()); - //} - //else - //{ - // // We can't do a read while there are pending async writes on this file - // mBytesRead = sVFSThread->readImmediate(mVFS, mFileID, mFileType, buffer, mPosition, bytes); - // mPosition += mBytesRead; - // if (! mBytesRead) - // { - // success = FALSE; - // } - //} - - //return success; - - //CP END -} - -//CP BEGIN -////static -//U8* LLVFile::readFile(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, S32* bytes_read) -//{ -// U8 *data; -// LLVFile file(vfs, uuid, type, LLVFile::READ); -// S32 file_size = file.getSize(); -// if (file_size == 0) -// { -// // File is empty. -// data = NULL; -// } -// else -// { -// data = (U8*) ll_aligned_malloc<16>(file_size); -// file.read(data, file_size); /* Flawfinder: ignore */ -// -// if (file.getLastBytesRead() != (S32)file_size) -// { -// ll_aligned_free<16>(data); -// data = NULL; -// file_size = 0; -// } -// } -// if (bytes_read) -// { -// *bytes_read = file_size; -// } -// return data; -//} -//CP END - -//CP BEGIN -//void LLVFile::setReadPriority(const F32 priority) -//{ -// mPriority = priority; -// if (mHandle != LLVFSThread::nullHandle()) -// { -// sVFSThread->setPriority(mHandle, threadPri()); -// } -//} -//CP END - -BOOL LLVFile::isReadComplete() -{ - if (mReadComplete) - { - return TRUE; - } - - return FALSE; - - //CP BEGIN - //BOOL res = TRUE; - //if (mHandle != LLVFSThread::nullHandle()) - //{ - // LLVFSThread::Request* req = (LLVFSThread::Request*)sVFSThread->getRequest(mHandle); - // LLVFSThread::status_t status = req->getStatus(); - // if (status == LLVFSThread::STATUS_COMPLETE) - // { - // mBytesRead = req->getBytesRead(); - // mPosition += mBytesRead; - // sVFSThread->completeRequest(mHandle); - // mHandle = LLVFSThread::nullHandle(); - // } - // else - // { - // res = FALSE; - // } - //} - //return res; - //CP END -} - -S32 LLVFile::getLastBytesRead() -{ - return mBytesRead; -} - -BOOL LLVFile::eof() -{ - return mPosition >= getSize(); -} - -BOOL LLVFile::write(const U8 *buffer, S32 bytes) -{ - std::string id_str; - mFileID.toString(id_str); - const std::string filename = idToFilepath(id_str, mFileType); - - BOOL success = FALSE; - - if (mMode == APPEND) - { - std::ofstream ofs(filename, std::ios::app | std::ios::binary); - if (ofs) - { - ofs.write((const char*)buffer, bytes); - - success = TRUE; - } - } - else - { - std::ofstream ofs(filename, std::ios::binary); - if (ofs) - { - ofs.write((const char*)buffer, bytes); - - mPosition += bytes; - - success = TRUE; - } - } - - return success; - - //CP BEGIN - //if (! (mMode & WRITE)) - //{ - // LL_WARNS() << "Attempt to write to file " << mFileID << " opened with mode " << std::hex << mMode << std::dec << LL_ENDL; - //} - //if (mHandle != LLVFSThread::nullHandle()) - //{ - // LL_ERRS() << "Attempt to write to vfile object " << mFileID << " with pending async operation" << LL_ENDL; - // return FALSE; - //} - //BOOL success = TRUE; - // - //// *FIX: allow async writes? potential problem wit mPosition... - //if (mMode == APPEND) // all appends are async (but WRITEs are not) - //{ - // U8* writebuf = new U8[bytes]; - // memcpy(writebuf, buffer, bytes); - // S32 offset = -1; - // mHandle = sVFSThread->write(mVFS, mFileID, mFileType, - // writebuf, offset, bytes, - // LLVFSThread::FLAG_AUTO_COMPLETE | LLVFSThread::FLAG_AUTO_DELETE); - // mHandle = LLVFSThread::nullHandle(); // FLAG_AUTO_COMPLETE means we don't track this - //} - //else - //{ - // // We can't do a write while there are pending reads or writes on this file - // waitForLock(VFSLOCK_READ); - // waitForLock(VFSLOCK_APPEND); - - // S32 pos = (mMode & APPEND) == APPEND ? -1 : mPosition; - - // S32 wrote = sVFSThread->writeImmediate(mVFS, mFileID, mFileType, (U8*)buffer, pos, bytes); - - // mPosition += wrote; - // - // if (wrote < bytes) - // { - // LL_WARNS() << "Tried to write " << bytes << " bytes, actually wrote " << wrote << LL_ENDL; - - // success = FALSE; - // } - //} - //return success; - //CP END -} - -//static -BOOL LLVFile::writeFile(const U8 *buffer, S32 bytes, LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type) -{ - LLVFile file(vfs, uuid, type, LLVFile::WRITE); - file.setMaxSize(bytes); - return file.write(buffer, bytes); -} - -BOOL LLVFile::seek(S32 offset, S32 origin) -{ - //CP BEG - //if (mMode == APPEND) - //{ - // LL_WARNS() << "Attempt to seek on append-only file" << LL_ENDL; - // return FALSE; - //} - //CP END - - if (-1 == origin) - { - origin = mPosition; - } - - S32 new_pos = origin + offset; - - S32 size = getSize(); // Calls waitForLock(VFSLOCK_APPEND) - - if (new_pos > size) - { - LL_WARNS() << "Attempt to seek past end of file" << LL_ENDL; - - mPosition = size; - return FALSE; - } - else if (new_pos < 0) - { - LL_WARNS() << "Attempt to seek past beginning of file" << LL_ENDL; - - mPosition = 0; - return FALSE; - } - - mPosition = new_pos; - return TRUE; -} - -S32 LLVFile::tell() const -{ - return mPosition; -} - -S32 LLVFile::getSize() -{ - std::string id_str; - mFileID.toString(id_str); - const std::string filename = idToFilepath(id_str, mFileType); - - S32 file_size = 0; - std::ifstream file(filename, std::ios::binary); - if (file.is_open()) - { - file.seekg(0, std::ios::end); - file_size = file.tellg(); - } - return file_size; - - //CP BEG - //waitForLock(VFSLOCK_APPEND); - //S32 size = mVFS->getSize(mFileID, mFileType); - - //return size; - //CP END -} - -S32 LLVFile::getMaxSize() -{ - // offer up a huge size since we don't care what the max is - return INT_MAX; - - //CP BEG - //S32 size = mVFS->getMaxSize(mFileID, mFileType); - - //return size; - //CP END -} - -BOOL LLVFile::setMaxSize(S32 size) -{ - // we don't care what the max size is so we do nothing - // and return true to indicate all was okay - return TRUE; - - //CP BEG - //if (! (mMode & WRITE)) - //{ - // LL_WARNS() << "Attempt to change size of file " << mFileID << " opened with mode " << std::hex << mMode << std::dec << LL_ENDL; - - // return FALSE; - //} - - //if (!mVFS->checkAvailable(size)) - //{ - // //LL_RECORD_BLOCK_TIME(FTM_VFILE_WAIT); - // S32 count = 0; - // while (sVFSThread->getPending() > 1000) - // { - // if (count % 100 == 0) - // { - // LL_INFOS() << "VFS catching up... Pending: " << sVFSThread->getPending() << LL_ENDL; - // } - // if (sVFSThread->isPaused()) - // { - // sVFSThread->update(0); - // } - // ms_sleep(10); - // } - //} - //return mVFS->setMaxSize(mFileID, mFileType, size); - //CP END -} - -BOOL LLVFile::rename(const LLUUID &new_id, const LLAssetType::EType new_type) -{ - std::string old_id_str; - mFileID.toString(old_id_str); - const std::string old_filename = idToFilepath(old_id_str, mFileType); - - std::string new_id_str; - new_id.toString(new_id_str); - const std::string new_filename = idToFilepath(new_id_str, new_type); - - if (std::rename(old_filename.c_str(), new_filename.c_str())) - { - // We would like to return FALSE here indicating the operation - // failed but the original code does not and doing so seems to - // break a lot of things so we go with the flow... - //return FALSE; - } - mFileID = new_id; - mFileType = new_type; - - return TRUE; - //CP BEG - //if (! (mMode & WRITE)) - //{ - // LL_WARNS() << "Attempt to rename file " << mFileID << " opened with mode " << std::hex << mMode << std::dec << LL_ENDL; - - // return FALSE; - //} - - //if (mHandle != LLVFSThread::nullHandle()) - //{ - // LL_WARNS() << "Renaming file with pending async read" << LL_ENDL; - //} - - //waitForLock(VFSLOCK_READ); - //waitForLock(VFSLOCK_APPEND); - - //// we need to release / replace our own lock - //// since the renamed file will inherit locks from the new name - //mVFS->decLock(mFileID, mFileType, VFSLOCK_OPEN); - //mVFS->renameFile(mFileID, mFileType, new_id, new_type); - //mVFS->incLock(new_id, new_type, VFSLOCK_OPEN); - // - //mFileID = new_id; - //mFileType = new_type; - - //return TRUE; - //CP END -} - -BOOL LLVFile::remove() -{ - std::string id_str; - mFileID.toString(id_str); - const std::string filename = idToFilepath(id_str, mFileType); - - std::remove(filename.c_str()); - // TODO: check if file was not removed and return false - maybe we don't care? - - return TRUE; - - //CP BEG - // LL_INFOS() << "Removing file " << mFileID << LL_ENDL; - //if (! (mMode & WRITE)) - //{ - // // Leaving paranoia warning just because this should be a very infrequent - // // operation. - // LL_WARNS() << "Remove file " << mFileID << " opened with mode " << std::hex << mMode << std::dec << LL_ENDL; - //} - - //if (mHandle != LLVFSThread::nullHandle()) - //{ - // LL_WARNS() << "Removing file with pending async read" << LL_ENDL; - //} - // - //// why not seek back to the beginning of the file too? - //mPosition = 0; - - //waitForLock(VFSLOCK_READ); - //waitForLock(VFSLOCK_APPEND); - //mVFS->removeFile(mFileID, mFileType); - - //return TRUE; - //CP END -} - -// static -void LLVFile::initClass(LLVFSThread* vfsthread) -{ - //CP BEG - //if (!vfsthread) - //{ - // if (LLVFSThread::sLocal != NULL) - // { - // vfsthread = LLVFSThread::sLocal; - // } - // else - // { - // vfsthread = new LLVFSThread(); - // sAllocdVFSThread = TRUE; - // } - //} - //sVFSThread = vfsthread; - //CP END -} - -// static -void LLVFile::cleanupClass() -{ - //CP BEG - //if (sAllocdVFSThread) - //{ - // delete sVFSThread; - //} - //sVFSThread = NULL; - //CP END -} - -bool LLVFile::isLocked(EVFSLock lock) -{ - // I don't think we care about this test since there is no locking - return FALSE; - - //CP return mVFS->isLocked(mFileID, mFileType, lock) ? true : false; -} - -void LLVFile::waitForLock(EVFSLock lock) -{ - //CP BEG - ////LL_RECORD_BLOCK_TIME(FTM_VFILE_WAIT); - //// spin until the lock clears - //while (isLocked(lock)) - //{ - // if (sVFSThread->isPaused()) - // { - // sVFSThread->update(0); - // } - // ms_sleep(1); - //} - //CP END -} -- cgit v1.2.3