Ansariel 2021-03-03 00:20:02 +01:00
commit 6b6b116fd4
182 changed files with 1558 additions and 4882 deletions

View File

@ -89,7 +89,7 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llmath)
add_subdirectory(${LIBS_OPEN_PREFIX}llmessage)
add_subdirectory(${LIBS_OPEN_PREFIX}llprimitive)
add_subdirectory(${LIBS_OPEN_PREFIX}llrender)
add_subdirectory(${LIBS_OPEN_PREFIX}llvfs)
add_subdirectory(${LIBS_OPEN_PREFIX}llfilesystem)
add_subdirectory(${LIBS_OPEN_PREFIX}llwindow)
add_subdirectory(${LIBS_OPEN_PREFIX}llxml)

View File

@ -73,12 +73,11 @@ if (WINDOWS)
# CP changed to only append the flag for 32bit builds - on 64bit builds,
# locally at least, the build output is spammed with 1000s of 'D9002'
# warnings about this switch being ignored.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
# <FS:ND> Remove this, it's no option to cl.exe and causes a massive amount of warnings.
#if( ADDRESS_SIZE EQUAL 32 )
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /p:PreferredToolArchitecture=x64")
#endif()
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Zo"
CACHE STRING "C++ compiler release-with-debug options" FORCE)

View File

@ -72,7 +72,7 @@ set(cmake_SOURCE_FILES
LLSharedLibs.cmake
LLTestCommand.cmake
LLUI.cmake
LLVFS.cmake
LLFileSystem.cmake
LLWindow.cmake
LLXML.cmake
Linking.cmake

View File

@ -0,0 +1,7 @@
# -*- cmake -*-
set(LLFILESYSTEM_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llfilesystem
)
set(LLFILESYSTEM_LIBRARIES llfilesystem)

View File

@ -1,7 +0,0 @@
# -*- cmake -*-
set(LLVFS_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llvfs
)
set(LLVFS_LIBRARIES llvfs)

View File

@ -10,11 +10,11 @@ include(LLImage)
include(LLMath)
include(LLImageJ2COJ)
include(LLKDU)
include(LLVFS)
include(LLFileSystem)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
${LLIMAGE_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
)
@ -66,7 +66,7 @@ endif (DARWIN)
target_link_libraries(llimage_libtest
${LEGACY_STDIO_LIBS}
${LLCOMMON_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLMATH_LIBRARIES}
${LLIMAGE_LIBRARIES}
${LLKDU_LIBRARIES}

View File

@ -16,7 +16,7 @@ include(LLMessage)
include(LLRender)
include(LLWindow)
include(LLUI)
include(LLVFS) # ugh, needed for LLDir
include(LLFileSystem)
include(LLXML)
include(Hunspell)
include(Linking)
@ -29,7 +29,7 @@ include_directories(
${LLMATH_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
${LLUI_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
${LIBS_PREBUILD_DIR}/include/hunspell

View File

@ -9,7 +9,7 @@ include(LLCommon)
include(LLCrashLogger)
include(LLMath)
include(LLMessage)
include(LLVFS)
include(LLFileSystem)
include(LLXML)
include(Linking)
include(UI)
@ -21,7 +21,7 @@ include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLCRASHLOGGER_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
${FREETYPE_INCLUDE_DIRS}
)
@ -62,10 +62,9 @@ set(LIBRT_LIBRARY rt)
target_link_libraries(linux-crash-logger
${LLCRASHLOGGER_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLXML_LIBRARIES}
${LLMESSAGE_LIBRARIES}
${LLVFS_LIBRARIES}
${LLMATH_LIBRARIES}
${LLCOREHTTP_LIBRARIES}
${LLCOMMON_LIBRARIES}

View File

@ -11,7 +11,7 @@ include(LLMath)
include(LLMessage)
include(LLCoreHttp)
include(LLRender)
include(LLVFS)
include(LLFileSystem)
include(LLWindow)
include(LLXML)
include(Linking)
@ -23,7 +23,7 @@ include_directories(
${LLINVENTORY_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
)
@ -83,7 +83,7 @@ target_link_libraries(llappearance
${LLINVENTORY_LIBRARIES}
${LLIMAGE_LIBRARIES}
${LLRENDER_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLMATH_LIBRARIES}
${LLXML_LIBRARIES}
${LLMATH_LIBRARIES}
@ -100,7 +100,7 @@ if (BUILD_HEADLESS)
${LLINVENTORY_LIBRARIES}
${LLIMAGE_LIBRARIES}
${LLRENDERHEADLESS_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLMATH_LIBRARIES}
${LLXML_LIBRARIES}
${LLMATH_LIBRARIES}
@ -109,15 +109,3 @@ if (BUILD_HEADLESS)
${LLCOMMON_LIBRARIES}
)
endif (BUILD_HEADLESS)
#add unit tests
#if (LL_TESTS)
# INCLUDE(LLAddBuildTest)
# SET(llappearance_TEST_SOURCE_FILES
# # no real unit tests yet!
# )
# LL_ADD_PROJECT_UNIT_TESTS(llappearance "${llappearance_TEST_SOURCE_FILES}")
#set(TEST_DEBUG on)
# set(test_libs llappearance ${LLCOMMON_LIBRARIES})
#endif (LL_TESTS)

View File

@ -33,8 +33,6 @@
#include "llimagej2c.h"
#include "llimagetga.h"
#include "lldir.h"
#include "llvfile.h"
#include "llvfs.h"
#include "lltexlayerparams.h"
#include "lltexturemanagerbridge.h"
#include "lllocaltextureobject.h"

View File

@ -9,14 +9,14 @@ include(OPENAL)
include(LLCommon)
include(LLMath)
include(LLMessage)
include(LLVFS)
include(LLFileSystem)
include_directories(
${LLAUDIO_INCLUDE_DIRS}
${LLCOMMON_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
${OGG_INCLUDE_DIRS}
${VORBISENC_INCLUDE_DIRS}
${VORBISFILE_INCLUDE_DIRS}
@ -86,7 +86,7 @@ target_link_libraries(
${LLCOMMON_LIBRARIES}
${LLMATH_LIBRARIES}
${LLMESSAGE_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${VORBISENC_LIBRARIES}
${VORBISFILE_LIBRARIES}
${VORBIS_LIBRARIES}

View File

@ -29,7 +29,7 @@
#include "llaudioengine.h"
#include "lllfsthread.h"
#include "llvfile.h"
#include "llfilesystem.h"
#include "llstring.h"
#include "lldir.h"
#include "llendianswizzle.h"
@ -90,19 +90,17 @@ protected:
LLUUID mUUID;
std::vector<U8> mWAVBuffer;
#if !defined(USE_WAV_VFILE)
std::string mOutFilename;
LLLFSThread::handle_t mFileHandle;
#endif
LLVFile *mInFilep;
LLFileSystem *mInFilep;
OggVorbis_File mVF;
S32 mCurrentSection;
};
size_t vfs_read(void *ptr, size_t size, size_t nmemb, void *datasource)
size_t cache_read(void *ptr, size_t size, size_t nmemb, void *datasource)
{
LLVFile *file = (LLVFile *)datasource;
LLFileSystem *file = (LLFileSystem *)datasource;
if (file->read((U8*)ptr, (S32)(size * nmemb))) /*Flawfinder: ignore*/
{
@ -115,11 +113,11 @@ size_t vfs_read(void *ptr, size_t size, size_t nmemb, void *datasource)
}
}
S32 vfs_seek(void *datasource, ogg_int64_t offset, S32 whence)
S32 cache_seek(void *datasource, ogg_int64_t offset, S32 whence)
{
LLVFile *file = (LLVFile *)datasource;
LLFileSystem *file = (LLFileSystem *)datasource;
// vfs has 31-bit files
// cache has 31-bit files
if (offset > S32_MAX)
{
return -1;
@ -137,7 +135,7 @@ S32 vfs_seek(void *datasource, ogg_int64_t offset, S32 whence)
origin = -1;
break;
default:
LL_ERRS("AudioEngine") << "Invalid whence argument to vfs_seek" << LL_ENDL;
LL_ERRS("AudioEngine") << "Invalid whence argument to cache_seek" << LL_ENDL;
return -1;
}
@ -151,16 +149,16 @@ S32 vfs_seek(void *datasource, ogg_int64_t offset, S32 whence)
}
}
S32 vfs_close (void *datasource)
S32 cache_close (void *datasource)
{
LLVFile *file = (LLVFile *)datasource;
LLFileSystem *file = (LLFileSystem *)datasource;
delete file;
return 0;
}
long vfs_tell (void *datasource)
long cache_tell (void *datasource)
{
LLVFile *file = (LLVFile *)datasource;
LLFileSystem *file = (LLFileSystem *)datasource;
return file->tell();
}
@ -172,11 +170,10 @@ LLVorbisDecodeState::LLVorbisDecodeState(const LLUUID &uuid, const std::string &
mUUID = uuid;
mInFilep = NULL;
mCurrentSection = 0;
#if !defined(USE_WAV_VFILE)
mOutFilename = out_filename;
mFileHandle = LLLFSThread::nullHandle();
#endif
// No default value for mVF, it's an ogg structure?
// No default value for mVF, it's an ogg structure?
// Hey, let's zero it anyway, for predictability.
memset(&mVF, 0, sizeof(mVF));
}
@ -193,15 +190,15 @@ LLVorbisDecodeState::~LLVorbisDecodeState()
BOOL LLVorbisDecodeState::initDecode()
{
ov_callbacks vfs_callbacks;
vfs_callbacks.read_func = vfs_read;
vfs_callbacks.seek_func = vfs_seek;
vfs_callbacks.close_func = vfs_close;
vfs_callbacks.tell_func = vfs_tell;
ov_callbacks cache_callbacks;
cache_callbacks.read_func = cache_read;
cache_callbacks.seek_func = cache_seek;
cache_callbacks.close_func = cache_close;
cache_callbacks.tell_func = cache_tell;
LL_DEBUGS("AudioEngine") << "Initing decode from vfile: " << mUUID << LL_ENDL;
mInFilep = new LLVFile(gVFS, mUUID, LLAssetType::AT_SOUND);
mInFilep = new LLFileSystem(mUUID, LLAssetType::AT_SOUND);
if (!mInFilep || !mInFilep->getSize())
{
LL_WARNS("AudioEngine") << "unable to open vorbis source vfile for reading" << LL_ENDL;
@ -210,7 +207,7 @@ BOOL LLVorbisDecodeState::initDecode()
return FALSE;
}
S32 r = ov_open_callbacks(mInFilep, &mVF, NULL, 0, vfs_callbacks);
S32 r = ov_open_callbacks(mInFilep, &mVF, NULL, 0, cache_callbacks);
if(r < 0)
{
LL_WARNS("AudioEngine") << r << " Input to vorbis decode does not appear to be an Ogg bitstream: " << mUUID << LL_ENDL;
@ -370,7 +367,7 @@ BOOL LLVorbisDecodeState::decodeSection()
{
if (!mInFilep)
{
LL_WARNS("AudioEngine") << "No VFS file to decode in vorbis!" << LL_ENDL;
LL_WARNS("AudioEngine") << "No cache file to decode in vorbis!" << LL_ENDL;
return TRUE;
}
if (mDone)
@ -420,9 +417,7 @@ BOOL LLVorbisDecodeState::finishDecode()
return TRUE; // We've finished
}
#if !defined(USE_WAV_VFILE)
if (mFileHandle == LLLFSThread::nullHandle())
#endif
{
ov_clear(&mVF);
@ -495,11 +490,9 @@ BOOL LLVorbisDecodeState::finishDecode()
mValid = FALSE;
return TRUE; // we've finished
}
#if !defined(USE_WAV_VFILE)
mBytesRead = -1;
mFileHandle = LLLFSThread::sLocal->write(mOutFilename, &mWAVBuffer[0], 0, mWAVBuffer.size(),
new WriteResponder(this));
#endif
}
if (mFileHandle != LLLFSThread::nullHandle())
@ -521,11 +514,6 @@ BOOL LLVorbisDecodeState::finishDecode()
mDone = TRUE;
#if defined(USE_WAV_VFILE)
// write the data.
LLVFile output(gVFS, mUUID, LLAssetType::AT_SOUND_WAV);
output.write(&mWAVBuffer[0], mWAVBuffer.size());
#endif
LL_DEBUGS("AudioEngine") << "Finished decode for " << getUUID() << LL_ENDL;
return TRUE;
@ -535,7 +523,7 @@ void LLVorbisDecodeState::flushBadFile()
{
if (mInFilep)
{
LL_WARNS("AudioEngine") << "Flushing bad vorbis file from VFS for " << mUUID << LL_ENDL;
LL_WARNS("AudioEngine") << "Flushing bad vorbis file from cache for " << mUUID << LL_ENDL;
mInFilep->remove();
// <FS:ND> FIRE-15975; Delete the current file, or we might end with stale locks during the re-transfer

View File

@ -33,7 +33,6 @@
#include "llassettype.h"
#include "llframetimer.h"
class LLVFS;
class LLVorbisDecodeState;
class LLAudioDecodeMgr

View File

@ -35,7 +35,7 @@
#include "sound_ids.h" // temporary hack for min/max distances
#include "llvfs.h"
#include "llfilesystem.h"
#include "lldir.h"
#include "llaudiodecodemgr.h"
#include "llassetstorage.h"
@ -702,13 +702,9 @@ bool LLAudioEngine::preloadSound(const LLUUID &uuid)
return true;
}
// At some point we need to have the audio/asset system check the static VFS
// before it goes off and fetches stuff from the server.
//LL_WARNS() << "Used internal preload for non-local sound" << LL_ENDL;
return false;
}
bool LLAudioEngine::isWindEnabled()
{
return mEnableWind;
@ -1053,13 +1049,12 @@ bool LLAudioEngine::hasDecodedFile(const LLUUID &uuid)
bool LLAudioEngine::hasLocalFile(const LLUUID &uuid)
{
// See if it's in the VFS.
bool have_local = gVFS->getExists(uuid, LLAssetType::AT_SOUND);
LL_DEBUGS("AudioEngine") << "sound uuid "<<uuid<<" exists in VFS"<<LL_ENDL;
// See if it's in the cache.
bool have_local = LLFileSystem::getExists(uuid, LLAssetType::AT_SOUND);
LL_DEBUGS("AudioEngine") << "sound uuid " << uuid << " exists in cache" << LL_ENDL;
return have_local;
}
void LLAudioEngine::startNextTransfer()
{
//LL_INFOS() << "LLAudioEngine::startNextTransfer()" << LL_ENDL;
@ -1260,7 +1255,7 @@ void LLAudioEngine::startNextTransfer()
// static
void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status)
void LLAudioEngine::assetCallback(const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status)
{
if (!gAudiop)
{

View File

@ -55,15 +55,6 @@ const F32 DEFAULT_MIN_DISTANCE = 2.0f;
#define MAX_BUFFERS 60
// </FS:Ansariel>
// This define is intended to allow us to switch from os based wav
// file loading to vfs based wav file loading. The problem is that I
// am unconvinced that the LLWaveFile works for loading sounds from
// memory. So, until that is fixed up, changed, whatever, this remains
// undefined.
//#define USE_WAV_VFILE
class LLVFS;
class LLAudioSource;
class LLAudioData;
class LLAudioChannel;
@ -72,11 +63,9 @@ class LLAudioBuffer;
class LLStreamingAudioInterface;
struct SoundData;
//
// LLAudioEngine definition
//
class LLAudioEngine
{
friend class LLAudioChannelOpenAL; // bleh. channel needs some listener methods.
@ -197,7 +186,7 @@ public:
// Asset callback when we're retrieved a sound from the asset server.
void startNextTransfer();
static void assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status);
static void assetCallback(const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status);
// <FS:Ansariel> Output device selection
typedef std::map<LLUUID, std::string> output_device_map_t;

View File

@ -6,14 +6,14 @@ include(00-Common)
include(LLCommon)
include(LLMath)
include(LLMessage)
include(LLVFS)
include(LLFileSystem)
include(LLXML)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
)
include_directories(SYSTEM
@ -85,18 +85,6 @@ target_link_libraries(
${LLCOMMON_LIBRARIES}
${LLMATH_LIBRARIES}
${LLMESSAGE_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLXML_LIBRARIES}
)
# Add tests
#if (LL_TESTS)
# include(LLAddBuildTest)
# # UNIT TESTS
# SET(llcharacter_TEST_SOURCE_FILES
# lljoint.cpp
# )
# LL_ADD_PROJECT_UNIT_TESTS(llcharacter "${llcharacter_TEST_SOURCE_FILES}")
#endif (LL_TESTS)

View File

@ -70,6 +70,11 @@ LLMotion::LLMotionInitStatus LLKeyframeFallMotion::onInitialize(LLCharacter *cha
// load keyframe data, setup pose and joint states
LLMotion::LLMotionInitStatus result = LLKeyframeMotion::onInitialize(character);
if (result != LLMotion::STATUS_SUCCESS)
{
return result;
}
for (U32 jm=0; jm<mJointMotionList->getNumJointMotions(); jm++)
{
if (!mJointStates[jm]->getJoint())

View File

@ -39,16 +39,15 @@
#include "llendianswizzle.h"
#include "llkeyframemotion.h"
#include "llquantize.h"
#include "llvfile.h"
#include "m3math.h"
#include "message.h"
#include "llfilesystem.h"
#include "nd/ndexceptions.h" // <FS:ND/> For nd::exceptions::xran
//-----------------------------------------------------------------------------
// Static Definitions
//-----------------------------------------------------------------------------
LLVFS* LLKeyframeMotion::sVFS = NULL;
LLKeyframeDataCache::keyframe_data_map_t LLKeyframeDataCache::sKeyframeDataMap;
//-----------------------------------------------------------------------------
@ -518,7 +517,7 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact
return STATUS_SUCCESS;
default:
// we don't know what state the asset is in yet, so keep going
// check keyframe cache first then static vfs then asset request
// check keyframe cache first then file cache then asset request
break;
}
@ -562,13 +561,8 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact
U8 *anim_data;
S32 anim_file_size;
if (!sVFS)
{
LL_ERRS() << "Must call LLKeyframeMotion::setVFS() first before loading a keyframe file!" << LL_ENDL;
}
BOOL success = FALSE;
LLVFile* anim_file = new LLVFile(sVFS, mID, LLAssetType::AT_ANIMATION);
LLFileSystem* anim_file = new LLFileSystem(mID, LLAssetType::AT_ANIMATION);
if (!anim_file || !anim_file->getSize())
{
delete anim_file;
@ -2356,10 +2350,9 @@ void LLKeyframeMotion::setLoopOut(F32 out_point)
//-----------------------------------------------------------------------------
// onLoadComplete()
//-----------------------------------------------------------------------------
void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
const LLUUID& asset_uuid,
LLAssetType::EType type,
void* user_data, S32 status, LLExtStat ext_status)
void LLKeyframeMotion::onLoadComplete(const LLUUID& asset_uuid,
LLAssetType::EType type,
void* user_data, S32 status, LLExtStat ext_status)
{
LLUUID* id = (LLUUID*)user_data;
@ -2391,7 +2384,7 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
// asset already loaded
return;
}
LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
LLFileSystem file(asset_uuid, type, LLFileSystem::READ);
S32 size = file.getSize();
U8* buffer = new U8[size];

View File

@ -44,7 +44,6 @@
#include "llbvhconsts.h"
class LLKeyframeDataCache;
class LLVFS;
class LLDataPacker;
#define MIN_REQUIRED_PIXEL_AREA_KEYFRAME (40.f)
@ -141,10 +140,7 @@ public:
virtual void setStopTime(F32 time);
static void setVFS(LLVFS* vfs) { sVFS = vfs; }
static void onLoadComplete(LLVFS *vfs,
const LLUUID& asset_uuid,
static void onLoadComplete(const LLUUID& asset_uuid,
LLAssetType::EType type,
void* user_data, S32 status, LLExtStat ext_status);
@ -416,13 +412,7 @@ public:
U32 getNumJointMotions() const { return mJointMotionArray.size(); }
};
protected:
static LLVFS* sVFS;
//-------------------------------------------------------------------------
// Member Data
//-------------------------------------------------------------------------
JointMotionList* mJointMotionList;
std::vector<LLPointer<LLJointState> > mJointStates;
LLJoint* mPelvisp;

View File

@ -196,23 +196,64 @@ namespace {
{
return LLError::getEnabledLogTypesMask() & 0x04;
}
LL_FORCE_INLINE std::string createBoldANSI()
{
std::string ansi_code;
ansi_code += '\033';
ansi_code += "[";
ansi_code += "1";
ansi_code += "m";
return ansi_code;
}
LL_FORCE_INLINE std::string createResetANSI()
{
std::string ansi_code;
ansi_code += '\033';
ansi_code += "[";
ansi_code += "0";
ansi_code += "m";
return ansi_code;
}
LL_FORCE_INLINE std::string createANSI(const std::string& color)
{
std::string ansi_code;
ansi_code += '\033';
ansi_code += "[";
ansi_code += color;
ansi_code += '\033';
ansi_code += "[";
ansi_code += "38;5;";
ansi_code += color;
ansi_code += "m";
return ansi_code;
}
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
static std::string s_ansi_error = createANSI("31"); // red
static std::string s_ansi_warn = createANSI("34"); // blue
static std::string s_ansi_debug = createANSI("35"); // magenta
// The default colors for error, warn and debug are now a bit more pastel
// and easier to read on the default (black) terminal background but you
// now have the option to set the color of each via an environment variables:
// LL_ANSI_ERROR_COLOR_CODE (default is red)
// LL_ANSI_WARN_COLOR_CODE (default is blue)
// LL_ANSI_DEBUG_COLOR_CODE (default is magenta)
// The list of color codes can be found in many places but I used this page:
// https://www.lihaoyi.com/post/BuildyourownCommandLinewithANSIescapecodes.html#256-colors
// (Note: you may need to restart Visual Studio to pick environment changes)
char* val = nullptr;
std::string s_ansi_error_code = "160";
if ((val = getenv("LL_ANSI_ERROR_COLOR_CODE")) != nullptr) s_ansi_error_code = std::string(val);
std::string s_ansi_warn_code = "33";
if ((val = getenv("LL_ANSI_WARN_COLOR_CODE")) != nullptr) s_ansi_warn_code = std::string(val);
std::string s_ansi_debug_code = "177";
if ((val = getenv("LL_ANSI_DEBUG_COLOR_CODE")) != nullptr) s_ansi_debug_code = std::string(val);
static std::string s_ansi_error = createANSI(s_ansi_error_code); // default is red
static std::string s_ansi_warn = createANSI(s_ansi_warn_code); // default is blue
static std::string s_ansi_debug = createANSI(s_ansi_debug_code); // default is magenta
if (mUseANSI)
{
@ -234,11 +275,11 @@ namespace {
LL_FORCE_INLINE void writeANSI(const std::string& ansi_code, const std::string& message)
{
static std::string s_ansi_bold = createANSI("1"); // bold
static std::string s_ansi_reset = createANSI("0"); // reset
static std::string s_ansi_bold = createBoldANSI(); // bold text
static std::string s_ansi_reset = createResetANSI(); // reset
// ANSI color code escape sequence, message, and reset in one fprintf call
// Default all message levels to bold so we can distinguish our own messages from those dumped by subprocesses and libraries.
fprintf(stderr, "%s%s%s\n%s", s_ansi_bold.c_str(), ansi_code.c_str(), message.c_str(), s_ansi_reset.c_str() );
fprintf(stderr, "%s%s\n%s", ansi_code.c_str(), message.c_str(), s_ansi_reset.c_str() );
}
static bool checkANSI(void)

View File

@ -7,7 +7,7 @@ include(LLCoreHttp)
include(LLCommon)
include(LLMath)
include(LLMessage)
include(LLVFS)
include(LLFileSystem)
include(LLXML)
include_directories(
@ -15,7 +15,7 @@ include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
)
include_directories(SYSTEM

View File

@ -1,5 +1,5 @@
/**
* @file llpidlock.h
* @file llcrashlock.h
* @brief Maintainence of disk locking files for crash reporting
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$

View File

@ -1,6 +1,6 @@
# -*- cmake -*-
project(llvfs)
project(llfilesystem)
include(00-Common)
include(LLCommon)
@ -11,39 +11,34 @@ include_directories(
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
)
set(llvfs_SOURCE_FILES
set(llfilesystem_SOURCE_FILES
lldir.cpp
lldiriterator.cpp
lllfsthread.cpp
llpidlock.cpp
llvfile.cpp
llvfs.cpp
llvfsthread.cpp
lldiskcache.cpp
llfilesystem.cpp
)
set(llvfs_HEADER_FILES
set(llfilesystem_HEADER_FILES
CMakeLists.txt
lldir.h
lldirguard.h
lldiriterator.h
lllfsthread.h
llpidlock.h
llvfile.h
llvfs.h
llvfsthread.h
lldiskcache.h
llfilesystem.h
)
if (DARWIN)
LIST(APPEND llvfs_SOURCE_FILES lldir_mac.cpp)
LIST(APPEND llvfs_HEADER_FILES lldir_mac.h)
LIST(APPEND llvfs_SOURCE_FILES llvfs_objc.mm)
LIST(APPEND llvfs_HEADER_FILES llvfs_objc.h)
LIST(APPEND llfilesystem_SOURCE_FILES lldir_utils_objc.mm)
LIST(APPEND llfilesystem_SOURCE_FILES lldir_utils_objc.h)
LIST(APPEND llfilesystem_SOURCE_FILES lldir_mac.cpp)
LIST(APPEND llfilesystem_HEADER_FILES lldir_mac.h)
endif (DARWIN)
if (LINUX)
LIST(APPEND llvfs_SOURCE_FILES lldir_linux.cpp)
LIST(APPEND llvfs_HEADER_FILES lldir_linux.h)
LIST(APPEND llfilesystem_SOURCE_FILES lldir_linux.cpp)
LIST(APPEND llfilesystem_HEADER_FILES lldir_linux.h)
if (INSTALL)
set_source_files_properties(lldir_linux.cpp
@ -54,31 +49,31 @@ if (LINUX)
endif (LINUX)
if (WINDOWS)
LIST(APPEND llvfs_SOURCE_FILES lldir_win32.cpp)
LIST(APPEND llvfs_HEADER_FILES lldir_win32.h)
LIST(APPEND llfilesystem_SOURCE_FILES lldir_win32.cpp)
LIST(APPEND llfilesystem_HEADER_FILES lldir_win32.h)
endif (WINDOWS)
set_source_files_properties(${llvfs_HEADER_FILES}
set_source_files_properties(${llfilesystem_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
list(APPEND llvfs_SOURCE_FILES ${llvfs_HEADER_FILES})
list(APPEND llfilesystem_SOURCE_FILES ${llfilesystem_HEADER_FILES})
add_library (llvfs ${llvfs_SOURCE_FILES})
add_library (llfilesystem ${llfilesystem_SOURCE_FILES})
set(vfs_BOOST_LIBRARIES
set(cache_BOOST_LIBRARIES
${BOOST_FILESYSTEM_LIBRARY}
${BOOST_SYSTEM_LIBRARY}
)
target_link_libraries(llvfs
target_link_libraries(llfilesystem
${LLCOMMON_LIBRARIES}
${vfs_BOOST_LIBRARIES}
${cache_BOOST_LIBRARIES}
)
if (DARWIN)
include(CMakeFindFrameworks)
find_library(COCOA_LIBRARY Cocoa)
target_link_libraries(llvfs ${COCOA_LIBRARY})
target_link_libraries(llfilesystem ${COCOA_LIBRARY})
endif (DARWIN)
@ -86,18 +81,18 @@ endif (DARWIN)
if (LL_TESTS)
include(LLAddBuildTest)
# UNIT TESTS
SET(llvfs_TEST_SOURCE_FILES
SET(llfilesystem_TEST_SOURCE_FILES
lldiriterator.cpp
)
set_source_files_properties(lldiriterator.cpp
PROPERTIES
LL_TEST_ADDITIONAL_LIBRARIES "${vfs_BOOST_LIBRARIES}"
LL_TEST_ADDITIONAL_LIBRARIES "${cache_BOOST_LIBRARIES}"
)
LL_ADD_PROJECT_UNIT_TESTS(llvfs "${llvfs_TEST_SOURCE_FILES}")
LL_ADD_PROJECT_UNIT_TESTS(llfilesystem "${llfilesystem_TEST_SOURCE_FILES}")
# INTEGRATION TESTS
set(test_libs llmath llcommon llvfs ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES})
set(test_libs llmath llcommon llfilesystem ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES})
# TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests.
LL_ADD_INTEGRATION_TEST(lldir "" "${test_libs}")

View File

@ -36,7 +36,7 @@
#include <unistd.h>
#include <glob.h>
#include <boost/filesystem.hpp>
#include "llvfs_objc.h"
#include "lldir_utils_objc.h"
// --------------------------------------------------------------------------------

View File

@ -1,10 +1,10 @@
/**
* @file llvfs_objc.h
* @file lldir_utils_objc.h
* @brief Definition of directory utilities class for Mac OS X
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
* Copyright (C) 2020, 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
@ -28,8 +28,8 @@
#error This header must not be included when compiling for any target other than Mac OS. Consider including lldir.h instead.
#endif // !LL_DARWIN
#ifndef LL_LLVFS_OBJC_H
#define LL_LLVFS_OBJC_H
#ifndef LL_LLDIR_UTILS_OBJC_H
#define LL_LLDIR_UTILS_OBJC_H
#include <iostream>
@ -40,4 +40,4 @@ std::string* getSystemResourceFolder();
std::string* getSystemExecutableFolder();
#endif // LL_LLVFS_OBJC_H
#endif // LL_LLDIR_UTILS_OBJC_H

View File

@ -1,10 +1,10 @@
/**
* @file llvfs_objc.cpp
* @file lldir_utils_objc.mm
* @brief Cocoa implementation of directory utilities for Mac OS X
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
* Copyright (C) 2020, 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
@ -27,7 +27,7 @@
//WARNING: This file CANNOT use standard linden includes due to conflicts between definitions of BOOL
#include "llvfs_objc.h"
#include "lldir_utils_objc.h"
#import <Cocoa/Cocoa.h>
std::string* getSystemTempFolder()

View File

@ -0,0 +1,327 @@
/**
* @file lldiskcache.cpp
* @brief The disk cache implementation.
*
* Note: Rather than keep the top level function comments up
* to date in both the source and header files, I elected to
* only have explicit comments about each function and variable
* in the header - look there for details. The same is true for
* description of how this code is supposed to work.
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2020, 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 "llassettype.h"
#include "lldir.h"
#include <boost/filesystem.hpp>
#include <boost/range/iterator_range.hpp>
#include <chrono>
#include "lldiskcache.h"
LLDiskCache::LLDiskCache(const std::string cache_dir,
const int max_size_bytes,
const bool enable_cache_debug_info) :
mCacheDir(cache_dir),
mMaxSizeBytes(max_size_bytes),
mEnableCacheDebugInfo(enable_cache_debug_info)
{
mCacheFilenamePrefix = "sl_cache";
LLFile::mkdir(cache_dir);
}
void LLDiskCache::purge()
{
if (mEnableCacheDebugInfo)
{
LL_INFOS() << "Total dir size before purge is " << dirFileSize(mCacheDir) << LL_ENDL;
}
auto start_time = std::chrono::high_resolution_clock::now();
typedef std::pair<std::time_t, std::pair<uintmax_t, std::string>> file_info_t;
std::vector<file_info_t> file_info;
#if LL_WINDOWS
std::wstring cache_path(utf8str_to_utf16str(mCacheDir));
#else
std::string cache_path(mCacheDir);
#endif
if (boost::filesystem::is_directory(cache_path))
{
for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path), {}))
{
if (boost::filesystem::is_regular_file(entry))
{
if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
{
uintmax_t file_size = boost::filesystem::file_size(entry);
const std::string file_path = entry.path().string();
const std::time_t file_time = boost::filesystem::last_write_time(entry);
file_info.push_back(file_info_t(file_time, { file_size, file_path }));
}
}
}
}
std::sort(file_info.begin(), file_info.end(), [](file_info_t& x, file_info_t& y)
{
return x.first > y.first;
});
LL_INFOS() << "Purging cache to a maximum of " << mMaxSizeBytes << " bytes" << LL_ENDL;
uintmax_t file_size_total = 0;
for (file_info_t& entry : file_info)
{
file_size_total += entry.second.first;
std::string action = "";
if (file_size_total > mMaxSizeBytes)
{
action = "DELETE:";
boost::filesystem::remove(entry.second.second);
}
else
{
action = " KEEP:";
}
if (mEnableCacheDebugInfo)
{
// have to do this because of LL_INFO/LL_END weirdness
std::ostringstream line;
line << action << " ";
line << entry.first << " ";
line << entry.second.first << " ";
line << entry.second.second;
line << " (" << file_size_total << "/" << mMaxSizeBytes << ")";
LL_INFOS() << line.str() << LL_ENDL;
}
}
if (mEnableCacheDebugInfo)
{
auto end_time = std::chrono::high_resolution_clock::now();
auto execute_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count();
LL_INFOS() << "Total dir size after purge is " << dirFileSize(mCacheDir) << LL_ENDL;
LL_INFOS() << "Cache purge took " << execute_time << " ms to execute for " << file_info.size() << " files" << LL_ENDL;
}
}
const std::string LLDiskCache::assetTypeToString(LLAssetType::EType at)
{
/**
* Make use of the handy C++17 feature that allows
* for inline initialization of an std::map<>
*/
typedef std::map<LLAssetType::EType, std::string> 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 LLDiskCache::metaDataToFilepath(const std::string id,
LLAssetType::EType at,
const std::string extra_info)
{
std::ostringstream file_path;
file_path << mCacheDir;
file_path << gDirUtilp->getDirDelimiter();
file_path << mCacheFilenamePrefix;
file_path << "_";
file_path << id;
file_path << "_";
file_path << (extra_info.empty() ? "0" : extra_info);
//file_path << "_";
//file_path << assetTypeToString(at); // see SL-14210 Prune descriptive tag from new cache filenames
// for details of why it was removed. Note that if you put it
// back or change the format of the filename, the cache files
// files will be invalidated (and perhaps, more importantly,
// never deleted unless you delete them manually).
file_path << ".asset";
return file_path.str();
}
void LLDiskCache::updateFileAccessTime(const std::string file_path)
{
/**
* Threshold in time_t units that is used to decide if the last access time
* time of the file is updated or not. Added as a precaution for the concern
* outlined in SL-14582 about frequent writes on older SSDs reducing their
* lifespan. I think this is the right place for the threshold value - rather
* than it being a pref - do comment on that Jira if you disagree...
*
* Let's start with 1 hour in time_t units and see how that unfolds
*/
const std::time_t time_threshold = 1 * 60 * 60;
// current time
const std::time_t cur_time = std::time(nullptr);
#if LL_WINDOWS
// file last write time
const std::time_t last_write_time = boost::filesystem::last_write_time(utf8str_to_utf16str(file_path));
// delta between cur time and last time the file was written
const std::time_t delta_time = cur_time - last_write_time;
// we only write the new value if the time in time_threshold has elapsed
// before the last one
if (delta_time > time_threshold)
{
boost::filesystem::last_write_time(utf8str_to_utf16str(file_path), cur_time);
}
#else
// file last write time
const std::time_t last_write_time = boost::filesystem::last_write_time(file_path);
// delta between cur time and last time the file was written
const std::time_t delta_time = cur_time - last_write_time;
// we only write the new value if the time in time_threshold has elapsed
// before the last one
if (delta_time > time_threshold)
{
boost::filesystem::last_write_time(file_path, cur_time);
}
#endif
}
const std::string LLDiskCache::getCacheInfo()
{
std::ostringstream cache_info;
F32 max_in_mb = (F32)mMaxSizeBytes / (1024.0 * 1024.0);
F32 percent_used = ((F32)dirFileSize(mCacheDir) / (F32)mMaxSizeBytes) * 100.0;
cache_info << std::fixed;
cache_info << std::setprecision(1);
cache_info << "Max size " << max_in_mb << " MB ";
cache_info << "(" << percent_used << "% used)";
return cache_info.str();
}
void LLDiskCache::clearCache()
{
/**
* See notes on performance in dirFileSize(..) - there may be
* a quicker way to do this by operating on the parent dir vs
* the component files but it's called infrequently so it's
* likely just fine
*/
#if LL_WINDOWS
std::wstring cache_path(utf8str_to_utf16str(mCacheDir));
#else
std::string cache_path(mCacheDir);
#endif
if (boost::filesystem::is_directory(cache_path))
{
for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path), {}))
{
if (boost::filesystem::is_regular_file(entry))
{
if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
{
boost::filesystem::remove(entry);
}
}
}
}
}
uintmax_t LLDiskCache::dirFileSize(const std::string dir)
{
uintmax_t total_file_size = 0;
/**
* There may be a better way that works directly on the folder (similar to
* right clicking on a folder in the OS and asking for size vs right clicking
* on all files and adding up manually) but this is very fast - less than 100ms
* for 10,000 files in my testing so, so long as it's not called frequently,
* it should be okay. Note that's it's only currently used for logging/debugging
* so if performance is ever an issue, optimizing this or removing it altogether,
* is an easy win.
*/
#if LL_WINDOWS
std::wstring dir_path(utf8str_to_utf16str(dir));
#else
std::string dir_path(dir);
#endif
if (boost::filesystem::is_directory(dir_path))
{
for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(dir_path), {}))
{
if (boost::filesystem::is_regular_file(entry))
{
if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
{
total_file_size += boost::filesystem::file_size(entry);
}
}
}
}
return total_file_size;
}

View File

@ -0,0 +1,183 @@
/**
* @file lldiskcache.h
* @brief The disk cache implementation declarations.
*
* @Description:
* This code implements a disk cache using the following ideas:
* 1/ The metadata for a file can be encapsulated in the filename.
The filenames will be composed of the following fields:
Prefix: Used to identify the file as a part of the cache.
An additional reason for using a prefix is that it
might be possible, either accidentally or maliciously
to end up with the cache dir set to a non-cache
location such as your OS system dir or a work folder.
Purging files from that would obviously be a disaster
so this is an extra step to help avoid that scenario.
ID: Typically the asset ID (UUID) of the asset being
saved but can be anything valid for a filename
Extra Info: A field for use in the future that can be used
to store extra identifiers - e.g. the discard
level of a JPEG2000 file
Asset Type: A text string created from the LLAssetType enum
that identifies the type of asset being stored.
.asset A file extension of .asset is used to help
identify this as a Viewer asset file
* 2/ The time of last access for a file can be updated instantly
* for file reads and automatically as part of the file writes.
* 3/ The purge algorithm collects a list of all files in the
* directory, sorts them by date of last access (write) and then
* deletes any files based on age until the total size of all
* the files is less than the maximum size specified.
* 4/ An LLSingleton idiom is used since there will only ever be
* a single cache and we want to access it from numerous places.
* 5/ Performance on my modest system seems very acceptable. For
* example, in testing, I was able to purge a directory of
* 10,000 files, deleting about half of them in ~ 1700ms. For
* the same sized directory of files, writing the last updated
* time to each took less than 600ms indicating that this
* important part of the mechanism has almost no overhead.
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2020, 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$
*/
#ifndef _LLDISKCACHE
#define _LLDISKCACHE
#include "llsingleton.h"
class LLDiskCache :
public LLParamSingleton<LLDiskCache>
{
public:
/**
* Since this is using the LLSingleton pattern but we
* want to allow the constructor to be called first
* with various parameters, we also invoke the
* LLParamSingleton idiom and use it to initialize
* the class via a call in LLAppViewer.
*/
LLSINGLETON(LLDiskCache,
/**
* The full name of the cache folder - typically a
* a child of the main Viewer cache directory. Defined
* by the setting at 'DiskCacheDirName'
*/
const std::string cache_dir,
/**
* The maximum size of the cache in bytes - Based on the
* setting at 'CacheSize' and 'DiskCachePercentOfTotal'
*/
const int max_size_bytes,
/**
* A flag that enables extra cache debugging so that
* if there are bugs, we can ask uses to enable this
* setting and send us their logs
*/
const bool enable_cache_debug_info);
virtual ~LLDiskCache() = default;
public:
/**
* Construct a filename and path to it based on the file meta data
* (id, asset type, additional 'extra' info like discard level perhaps)
* Worth pointing out that this function used to be in LLFileSystem but
* so many things had to be pushed back there to accomodate it, that I
* decided to move it here. Still not sure that's completely right.
*/
const std::string metaDataToFilepath(const std::string id,
LLAssetType::EType at,
const std::string extra_info);
/**
* Update the "last write time" of a file to "now". This must be called whenever a
* file in the cache is read (not written) so that the last time the file was
* accessed is up to date (This is used in the mechanism for purging the cache)
*/
void updateFileAccessTime(const std::string file_path);
/**
* Purge the oldest items in the cache so that the combined size of all files
* is no bigger than mMaxSizeBytes.
*/
void purge();
/**
* Clear the cache by removing all the files in the specified cache
* directory individually. Only the files that contain a prefix defined
* by mCacheFilenamePrefix will be removed.
*/
void clearCache();
/**
* Return some information about the cache for use in About Box etc.
*/
const std::string getCacheInfo();
private:
/**
* Utility function to gather the total size the files in a given
* directory. Primarily used here to determine the directory size
* before and after the cache purge
*/
uintmax_t dirFileSize(const std::string dir);
/**
* Utility function to convert an LLAssetType enum into a
* string that we use as part of the cache file filename
*/
const std::string assetTypeToString(LLAssetType::EType at);
private:
/**
* The maximum size of the cache in bytes. After purge is called, the
* total size of the cache files in the cache directory will be
* less than this value
*/
uintmax_t mMaxSizeBytes;
/**
* The folder that holds the cached files. The consumer of this
* class must avoid letting the user set this location as a malicious
* setting could potentially point it at a non-cache directory (for example,
* the Windows System dir) with disastrous results.
*/
std::string mCacheDir;
/**
* The prefix inserted at the start of a cache file filename to
* help identify it as a cache file. It's probably not required
* (just the presence in the cache folder is enough) but I am
* paranoid about the cache folder being set to something bad
* like the users' OS system dir by mistake or maliciously and
* this will help to offset any damage if that happens.
*/
std::string mCacheFilenamePrefix;
/**
* When enabled, displays additional debugging information in
* various parts of the code
*/
bool mEnableCacheDebugInfo;
};
#endif // _LLDISKCACHE

View File

@ -0,0 +1,283 @@
/**
* @file filesystem.h
* @brief Simulate local file system operations.
* @Note The initial implementation does actually use standard C++
* file operations but eventually, there will be another
* layer that caches and manages file meta data too.
*
* $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 "lldir.h"
#include "llfilesystem.h"
#include "llfasttimer.h"
#include "lldiskcache.h"
const S32 LLFileSystem::READ = 0x00000001;
const S32 LLFileSystem::WRITE = 0x00000002;
const S32 LLFileSystem::READ_WRITE = 0x00000003; // LLFileSystem::READ & LLFileSystem::WRITE
const S32 LLFileSystem::APPEND = 0x00000006; // 0x00000004 & LLFileSystem::WRITE
static LLTrace::BlockTimerStatHandle FTM_VFILE_WAIT("VFile Wait");
LLFileSystem::LLFileSystem(const LLUUID& file_id, const LLAssetType::EType file_type, S32 mode)
{
mFileType = file_type;
mFileID = file_id;
mPosition = 0;
mBytesRead = 0;
mMode = mode;
}
LLFileSystem::~LLFileSystem()
{
}
// static
bool LLFileSystem::getExists(const LLUUID& file_id, const LLAssetType::EType file_type)
{
std::string id_str;
file_id.toString(id_str);
const std::string extra_info = "";
const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id_str, file_type, extra_info);
llifstream file(filename, std::ios::binary);
if (file.is_open())
{
file.seekg(0, std::ios::end);
return file.tellg() > 0;
}
return false;
}
// static
bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType file_type)
{
std::string id_str;
file_id.toString(id_str);
const std::string extra_info = "";
const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id_str, file_type, extra_info);
LLFile::remove(filename.c_str());
return true;
}
// static
bool LLFileSystem::renameFile(const LLUUID& old_file_id, const LLAssetType::EType old_file_type,
const LLUUID& new_file_id, const LLAssetType::EType new_file_type)
{
std::string old_id_str;
old_file_id.toString(old_id_str);
const std::string extra_info = "";
const std::string old_filename = LLDiskCache::getInstance()->metaDataToFilepath(old_id_str, old_file_type, extra_info);
std::string new_id_str;
new_file_id.toString(new_id_str);
const std::string new_filename = LLDiskCache::getInstance()->metaDataToFilepath(new_id_str, new_file_type, extra_info);
// Rename needs the new file to not exist.
LLFileSystem::removeFile(new_file_id, new_file_type);
if (LLFile::rename(old_filename, new_filename) != 0)
{
// 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;
LL_WARNS() << "Failed to rename " << old_file_id << " to " << new_id_str << " reason: " << strerror(errno) << LL_ENDL;
}
return TRUE;
}
// static
S32 LLFileSystem::getFileSize(const LLUUID& file_id, const LLAssetType::EType file_type)
{
std::string id_str;
file_id.toString(id_str);
const std::string extra_info = "";
const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id_str, file_type, extra_info);
S32 file_size = 0;
llifstream file(filename, std::ios::binary);
if (file.is_open())
{
file.seekg(0, std::ios::end);
file_size = file.tellg();
}
return file_size;
}
BOOL LLFileSystem::read(U8* buffer, S32 bytes)
{
BOOL success = TRUE;
std::string id;
mFileID.toString(id);
const std::string extra_info = "";
const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id, mFileType, extra_info);
llifstream 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;
}
}
// update the last access time for the file - this is required
// even though we are reading and not writing because this is the
// way the cache works - it relies on a valid "last accessed time" for
// each file so it knows how to remove the oldest, unused files
LLDiskCache::getInstance()->updateFileAccessTime(filename);
return success;
}
S32 LLFileSystem::getLastBytesRead()
{
return mBytesRead;
}
BOOL LLFileSystem::eof()
{
return mPosition >= getSize();
}
BOOL LLFileSystem::write(const U8* buffer, S32 bytes)
{
std::string id_str;
mFileID.toString(id_str);
const std::string extra_info = "";
const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id_str, mFileType, extra_info);
BOOL success = FALSE;
if (mMode == APPEND)
{
llofstream ofs(filename, std::ios::app | std::ios::binary);
if (ofs)
{
ofs.write((const char*)buffer, bytes);
success = TRUE;
}
}
else
{
llofstream ofs(filename, std::ios::binary);
if (ofs)
{
ofs.write((const char*)buffer, bytes);
mPosition += bytes;
success = TRUE;
}
}
return success;
}
BOOL LLFileSystem::seek(S32 offset, S32 origin)
{
if (-1 == origin)
{
origin = mPosition;
}
S32 new_pos = origin + offset;
S32 size = getSize();
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 LLFileSystem::tell() const
{
return mPosition;
}
S32 LLFileSystem::getSize()
{
return LLFileSystem::getFileSize(mFileID, mFileType);
}
S32 LLFileSystem::getMaxSize()
{
// offer up a huge size since we don't care what the max is
return INT_MAX;
}
BOOL LLFileSystem::rename(const LLUUID& new_id, const LLAssetType::EType new_type)
{
LLFileSystem::renameFile(mFileID, mFileType, new_id, new_type);
mFileID = new_id;
mFileType = new_type;
return TRUE;
}
BOOL LLFileSystem::remove()
{
LLFileSystem::removeFile(mFileID, mFileType);
return TRUE;
}

View File

@ -0,0 +1,78 @@
/**
* @file filesystem.h
* @brief Simulate local file system operations.
* @Note The initial implementation does actually use standard C++
* file operations but eventually, there will be another
* layer that caches and manages file meta data too.
*
* $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$
*/
#ifndef LL_FILESYSTEM_H
#define LL_FILESYSTEM_H
#include "lluuid.h"
#include "llassettype.h"
#include "lldiskcache.h"
class LLFileSystem
{
public:
LLFileSystem(const LLUUID& file_id, const LLAssetType::EType file_type, S32 mode = LLFileSystem::READ);
~LLFileSystem();
BOOL read(U8* buffer, S32 bytes);
S32 getLastBytesRead();
BOOL eof();
BOOL write(const U8* buffer, S32 bytes);
BOOL seek(S32 offset, S32 origin = -1);
S32 tell() const;
S32 getSize();
S32 getMaxSize();
BOOL rename(const LLUUID& new_id, const LLAssetType::EType new_type);
BOOL remove();
static bool getExists(const LLUUID& file_id, const LLAssetType::EType file_type);
static bool removeFile(const LLUUID& file_id, const LLAssetType::EType file_type);
static bool renameFile(const LLUUID& old_file_id, const LLAssetType::EType old_file_type,
const LLUUID& new_file_id, const LLAssetType::EType new_file_type);
static S32 getFileSize(const LLUUID& file_id, const LLAssetType::EType file_type);
public:
static const S32 READ;
static const S32 WRITE;
static const S32 READ_WRITE;
static const S32 APPEND;
protected:
LLAssetType::EType mFileType;
LLUUID mFileID;
S32 mPosition;
S32 mMode;
S32 mBytesRead;
//private:
// static const std::string idToFilepath(const std::string id, LLAssetType::EType at);
};
#endif // LL_FILESYSTEM_H

View File

@ -6,7 +6,7 @@ include(00-Common)
include(LLCommon)
include(LLImage)
include(LLMath)
include(LLVFS)
include(LLFileSystem)
include(LLKDU)
include(LLImageJ2COJ)
include(ZLIB)
@ -17,7 +17,7 @@ include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
${PNG_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIRS}
)
@ -68,7 +68,7 @@ else (USE_KDU)
endif (USE_KDU)
target_link_libraries(llimage
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES}
${JPEG_LIBRARIES}

View File

@ -2269,20 +2269,11 @@ bool LLImageFormatted::save(const std::string &filename)
return true;
}
// bool LLImageFormatted::save(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type)
// Depricated to remove VFS dependency.
// Use:
// LLVFile::writeFile(image->getData(), image->getDataSize(), vfs, uuid, type);
//----------------------------------------------------------------------------
S8 LLImageFormatted::getCodec() const
{
return mCodec;
}
//============================================================================
static void avg4_colors4(const U8* a, const U8* b, const U8* c, const U8* d, U8* dst)
{
dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2);

View File

@ -7,7 +7,7 @@ include(LLCommon)
include(LLCoreHttp)
include(LLMath)
include(LLMessage)
include(LLVFS)
include(LLFileSystem)
include(LLXML)
include_directories(
@ -87,7 +87,7 @@ if (LL_TESTS)
LL_ADD_PROJECT_UNIT_TESTS(llinventory "${llinventory_TEST_SOURCE_FILES}")
#set(TEST_DEBUG on)
set(test_libs llinventory ${LLMESSAGE_LIBRARIES} ${LLVFS_LIBRARIES} ${LLCOREHTTP_LIBRARIES} ${LLMATH_LIBRARIES} ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES})
set(test_libs llinventory ${LLMESSAGE_LIBRARIES} ${LLFILESYSTEM_LIBRARIES} ${LLCOREHTTP_LIBRARIES} ${LLMATH_LIBRARIES} ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES})
LL_ADD_INTEGRATION_TEST(inventorymisc "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llparcel "" "${test_libs}")
endif (LL_TESTS)

View File

@ -13,7 +13,7 @@ include(LLCommon)
include(LLCoreHttp)
include(LLMath)
include(LLMessage)
include(LLVFS)
include(LLFileSystem)
include(LLAddBuildTest)
include(Python)
include(Tut)
@ -27,7 +27,7 @@ include_directories(
${LLCOREHTTP_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
${JSONCPP_INCLUDE_DIR}
)
@ -215,7 +215,7 @@ target_link_libraries(
llmessage
${CURL_LIBRARIES}
${LLCOMMON_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLMATH_LIBRARIES}
${JSONCPP_LIBRARIES}
${OPENSSL_LIBRARIES}
@ -233,7 +233,7 @@ target_link_libraries(
llmessage
${CURL_LIBRARIES}
${LLCOMMON_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLMATH_LIBRARIES}
${JSONCPP_LIBRARIES}
${OPENSSL_LIBRARIES}
@ -263,7 +263,7 @@ if (LL_TESTS)
if (LINUX)
set(test_libs
${WINDOWS_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLMATH_LIBRARIES}
${CURL_LIBRARIES}
${NGHTTP2_LIBRARIES}
@ -279,7 +279,7 @@ if (LINUX)
else (LINUX)
set(test_libs
${WINDOWS_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLMATH_LIBRARIES}
${CURL_LIBRARIES}
${NGHTTP2_LIBRARIES}

View File

@ -42,8 +42,7 @@
// this library includes
#include "message.h"
#include "llxfermanager.h"
#include "llvfile.h"
#include "llvfs.h"
#include "llfilesystem.h"
#include "lldbstrings.h"
#include "lltransfersourceasset.h"
@ -202,7 +201,7 @@ LLBaseDownloadRequest::LLBaseDownloadRequest(const LLUUID &uuid, const LLAssetTy
mIsTemp(FALSE),
mIsPriority(FALSE),
mDataSentInFirstPacket(FALSE),
mDataIsInVFS(FALSE)
mDataIsInCache(FALSE)
{
// Need to guarantee that this time is up to date, we may be creating a circuit even though we haven't been
// running a message system loop.
@ -266,7 +265,8 @@ LLSD LLAssetRequest::getFullDetails() const
sd["is_local"] = mIsLocal;
sd["is_priority"] = mIsPriority;
sd["data_send_in_first_packet"] = mDataSentInFirstPacket;
sd["data_is_in_vfs"] = mDataIsInVFS;
// Note: cannot change this (easily) since it is consumed by server
sd["data_is_in_vfs"] = mDataIsInCache;
return sd;
}
@ -330,28 +330,23 @@ LLBaseDownloadRequest* LLEstateAssetRequest::getCopy()
// TODO: rework tempfile handling?
LLAssetStorage::LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, LLVFS *vfs, LLVFS *static_vfs, const LLHost &upstream_host)
LLAssetStorage::LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, const LLHost &upstream_host)
{
_init(msg, xfer, vfs, static_vfs, upstream_host);
_init(msg, xfer, upstream_host);
}
LLAssetStorage::LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
LLVFS *vfs, LLVFS *static_vfs)
LLAssetStorage::LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer)
{
_init(msg, xfer, vfs, static_vfs, LLHost());
_init(msg, xfer, LLHost());
}
void LLAssetStorage::_init(LLMessageSystem *msg,
LLXferManager *xfer,
LLVFS *vfs,
LLVFS *static_vfs,
const LLHost &upstream_host)
{
mShutDown = FALSE;
mMessageSys = msg;
mXferManager = xfer;
mVFS = vfs;
mStaticVFS = static_vfs;
setUpstream(upstream_host);
msg->setHandlerFuncFast(_PREHASH_AssetUploadComplete, processUploadComplete, (void **)this);
@ -430,7 +425,7 @@ void LLAssetStorage::_cleanupRequests(BOOL all, S32 error)
}
if (tmp->mDownCallback)
{
tmp->mDownCallback(mVFS, tmp->getUUID(), tmp->getType(), tmp->mUserData, error, LLExtStat::NONE);
tmp->mDownCallback(tmp->getUUID(), tmp->getType(), tmp->mUserData, error, LLExtStat::NONE);
}
if (tmp->mInfoCallback)
{
@ -443,10 +438,10 @@ void LLAssetStorage::_cleanupRequests(BOOL all, S32 error)
BOOL LLAssetStorage::hasLocalAsset(const LLUUID &uuid, const LLAssetType::EType type)
{
return mStaticVFS->getExists(uuid, type) || mVFS->getExists(uuid, type);
return LLFileSystem::getExists(uuid, type);
}
bool LLAssetStorage::findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAssetType::EType type,
bool LLAssetStorage::findInCacheAndInvokeCallback(const LLUUID& uuid, LLAssetType::EType type,
LLGetAssetCallback callback, void *user_data)
{
if (user_data)
@ -455,17 +450,17 @@ bool LLAssetStorage::findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAsse
llassert(callback != NULL);
}
BOOL exists = mStaticVFS->getExists(uuid, type);
BOOL exists = LLFileSystem::getExists(uuid, type);
if (exists)
{
LLVFile file(mStaticVFS, uuid, type);
LLFileSystem file(uuid, type);
U32 size = file.getSize();
if (size > 0)
{
// we've already got the file
if (callback)
{
callback(mStaticVFS, uuid, type, user_data, LL_ERR_NOERR, LLExtStat::VFS_CACHED);
callback(uuid, type, user_data, LL_ERR_NOERR, LLExtStat::CACHE_CACHED);
}
return true;
}
@ -506,7 +501,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
if (callback)
{
add(sFailedDownloadCount, 1);
callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_FAILED, LLExtStat::NONE);
callback(uuid, type, user_data, LL_ERR_ASSET_REQUEST_FAILED, LLExtStat::NONE);
}
return;
}
@ -517,20 +512,19 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
if (callback)
{
add(sFailedDownloadCount, 1);
callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LLExtStat::NULL_UUID);
callback(uuid, type, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LLExtStat::NULL_UUID);
}
return;
}
// Try static VFS first.
if (findInStaticVFSAndInvokeCallback(uuid,type,callback,user_data))
if (findInCacheAndInvokeCallback(uuid,type,callback,user_data))
{
LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << uuid << " found in static VFS" << LL_ENDL;
LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << uuid << " found in cache" << LL_ENDL;
return;
}
BOOL exists = mVFS->getExists(uuid, type);
LLVFile file(mVFS, uuid, type);
BOOL exists = LLFileSystem::getExists(uuid, type);
LLFileSystem file(uuid, type);
U32 size = exists ? file.getSize() : 0;
if (size > 0)
@ -540,10 +534,10 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
// unless there's a weird error
if (callback)
{
callback(mVFS, uuid, type, user_data, LL_ERR_NOERR, LLExtStat::VFS_CACHED);
callback(uuid, type, user_data, LL_ERR_NOERR, LLExtStat::CACHE_CACHED);
}
LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << uuid << " found in VFS" << LL_ENDL;
LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << uuid << " found in cache" << LL_ENDL;
}
else
{
@ -616,7 +610,7 @@ void LLAssetStorage::removeAndCallbackPendingDownloads(const LLUUID& file_id, LL
{
add(sFailedDownloadCount, 1);
}
tmp->mDownCallback(gAssetStorage->mVFS, callback_id, callback_type, tmp->mUserData, result_code, ext_status);
tmp->mDownCallback(callback_id, callback_type, tmp->mUserData, result_code, ext_status);
}
delete tmp;
}
@ -670,7 +664,7 @@ void LLAssetStorage::downloadCompleteCallback(
if (LL_ERR_NOERR == result)
{
// we might have gotten a zero-size file
LLVFile vfile(gAssetStorage->mVFS, callback_id, callback_type);
LLFileSystem vfile(callback_id, callback_type);
if (vfile.getSize() <= 0)
{
LL_WARNS("AssetStorage") << "downloadCompleteCallback has non-existent or zero-size asset " << callback_id << LL_ENDL;
@ -719,19 +713,19 @@ void LLAssetStorage::getEstateAsset(
if (callback)
{
add(sFailedDownloadCount, 1);
callback(mVFS, asset_id, atype, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LLExtStat::NULL_UUID);
callback(asset_id, atype, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LLExtStat::NULL_UUID);
}
return;
}
// Try static VFS first.
if (findInStaticVFSAndInvokeCallback(asset_id,atype,callback,user_data))
// Try static first.
if (findInCacheAndInvokeCallback(asset_id,atype,callback,user_data))
{
return;
}
BOOL exists = mVFS->getExists(asset_id, atype);
LLVFile file(mVFS, asset_id, atype);
BOOL exists = LLFileSystem::getExists(asset_id, atype);
LLFileSystem file(asset_id, atype);
U32 size = exists ? file.getSize() : 0;
if (size > 0)
@ -741,7 +735,7 @@ void LLAssetStorage::getEstateAsset(
// unless there's a weird error
if (callback)
{
callback(mVFS, asset_id, atype, user_data, LL_ERR_NOERR, LLExtStat::VFS_CACHED);
callback(asset_id, atype, user_data, LL_ERR_NOERR, LLExtStat::CACHE_CACHED);
}
}
else
@ -792,7 +786,7 @@ void LLAssetStorage::getEstateAsset(
if (callback)
{
add(sFailedDownloadCount, 1);
callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LLExtStat::NO_UPSTREAM);
callback(asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LLExtStat::NO_UPSTREAM);
}
}
}
@ -824,7 +818,7 @@ void LLAssetStorage::downloadEstateAssetCompleteCallback(
if (LL_ERR_NOERR == result)
{
// we might have gotten a zero-size file
LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getAType());
LLFileSystem vfile(req->getUUID(), req->getAType());
if (vfile.getSize() <= 0)
{
LL_WARNS("AssetStorage") << "downloadCompleteCallback has non-existent or zero-size asset!" << LL_ENDL;
@ -838,7 +832,7 @@ void LLAssetStorage::downloadEstateAssetCompleteCallback(
{
add(sFailedDownloadCount, 1);
}
req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getAType(), req->mUserData, result, ext_status);
req->mDownCallback(req->getUUID(), req->getAType(), req->mUserData, result, ext_status);
}
void LLAssetStorage::getInvItemAsset(
@ -861,14 +855,13 @@ void LLAssetStorage::getInvItemAsset(
if(asset_id.notNull())
{
// Try static VFS first.
if (findInStaticVFSAndInvokeCallback( asset_id, atype, callback, user_data))
if (findInCacheAndInvokeCallback( asset_id, atype, callback, user_data))
{
return;
}
exists = mVFS->getExists(asset_id, atype);
LLVFile file(mVFS, asset_id, atype);
exists = LLFileSystem::getExists(asset_id, atype);
LLFileSystem file(asset_id, atype);
size = exists ? file.getSize() : 0;
if(exists && size < 1)
{
@ -885,7 +878,7 @@ void LLAssetStorage::getInvItemAsset(
// unless there's a weird error
if (callback)
{
callback(mVFS, asset_id, atype, user_data, LL_ERR_NOERR, LLExtStat::VFS_CACHED);
callback(asset_id, atype, user_data, LL_ERR_NOERR, LLExtStat::CACHE_CACHED);
}
}
else
@ -936,7 +929,7 @@ void LLAssetStorage::getInvItemAsset(
if (callback)
{
add(sFailedDownloadCount, 1);
callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LLExtStat::NO_UPSTREAM);
callback(asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LLExtStat::NO_UPSTREAM);
}
}
}
@ -968,7 +961,7 @@ void LLAssetStorage::downloadInvItemCompleteCallback(
if (LL_ERR_NOERR == result)
{
// we might have gotten a zero-size file
LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getType());
LLFileSystem vfile(req->getUUID(), req->getType());
if (vfile.getSize() <= 0)
{
LL_WARNS("AssetStorage") << "downloadCompleteCallback has non-existent or zero-size asset!" << LL_ENDL;
@ -982,7 +975,7 @@ void LLAssetStorage::downloadInvItemCompleteCallback(
{
add(sFailedDownloadCount, 1);
}
req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), req->mUserData, result, ext_status);
req->mDownCallback(req->getUUID(), req->getType(), req->mUserData, result, ext_status);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1293,7 +1286,7 @@ bool LLAssetStorage::deletePendingRequestImpl(LLAssetStorage::request_list_t* re
if (req->mDownCallback)
{
add(sFailedDownloadCount, 1);
req->mDownCallback(mVFS, req->getUUID(), req->getType(), req->mUserData, error, LLExtStat::REQUEST_DROPPED);
req->mDownCallback(req->getUUID(), req->getType(), req->mUserData, error, LLExtStat::REQUEST_DROPPED);
}
if (req->mInfoCallback)
{
@ -1363,8 +1356,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
{
LLAssetRequest* tmp = *iter++;
//void(*const* cbptr)(LLVFS *, const LLUUID &, LLAssetType::EType, void *, S32, LLExtStat)
auto cbptr = tmp->mDownCallback.target<void(*)(LLVFS *, const LLUUID &, LLAssetType::EType, void *, S32, LLExtStat)>();
auto cbptr = tmp->mDownCallback.target<void(*)(const LLUUID &, LLAssetType::EType, void *, S32, LLExtStat)>();
if (type == tmp->getType() &&
uuid == tmp->getUUID() &&
@ -1389,8 +1381,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
}
// static
void LLAssetStorage::legacyGetDataCallback(LLVFS *vfs,
const LLUUID &uuid,
void LLAssetStorage::legacyGetDataCallback(const LLUUID &uuid,
LLAssetType::EType type,
void *user_data,
S32 status,
@ -1405,7 +1396,7 @@ void LLAssetStorage::legacyGetDataCallback(LLVFS *vfs,
if ( !status
&& !toxic )
{
LLVFile file(vfs, uuid, type);
LLFileSystem file(uuid, type);
std::string uuid_str;

View File

@ -44,7 +44,6 @@
class LLMessageSystem;
class LLXferManager;
class LLAssetStorage;
class LLVFS;
class LLSD;
// anything that takes longer than this to download will abort.
@ -60,11 +59,11 @@ const int LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE = -4;
const int LL_ERR_INSUFFICIENT_PERMISSIONS = -5;
const int LL_ERR_PRICE_MISMATCH = -23018;
// *TODO: these typedefs are passed into the VFS via a legacy C function pointer
// *TODO: these typedefs are passed into the cache via a legacy C function pointer
// future project would be to convert these to C++ callables (std::function<>) so that
// we can use bind and remove the userData parameter.
//
typedef std::function<void(LLVFS *vfs, const LLUUID &asset_id, LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status)> LLGetAssetCallback;
typedef std::function<void(const LLUUID &asset_id, LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status)> LLGetAssetCallback;
typedef std::function<void(const LLUUID &asset_id, void *user_data, S32 status, LLExtStat ext_status)> LLStoreAssetCallback;
@ -120,7 +119,6 @@ protected:
public:
LLGetAssetCallback mDownCallback;
// void(*mDownCallback)(LLVFS*, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat);
void *mUserData;
LLHost mHost;
@ -128,7 +126,7 @@ public:
F64Seconds mTime; // Message system time
BOOL mIsPriority;
BOOL mDataSentInFirstPacket;
BOOL mDataIsInVFS;
BOOL mDataIsInCache;
};
class LLAssetRequest : public LLBaseDownloadRequest
@ -198,9 +196,6 @@ typedef std::map<LLUUID,U64,lluuid_less> toxic_asset_map_t;
class LLAssetStorage
{
public:
// VFS member is public because static child methods need it :(
LLVFS *mVFS;
LLVFS *mStaticVFS;
typedef ::LLStoreAssetCallback LLStoreAssetCallback;
typedef ::LLGetAssetCallback LLGetAssetCallback;
@ -230,11 +225,9 @@ protected:
toxic_asset_map_t mToxicAssetMap; // Objects in this list are known to cause problems and are not loaded
public:
LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
LLVFS *vfs, LLVFS *static_vfs, const LLHost &upstream_host);
LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, const LLHost &upstream_host);
LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
LLVFS *vfs, LLVFS *static_vfs);
LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer);
virtual ~LLAssetStorage();
void setUpstream(const LLHost &upstream_host);
@ -284,7 +277,7 @@ public:
void markAssetToxic( const LLUUID& uuid );
protected:
bool findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAssetType::EType type,
bool findInCacheAndInvokeCallback(const LLUUID& uuid, LLAssetType::EType type,
LLGetAssetCallback callback, void *user_data);
LLSD getPendingDetailsImpl(const request_list_t* requests,
@ -375,7 +368,7 @@ public:
bool user_waiting = false,
F64Seconds timeout = LL_ASSET_STORAGE_TIMEOUT) = 0;
static void legacyGetDataCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType, void *user_data, S32 status, LLExtStat ext_status);
static void legacyGetDataCallback(const LLUUID &uuid, LLAssetType::EType, void *user_data, S32 status, LLExtStat ext_status);
static void legacyStoreDataCallback(const LLUUID &uuid, void *user_data, S32 status, LLExtStat ext_status);
// add extra methods to handle metadata
@ -385,15 +378,12 @@ protected:
void _callUploadCallbacks(const LLUUID &uuid, const LLAssetType::EType asset_type, BOOL success, LLExtStat ext_status);
virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type, LLGetAssetCallback callback,
// void (*callback)(LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat),
void *user_data, BOOL duplicate,
BOOL is_priority) = 0;
private:
void _init(LLMessageSystem *msg,
LLXferManager *xfer,
LLVFS *vfs,
LLVFS *static_vfs,
const LLHost &upstream_host);
protected:
@ -408,7 +398,7 @@ protected:
MR_FILE_NONEXIST = 3, // Old format store call - source file does not exist
MR_NO_FILENAME = 4, // Old format store call - source filename is NULL/0-length
MR_NO_UPSTREAM = 5, // Upstream provider is missing
MR_VFS_CORRUPTION = 6 // VFS is corrupt - too-large or mismatched stated/returned sizes
MR_CACHE_CORRUPTION = 6 // cache is corrupt - too-large or mismatched stated/returned sizes
};
static class LLMetrics *metric_recipient;

View File

@ -37,7 +37,7 @@
#include "llsdserialize.h"
#include "json/reader.h" // JSON
#include "json/writer.h" // JSON
#include "llvfile.h"
#include "llfilesystem.h"
#include "message.h" // for getting the port
@ -784,7 +784,7 @@ LLSD HttpCoroutineAdapter::postFileAndSuspend(LLCore::HttpRequest::ptr_t request
// scoping for our streams so that they go away when we no longer need them.
{
LLCore::BufferArrayStream outs(fileData.get());
LLVFile vfile(gVFS, assetId, assetType, LLVFile::READ);
LLFileSystem vfile(assetId, assetType, LLFileSystem::READ);
S32 fileSize = vfile.getSize();
U8* fileBuffer;

View File

@ -1,7 +1,7 @@
/**
* @file llextendedstatus.h
* @date August 2007
* @brief extended status codes for curl/vfs/resident asset storage and delivery
* @brief extended status codes for curl/resident asset storage and delivery
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@ -32,9 +32,9 @@ enum class LLExtStat: uint32_t
{
// Status provider groups - Top bits indicate which status type it is
// Zero is common status code (next section)
CURL_RESULT = 1UL<<30, // serviced by curl - use 1L if we really implement the below
RES_RESULT = 2UL<<30, // serviced by resident copy
VFS_RESULT = 3UL<<30, // serviced by vfs
CURL_RESULT = 1UL<<30, // serviced by curl - use 1L if we really implement the below
RES_RESULT = 2UL<<30, // serviced by resident copy
CACHE_RESULT = 3UL<<30, // serviced by cache
// Common Status Codes
@ -54,9 +54,9 @@ enum class LLExtStat: uint32_t
// Memory-Resident status codes:
// None at present
// VFS status codes:
VFS_CACHED = VFS_RESULT | 0x0001,
VFS_CORRUPT = VFS_RESULT | 0x0002,
// CACHE status codes:
CACHE_CACHED = CACHE_RESULT | 0x0001,
CACHE_CORRUPT = CACHE_RESULT | 0x0002,
};

View File

@ -32,7 +32,7 @@
#include "message.h"
#include "lldatapacker.h"
#include "lldir.h"
#include "llvfile.h"
#include "llfilesystem.h"
LLTransferSourceAsset::LLTransferSourceAsset(const LLUUID &request_id, const F32 priority) :
LLTransferSource(LLTST_ASSET, request_id, priority),
@ -99,7 +99,7 @@ LLTSCode LLTransferSourceAsset::dataCallback(const S32 packet_id,
return LLTS_SKIP;
}
LLVFile vf(gAssetStorage->mVFS, mParams.getAssetID(), mParams.getAssetType(), LLVFile::READ);
LLFileSystem vf(mParams.getAssetID(), mParams.getAssetType(), LLFileSystem::READ);
if (!vf.getSize())
{
@ -171,7 +171,7 @@ BOOL LLTransferSourceAsset::unpackParams(LLDataPacker &dp)
}
void LLTransferSourceAsset::responderCallback(LLVFS *vfs, const LLUUID& uuid, LLAssetType::EType type,
void LLTransferSourceAsset::responderCallback(const LLUUID& uuid, LLAssetType::EType type,
void *user_data, S32 result, LLExtStat ext_status )
{
LLUUID *tidp = ((LLUUID*) user_data);
@ -198,7 +198,7 @@ void LLTransferSourceAsset::responderCallback(LLVFS *vfs, const LLUUID& uuid, LL
if (LL_ERR_NOERR == result)
{
// Everything's OK.
LLVFile vf(gAssetStorage->mVFS, uuid, type, LLVFile::READ);
LLFileSystem vf(uuid, type, LLFileSystem::READ);
tsap->mSize = vf.getSize();
status = LLTS_OK;
}

View File

@ -30,7 +30,7 @@
#include "lltransfermanager.h"
#include "llassetstorage.h"
class LLVFile;
class LLFileSystem;
class LLTransferSourceParamsAsset : public LLTransferSourceParams
{
@ -56,7 +56,7 @@ public:
LLTransferSourceAsset(const LLUUID &request_id, const F32 priority);
virtual ~LLTransferSourceAsset();
static void responderCallback(LLVFS *vfs, const LLUUID& uuid, LLAssetType::EType type,
static void responderCallback(const LLUUID& uuid, LLAssetType::EType type,
void *user_data, S32 result, LLExtStat ext_status );
protected:
/*virtual*/ void initTransfer();

View File

@ -30,7 +30,7 @@
#include "lldatapacker.h"
#include "llerror.h"
#include "llvfile.h"
#include "llfilesystem.h"
//static
void LLTransferTargetVFile::updateQueue(bool shutdown)
@ -138,10 +138,9 @@ LLTSCode LLTransferTargetVFile::dataCallback(const S32 packet_id, U8 *in_datap,
//LL_INFOS() << "LLTransferTargetFile::dataCallback" << LL_ENDL;
//LL_INFOS() << "Packet: " << packet_id << LL_ENDL;
LLVFile vf(gAssetStorage->mVFS, mTempID, mParams.getAssetType(), LLVFile::APPEND);
LLFileSystem vf(mTempID, mParams.getAssetType(), LLFileSystem::APPEND);
if (mNeedsCreate)
{
vf.setMaxSize(mSize);
mNeedsCreate = FALSE;
}
@ -176,7 +175,7 @@ void LLTransferTargetVFile::completionCallback(const LLTSCode status)
case LLTS_DONE:
if (!mNeedsCreate)
{
LLVFile file(gAssetStorage->mVFS, mTempID, mParams.getAssetType(), LLVFile::WRITE);
LLFileSystem file(mTempID, mParams.getAssetType(), LLFileSystem::WRITE);
if (!file.rename(mParams.getAssetID(), mParams.getAssetType()))
{
LL_ERRS() << "LLTransferTargetVFile: rename failed" << LL_ENDL;
@ -195,7 +194,7 @@ void LLTransferTargetVFile::completionCallback(const LLTSCode status)
{
// We're aborting this transfer, we don't want to keep this file.
LL_WARNS() << "Aborting vfile transfer for " << mParams.getAssetID() << LL_ENDL;
LLVFile vf(gAssetStorage->mVFS, mTempID, mParams.getAssetType(), LLVFile::APPEND);
LLFileSystem vf(mTempID, mParams.getAssetType(), LLFileSystem::APPEND);
vf.remove();
}
break;

View File

@ -29,9 +29,9 @@
#include "lltransfermanager.h"
#include "llassetstorage.h"
#include "llvfile.h"
#include "llfilesystem.h"
class LLVFile;
class LLFileSystem;
// Lame, an S32 for now until I figure out the deal with how we want to do
// error codes.

View File

@ -30,8 +30,7 @@
#include "lluuid.h"
#include "llerror.h"
#include "llmath.h"
#include "llvfile.h"
#include "llvfs.h"
#include "llfilesystem.h"
#include "lldir.h"
// size of chunks read from/written to disk
@ -42,13 +41,13 @@ const U32 LL_MAX_XFER_FILE_BUFFER = 65536;
LLXfer_VFile::LLXfer_VFile ()
: LLXfer(-1)
{
init(NULL, LLUUID::null, LLAssetType::AT_NONE);
init(LLUUID::null, LLAssetType::AT_NONE);
}
LLXfer_VFile::LLXfer_VFile (LLVFS *vfs, const LLUUID &local_id, LLAssetType::EType type)
LLXfer_VFile::LLXfer_VFile (const LLUUID &local_id, LLAssetType::EType type)
: LLXfer(-1)
{
init(vfs, local_id, type);
init(local_id, type);
}
///////////////////////////////////////////////////////////
@ -60,10 +59,8 @@ LLXfer_VFile::~LLXfer_VFile ()
///////////////////////////////////////////////////////////
void LLXfer_VFile::init (LLVFS *vfs, const LLUUID &local_id, LLAssetType::EType type)
void LLXfer_VFile::init (const LLUUID &local_id, LLAssetType::EType type)
{
mVFS = vfs;
mLocalID = local_id;
mType = type;
@ -82,14 +79,14 @@ void LLXfer_VFile::cleanup ()
if (mTempID.notNull() &&
mDeleteTempFile)
{
if (mVFS->getExists(mTempID, mType))
if (LLFileSystem::getExists(mTempID, mType))
{
LLVFile file(mVFS, mTempID, mType, LLVFile::WRITE);
LLFileSystem file(mTempID, mType, LLFileSystem::WRITE);
file.remove();
}
else
{
LL_WARNS("Xfer") << "LLXfer_VFile::cleanup() can't open to delete VFS file " << mTempID << "." << LLAssetType::lookup(mType)
LL_WARNS("Xfer") << "LLXfer_VFile::cleanup() can't open to delete cache file " << mTempID << "." << LLAssetType::lookup(mType)
<< ", mRemoteID is " << mRemoteID << LL_ENDL;
}
}
@ -103,7 +100,6 @@ void LLXfer_VFile::cleanup ()
///////////////////////////////////////////////////////////
S32 LLXfer_VFile::initializeRequest(U64 xfer_id,
LLVFS* vfs,
const LLUUID& local_id,
const LLUUID& remote_id,
LLAssetType::EType type,
@ -115,7 +111,6 @@ S32 LLXfer_VFile::initializeRequest(U64 xfer_id,
mRemoteHost = remote_host;
mVFS = vfs;
mLocalID = local_id;
mRemoteID = remote_id;
mType = type;
@ -192,13 +187,13 @@ S32 LLXfer_VFile::startSend (U64 xfer_id, const LLHost &remote_host)
delete mVFile;
mVFile = NULL;
if(mVFS->getExists(mLocalID, mType))
if(LLFileSystem::getExists(mLocalID, mType))
{
mVFile = new LLVFile(mVFS, mLocalID, mType, LLVFile::READ);
mVFile = new LLFileSystem(mLocalID, mType, LLFileSystem::READ);
if (mVFile->getSize() <= 0)
{
LL_WARNS("Xfer") << "LLXfer_VFile::startSend() VFS file " << mLocalID << "." << LLAssetType::lookup(mType)
LL_WARNS("Xfer") << "LLXfer_VFile::startSend() cache file " << mLocalID << "." << LLAssetType::lookup(mType)
<< " has unexpected file size of " << mVFile->getSize() << LL_ENDL;
delete mVFile;
mVFile = NULL;
@ -214,7 +209,7 @@ S32 LLXfer_VFile::startSend (U64 xfer_id, const LLHost &remote_host)
}
else
{
LL_WARNS("Xfer") << "LLXfer_VFile::startSend() can't read VFS file " << mLocalID << "." << LLAssetType::lookup(mType) << LL_ENDL;
LL_WARNS("Xfer") << "LLXfer_VFile::startSend() can't read cache file " << mLocalID << "." << LLAssetType::lookup(mType) << LL_ENDL;
retval = LL_ERR_FILE_NOT_FOUND;
}
@ -240,13 +235,13 @@ S32 LLXfer_VFile::reopenFileHandle()
if (mVFile == NULL)
{
if (mVFS->getExists(mLocalID, mType))
if (LLFileSystem::getExists(mLocalID, mType))
{
mVFile = new LLVFile(mVFS, mLocalID, mType, LLVFile::READ);
mVFile = new LLFileSystem(mLocalID, mType, LLFileSystem::READ);
}
else
{
LL_WARNS("Xfer") << "LLXfer_VFile::reopenFileHandle() can't read VFS file " << mLocalID << "." << LLAssetType::lookup(mType) << LL_ENDL;
LL_WARNS("Xfer") << "LLXfer_VFile::reopenFileHandle() can't read cache file " << mLocalID << "." << LLAssetType::lookup(mType) << LL_ENDL;
retval = LL_ERR_FILE_NOT_FOUND;
}
}
@ -265,8 +260,7 @@ void LLXfer_VFile::setXferSize (S32 xfer_size)
// It would be nice if LLXFers could tell which end of the pipe they were
if (! mVFile)
{
LLVFile file(mVFS, mTempID, mType, LLVFile::APPEND);
file.setMaxSize(xfer_size);
LLFileSystem file(mTempID, mType, LLFileSystem::APPEND);
}
}
@ -320,7 +314,7 @@ S32 LLXfer_VFile::flush()
S32 retval = 0;
if (mBufferLength)
{
LLVFile file(mVFS, mTempID, mType, LLVFile::APPEND);
LLFileSystem file(mTempID, mType, LLFileSystem::APPEND);
file.write((U8*)mBuffer, mBufferLength);
@ -340,22 +334,15 @@ S32 LLXfer_VFile::processEOF()
if (!mCallbackResult)
{
if (mVFS->getExists(mTempID, mType))
if (LLFileSystem::getExists(mTempID, mType))
{
LLVFile file(mVFS, mTempID, mType, LLVFile::WRITE);
LLFileSystem file(mTempID, mType, LLFileSystem::WRITE);
if (!file.rename(mLocalID, mType))
{
LL_WARNS("Xfer") << "VFS rename of temp file failed: unable to rename " << mTempID << " to " << mLocalID << LL_ENDL;
LL_WARNS("Xfer") << "Cache rename of temp file failed: unable to rename " << mTempID << " to " << mLocalID << LL_ENDL;
}
else
{
#ifdef VFS_SPAM
// Debugging spam
LL_INFOS("Xfer") << "VFS rename of temp file done: renamed " << mTempID << " to " << mLocalID
<< " LLVFile size is " << file.getSize()
<< LL_ENDL;
#endif
{
// Rename worked: the original file is gone. Clear mDeleteTempFile
// so we don't attempt to delete the file in cleanup()
mDeleteTempFile = FALSE;
@ -363,7 +350,7 @@ S32 LLXfer_VFile::processEOF()
}
else
{
LL_WARNS("Xfer") << "LLXfer_VFile::processEOF() can't open for renaming VFS file " << mTempID << "." << LLAssetType::lookup(mType) << LL_ENDL;
LL_WARNS("Xfer") << "LLXfer_VFile::processEOF() can't open for renaming cache file " << mTempID << "." << LLAssetType::lookup(mType) << LL_ENDL;
}
}

View File

@ -30,8 +30,7 @@
#include "llxfer.h"
#include "llassetstorage.h"
class LLVFS;
class LLVFile;
class LLFileSystem;
class LLXfer_VFile : public LLXfer
{
@ -41,9 +40,7 @@ class LLXfer_VFile : public LLXfer
LLUUID mTempID;
LLAssetType::EType mType;
LLVFile *mVFile;
LLVFS *mVFS;
LLFileSystem *mVFile;
std::string mName;
@ -51,14 +48,13 @@ class LLXfer_VFile : public LLXfer
public:
LLXfer_VFile ();
LLXfer_VFile (LLVFS *vfs, const LLUUID &local_id, LLAssetType::EType type);
LLXfer_VFile (const LLUUID &local_id, LLAssetType::EType type);
virtual ~LLXfer_VFile();
virtual void init(LLVFS *vfs, const LLUUID &local_id, LLAssetType::EType type);
virtual void init(const LLUUID &local_id, LLAssetType::EType type);
virtual void cleanup();
virtual S32 initializeRequest(U64 xfer_id,
LLVFS *vfs,
const LLUUID &local_id,
const LLUUID &remote_id,
const LLAssetType::EType type,

View File

@ -56,9 +56,9 @@ const S32 LL_DEFAULT_MAX_HARD_LIMIT_SIMULTANEOUS_XFERS = 500;
///////////////////////////////////////////////////////////
LLXferManager::LLXferManager (LLVFS *vfs)
LLXferManager::LLXferManager ()
{
init(vfs);
init();
}
///////////////////////////////////////////////////////////
@ -70,7 +70,7 @@ LLXferManager::~LLXferManager ()
///////////////////////////////////////////////////////////
void LLXferManager::init (LLVFS *vfs)
void LLXferManager::init()
{
cleanup();
@ -78,8 +78,6 @@ void LLXferManager::init (LLVFS *vfs)
setHardLimitOutgoingXfersPerCircuit(LL_DEFAULT_MAX_HARD_LIMIT_SIMULTANEOUS_XFERS);
setMaxIncomingXfers(LL_DEFAULT_MAX_REQUEST_FIFO_XFERS);
mVFS = vfs;
// Turn on or off ack throttling
mUseAckThrottling = FALSE;
setAckThrottleBPS(100000);
@ -462,7 +460,7 @@ U64 LLXferManager::requestFile(const std::string& local_filename,
void LLXferManager::requestVFile(const LLUUID& local_id,
const LLUUID& remote_id,
LLAssetType::EType type, LLVFS* vfs,
LLAssetType::EType type,
const LLHost& remote_host,
void (*callback)(void**,S32,LLExtStat),
void** user_data,
@ -508,7 +506,6 @@ void LLXferManager::requestVFile(const LLUUID& local_id,
addToList(xfer_p, mReceiveList, is_priority);
((LLXfer_VFile *)xfer_p)->initializeRequest(getNextID(),
vfs,
local_id,
remote_id,
type,
@ -784,33 +781,17 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
LLXfer *xferp;
if (uuid != LLUUID::null)
{ // Request for an asset - use a VFS file
{ // Request for an asset - use a cache file
if(NULL == LLAssetType::lookup(type))
{
LL_WARNS("Xfer") << "Invalid type for xfer request: " << uuid << ":"
<< type_s16 << " to " << mesgsys->getSender() << LL_ENDL;
return;
}
if (! mVFS)
{
LL_WARNS("Xfer") << "Attempt to send VFile w/o available VFS" << LL_ENDL;
return;
}
/* Present in fireengine, not used by viewer
if (!validateVFileForTransfer(uuid.asString()))
{
// it is up to the app sending the file to mark it for expected
// transfer before the request arrives or it will be dropped
LL_WARNS("Xfer") << "SECURITY: Unapproved VFile '" << uuid << "'" << LL_ENDL;
return;
}
*/
LL_INFOS("Xfer") << "starting vfile transfer: " << uuid << "," << LLAssetType::lookup(type) << " to " << mesgsys->getSender() << LL_ENDL;
xferp = (LLXfer *)new LLXfer_VFile(mVFS, uuid, type);
xferp = (LLXfer *)new LLXfer_VFile(uuid, type);
if (xferp)
{
mSendList.push_front(xferp);
@ -1273,9 +1254,9 @@ void LLXferManager::addToList(LLXfer* xferp, xfer_list_t & xfer_list, BOOL is_pr
LLXferManager *gXferManager = NULL;
void start_xfer_manager(LLVFS *vfs)
void start_xfer_manager()
{
gXferManager = new LLXferManager(vfs);
gXferManager = new LLXferManager();
}
void cleanup_xfer_manager()

View File

@ -35,7 +35,6 @@
//Forward declaration to avoid circular dependencies
class LLXfer;
class LLVFS;
#include "llxfer.h"
#include "message.h"
@ -72,9 +71,6 @@ public:
class LLXferManager
{
private:
LLVFS *mVFS;
protected:
S32 mMaxOutgoingXfersPerCircuit;
S32 mHardLimitOutgoingXfersPerCircuit; // At this limit, kill off the connection
@ -111,10 +107,10 @@ class LLXferManager
std::multiset<std::string> mExpectedVFileRequests; // files that are authorized to be downloaded on top of
public:
LLXferManager(LLVFS *vfs);
LLXferManager();
virtual ~LLXferManager();
virtual void init(LLVFS *vfs);
virtual void init();
virtual void cleanup();
void setUseAckThrottling(const BOOL use);
@ -166,7 +162,7 @@ class LLXferManager
// vfile requesting
// .. to vfile
virtual void requestVFile(const LLUUID &local_id, const LLUUID& remote_id,
LLAssetType::EType type, LLVFS* vfs,
LLAssetType::EType type,
const LLHost& remote_host,
void (*callback)(void**,S32,LLExtStat), void** user_data,
BOOL is_priority = FALSE);
@ -213,7 +209,7 @@ class LLXferManager
extern LLXferManager* gXferManager;
// initialization and garbage collection
void start_xfer_manager(LLVFS *vfs);
void start_xfer_manager();
void cleanup_xfer_manager();
// message system callbacks

View File

@ -9,10 +9,9 @@ include(LLCommon)
include(LLImage)
include(LLMath)
include(LLRender)
include(LLVFS)
include(LLWindow)
include(LLXML)
include(LLVFS)
include(LLFileSystem)
include_directories(
${FREETYPE_INCLUDE_DIRS}
@ -20,10 +19,9 @@ include_directories(
${LLIMAGE_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
)
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
@ -104,9 +102,8 @@ if (BUILD_HEADLESS)
${LLIMAGE_LIBRARIES}
${LLMATH_LIBRARIES}
${LLRENDER_HEADLESS_LIBRARIES}
${LLVFS_LIBRARIES}
${LLXML_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLWINDOW_HEADLESS_LIBRARIES}
${OPENGL_HEADLESS_LIBRARIES})
@ -126,9 +123,8 @@ target_link_libraries(llrender
${LLCOMMON_LIBRARIES}
${LLIMAGE_LIBRARIES}
${LLMATH_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLXML_LIBRARIES}
${LLVFS_LIBRARIES}
${LLWINDOW_LIBRARIES}
${FREETYPE_LIBRARIES}
${OPENGL_LIBRARIES})

View File

@ -13,7 +13,7 @@ include(LLCoreHttp)
include(LLRender)
include(LLWindow)
include(LLCoreHttp)
include(LLVFS)
include(LLFileSystem)
include(LLXML)
include_directories(
@ -25,7 +25,7 @@ include_directories(
${LLMESSAGE_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
${LIBS_PREBUILD_DIR}/include/hunspell
)
@ -287,7 +287,7 @@ target_link_libraries(llui
${LLINVENTORY_LIBRARIES}
${LLMESSAGE_LIBRARIES}
${LLCOREHTTP_LIBRARIES}
${LLVFS_LIBRARIES} # ugh, just for LLDir
${LLFILESYSTEM_LIBRARIES}
${LLXUIXML_LIBRARIES}
${LLXML_LIBRARIES}
${LLMATH_LIBRARIES}

View File

@ -32,7 +32,6 @@
#include "lldir.h"
#include "llsd.h"
#include "llfile.h"
#include "llvfile.h"
#include "lldate.h"
#include "llsdserialize.h"
#include "llkeyboard.h"

View File

@ -1,276 +0,0 @@
/**
* @file llformat.cpp
* @date January 2007
* @brief string formatting utility
*
* $LicenseInfo:firstyear=2007&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 "llapr.h" // thread-related functions
#include "llpidlock.h"
#include "lldir.h"
#include "llsd.h"
#include "llsdserialize.h"
#include "llnametable.h"
#include "llframetimer.h"
#if LL_WINDOWS //For windows platform.
#include <windows.h>
bool isProcessAlive(U32 pid)
{
return (bool) GetProcessVersion((DWORD)pid);
}
#else //Everyone Else
bool isProcessAlive(U32 pid)
{
return (bool) kill( (pid_t)pid, 0);
}
#endif //Everyone else.
class LLPidLockFile
{
public:
LLPidLockFile( ) :
mAutosave(false),
mSaving(false),
mWaiting(false),
mPID(getpid()),
mNameTable(NULL),
mClean(true)
{
mLockName = gDirUtilp->getTempDir() + gDirUtilp->getDirDelimiter() + "savelock";
}
bool requestLock(LLNameTable<void *> *name_table, bool autosave,
bool force_immediate=FALSE, F32 timeout=300.0);
bool checkLock();
void releaseLock();
private:
void writeLockFile(LLSD pids);
public:
static LLPidLockFile& instance(); // return the singleton black list file
bool mAutosave;
bool mSaving;
bool mWaiting;
LLFrameTimer mTimer;
U32 mPID;
std::string mLockName;
std::string mSaveName;
LLSD mPIDS_sd;
LLNameTable<void*> *mNameTable;
bool mClean;
};
LLPidLockFile& LLPidLockFile::instance()
{
static LLPidLockFile the_file;
return the_file;
}
void LLPidLockFile::writeLockFile(LLSD pids)
{
llofstream ofile(mLockName.c_str());
if (!LLSDSerialize::toXML(pids,ofile))
{
LL_WARNS() << "Unable to write concurrent save lock file." << LL_ENDL;
}
ofile.close();
}
bool LLPidLockFile::requestLock(LLNameTable<void *> *name_table, bool autosave,
bool force_immediate, F32 timeout)
{
bool readyToSave = FALSE;
if (mSaving) return FALSE; //Bail out if we're currently saving. Will not queue another save.
if (!mWaiting){
mNameTable=name_table;
mAutosave = autosave;
}
LLSD out_pids;
out_pids.append( (LLSD::Integer)mPID );
llifstream ifile(mLockName.c_str());
if (ifile.is_open())
{ //If file exists, we need to decide whether or not to continue.
if ( force_immediate
|| mTimer.hasExpired() ) //Only deserialize if we REALLY need to.
{
LLSD in_pids;
LLSDSerialize::fromXML(in_pids, ifile);
//Clean up any dead PIDS that might be in there.
for (LLSD::array_iterator i=in_pids.beginArray();
i !=in_pids.endArray();
++i)
{
U32 stored_pid=(*i).asInteger();
if (isProcessAlive(stored_pid))
{
out_pids.append( (*i) );
}
}
readyToSave=TRUE;
}
ifile.close();
}
else
{
readyToSave=TRUE;
}
if (!mWaiting) //Not presently waiting to save. Queue up.
{
mTimer.resetWithExpiry(timeout);
mWaiting=TRUE;
}
if (readyToSave)
{ //Potential race condition won't kill us. Ignore it.
writeLockFile(out_pids);
mSaving=TRUE;
}
return readyToSave;
}
bool LLPidLockFile::checkLock()
{
return mWaiting;
}
void LLPidLockFile::releaseLock()
{
llifstream ifile(mLockName.c_str());
LLSD in_pids;
LLSD out_pids;
bool write_file=FALSE;
LLSDSerialize::fromXML(in_pids, ifile);
//Clean up this PID and any dead ones.
for (LLSD::array_iterator i=in_pids.beginArray();
i !=in_pids.endArray();
++i)
{
U32 stored_pid=(*i).asInteger();
if (stored_pid != mPID && isProcessAlive(stored_pid))
{
out_pids.append( (*i) );
write_file=TRUE;
}
}
ifile.close();
if (write_file)
{
writeLockFile(out_pids);
}
else
{
unlink(mLockName.c_str());
}
mSaving=FALSE;
mWaiting=FALSE;
}
//LLPidLock
void LLPidLock::initClass() {
(void) LLPidLockFile::instance();
}
bool LLPidLock::checkLock()
{
return LLPidLockFile::instance().checkLock();
}
bool LLPidLock::requestLock(LLNameTable<void *> *name_table, bool autosave,
bool force_immediate, F32 timeout)
{
return LLPidLockFile::instance().requestLock(name_table,autosave,force_immediate,timeout);
}
void LLPidLock::releaseLock()
{
return LLPidLockFile::instance().releaseLock();
}
bool LLPidLock::isClean()
{
return LLPidLockFile::instance().mClean;
}
//getters
LLNameTable<void *> * LLPidLock::getNameTable()
{
return LLPidLockFile::instance().mNameTable;
}
bool LLPidLock::getAutosave()
{
return LLPidLockFile::instance().mAutosave;
}
bool LLPidLock::getClean()
{
return LLPidLockFile::instance().mClean;
}
std::string LLPidLock::getSaveName()
{
return LLPidLockFile::instance().mSaveName;
}
//setters
void LLPidLock::setClean(bool clean)
{
LLPidLockFile::instance().mClean=clean;
}
void LLPidLock::setSaveName(std::string savename)
{
LLPidLockFile::instance().mSaveName=savename;
}
S32 LLPidLock::getPID()
{
return (S32)getpid();
}

View File

@ -1,60 +0,0 @@
/**
* @file llpidlock.h
* @brief System information debugging classes.
*
* $LicenseInfo:firstyear=2001&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$
*/
#ifndef LL_PIDLOCK_H
#define LL_PIDLOCK_H
#include "llnametable.h"
class LLSD;
class LLFrameTimer;
#if !LL_WINDOWS //For non-windows platforms.
#include <signal.h>
#endif
namespace LLPidLock
{
void initClass(); // { (void) LLPidLockFile::instance(); }
bool requestLock( LLNameTable<void *> *name_table=NULL, bool autosave=TRUE,
bool force_immediate=FALSE, F32 timeout=300.0);
bool checkLock();
void releaseLock();
bool isClean();
//getters
LLNameTable<void *> * getNameTable();
bool getAutosave();
bool getClean();
std::string getSaveName();
S32 getPID();
//setters
void setClean(bool clean);
void setSaveName(std::string savename);
};
#endif // LL_PIDLOCK_H

View File

@ -1,437 +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"
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");
//----------------------------------------------------------------------------
LLVFSThread* LLVFile::sVFSThread = NULL;
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;
mMode = mode;
mVFS = vfs;
mBytesRead = 0;
mHandle = LLVFSThread::nullHandle();
mPriority = 128.f;
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);
}
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;
}
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;
// 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;
}
}
return success;
}
//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());
}
}
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;
}
S32 LLVFile::getLastBytesRead()
{
return mBytesRead;
}
BOOL LLVFile::eof()
{
return mPosition >= getSize();
}
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;
}
//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)
{
if (mMode == APPEND)
{
LL_WARNS() << "Attempt to seek on append-only file" << LL_ENDL;
return FALSE;
}
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()
{
waitForLock(VFSLOCK_APPEND);
S32 size = mVFS->getSize(mFileID, mFileType);
return size;
}
S32 LLVFile::getMaxSize()
{
S32 size = mVFS->getMaxSize(mFileID, mFileType);
return size;
}
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);
}
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;
}
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;
}
// static
void LLVFile::initClass(LLVFSThread* vfsthread)
{
if (!vfsthread)
{
if (LLVFSThread::sLocal != NULL)
{
vfsthread = LLVFSThread::sLocal;
}
else
{
vfsthread = new LLVFSThread();
sAllocdVFSThread = TRUE;
}
}
sVFSThread = vfsthread;
}
// static
void LLVFile::cleanupClass()
{
if (sAllocdVFSThread)
{
delete sVFSThread;
}
sVFSThread = NULL;
}
bool LLVFile::isLocked(EVFSLock lock)
{
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);
}
}

View File

@ -1,90 +0,0 @@
/**
* @file llvfile.h
* @brief Definition 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$
*/
#ifndef LL_LLVFILE_H
#define LL_LLVFILE_H
#include "lluuid.h"
#include "llassettype.h"
#include "llvfs.h"
#include "llvfsthread.h"
class LLVFile
{
public:
LLVFile(LLVFS *vfs, const LLUUID &file_id, const LLAssetType::EType file_type, S32 mode = LLVFile::READ);
~LLVFile();
BOOL read(U8 *buffer, S32 bytes, BOOL async = FALSE, F32 priority = 128.f); /* Flawfinder: ignore */
static U8* readFile(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, S32* bytes_read = 0);
void setReadPriority(const F32 priority);
BOOL isReadComplete();
S32 getLastBytesRead();
BOOL eof();
BOOL write(const U8 *buffer, S32 bytes);
static BOOL writeFile(const U8 *buffer, S32 bytes, LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type);
BOOL seek(S32 offset, S32 origin = -1);
S32 tell() const;
S32 getSize();
S32 getMaxSize();
BOOL setMaxSize(S32 size);
BOOL rename(const LLUUID &new_id, const LLAssetType::EType new_type);
BOOL remove();
bool isLocked(EVFSLock lock);
void waitForLock(EVFSLock lock);
static void initClass(LLVFSThread* vfsthread = NULL);
static void cleanupClass();
static LLVFSThread* getVFSThread() { return sVFSThread; }
protected:
static LLVFSThread* sVFSThread;
static BOOL sAllocdVFSThread;
U32 threadPri() { return LLVFSThread::PRIORITY_NORMAL + llmin((U32)mPriority,(U32)0xfff); }
public:
static const S32 READ;
static const S32 WRITE;
static const S32 READ_WRITE;
static const S32 APPEND;
protected:
LLAssetType::EType mFileType;
LLUUID mFileID;
S32 mPosition;
S32 mMode;
LLVFS *mVFS;
F32 mPriority;
S32 mBytesRead;
LLVFSThread::handle_t mHandle;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,188 +0,0 @@
/**
* @file llvfs.h
* @brief Definition of virtual file system
*
* $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$
*/
#ifndef LL_LLVFS_H
#define LL_LLVFS_H
#include <deque>
#include "lluuid.h"
#include "llassettype.h"
#include "llthread.h"
#include "llmutex.h"
enum EVFSValid
{
VFSVALID_UNKNOWN = 0,
VFSVALID_OK = 1,
VFSVALID_BAD_CORRUPT = 2,
VFSVALID_BAD_CANNOT_OPEN_READONLY = 3,
VFSVALID_BAD_CANNOT_CREATE = 4
};
// Lock types for open vfiles, pending async reads, and pending async appends
// (There are no async normal writes, currently)
enum EVFSLock
{
VFSLOCK_OPEN = 0,
VFSLOCK_READ = 1,
VFSLOCK_APPEND = 2,
VFSLOCK_COUNT = 3
};
// internal classes
class LLVFSBlock;
class LLVFSFileBlock;
class LLVFSFileSpecifier
{
public:
LLVFSFileSpecifier();
LLVFSFileSpecifier(const LLUUID &file_id, const LLAssetType::EType file_type);
bool operator<(const LLVFSFileSpecifier &rhs) const;
bool operator==(const LLVFSFileSpecifier &rhs) const;
public:
LLUUID mFileID;
LLAssetType::EType mFileType;
};
class LLVFS
{
private:
// Use createLLVFS() to open a VFS file
// Pass 0 to not presize
LLVFS(const std::string& index_filename,
const std::string& data_filename,
const BOOL read_only,
const U32 presize,
const BOOL remove_after_crash);
public:
~LLVFS();
// Use this function normally to create LLVFS files
// Pass 0 to not presize
static LLVFS * createLLVFS(const std::string& index_filename,
const std::string& data_filename,
const BOOL read_only,
const U32 presize,
const BOOL remove_after_crash);
BOOL isValid() const { return (VFSVALID_OK == mValid); }
EVFSValid getValidState() const { return mValid; }
// ---------- The following fucntions lock/unlock mDataMutex ----------
BOOL getExists(const LLUUID &file_id, const LLAssetType::EType file_type);
S32 getSize(const LLUUID &file_id, const LLAssetType::EType file_type);
BOOL checkAvailable(S32 max_size);
S32 getMaxSize(const LLUUID &file_id, const LLAssetType::EType file_type);
BOOL setMaxSize(const LLUUID &file_id, const LLAssetType::EType file_type, S32 max_size);
void renameFile(const LLUUID &file_id, const LLAssetType::EType file_type,
const LLUUID &new_id, const LLAssetType::EType &new_type);
void removeFile(const LLUUID &file_id, const LLAssetType::EType file_type);
S32 getData(const LLUUID &file_id, const LLAssetType::EType file_type, U8 *buffer, S32 location, S32 length);
S32 storeData(const LLUUID &file_id, const LLAssetType::EType file_type, const U8 *buffer, S32 location, S32 length);
void incLock(const LLUUID &file_id, const LLAssetType::EType file_type, EVFSLock lock);
void decLock(const LLUUID &file_id, const LLAssetType::EType file_type, EVFSLock lock);
BOOL isLocked(const LLUUID &file_id, const LLAssetType::EType file_type, EVFSLock lock);
// ----------------------------------------------------------------
// Used to trigger evil WinXP behavior of "preloading" entire file into memory.
void pokeFiles();
// Verify that the index file contents match the in-memory file structure
// Very slow, do not call routinely. JC
void audit();
// Check for uninitialized blocks. Slow, do not call in release. JC
void checkMem();
// for debugging, prints a map of the vfs
void dumpMap();
void dumpLockCounts();
void dumpStatistics();
void listFiles();
void dumpFiles();
time_t creationTime();
protected:
void removeFileBlock(LLVFSFileBlock *fileblock);
void eraseBlockLength(LLVFSBlock *block);
void eraseBlock(LLVFSBlock *block);
void addFreeBlock(LLVFSBlock *block);
//void mergeFreeBlocks();
void useFreeSpace(LLVFSBlock *free_block, S32 length);
void sync(LLVFSFileBlock *block, BOOL remove = FALSE);
void presizeDataFile(const U32 size);
static LLFILE *openAndLock(const std::string& filename, const char* mode, BOOL read_lock);
static void unlockAndClose(FILE *fp);
// Can initiate LRU-based file removal to make space.
// The immune file block will not be removed.
LLVFSBlock *findFreeBlock(S32 size, LLVFSFileBlock *immune = NULL);
// lock/unlock data mutex (mDataMutex)
void lockData() { mDataMutex->lock(); }
void unlockData() { mDataMutex->unlock(); }
protected:
LLMutex* mDataMutex;
typedef std::map<LLVFSFileSpecifier, LLVFSFileBlock*> fileblock_map;
fileblock_map mFileBlocks;
typedef std::multimap<S32, LLVFSBlock*> blocks_length_map_t;
blocks_length_map_t mFreeBlocksByLength;
typedef std::multimap<U32, LLVFSBlock*> blocks_location_map_t;
blocks_location_map_t mFreeBlocksByLocation;
LLFILE *mDataFP;
LLFILE *mIndexFP;
std::deque<S32> mIndexHoles;
std::string mIndexFilename;
std::string mDataFilename;
BOOL mReadOnly;
EVFSValid mValid;
S32 mLockCounts[VFSLOCK_COUNT];
BOOL mRemoveAfterCrash;
// <FS:ND> Query when this cache was created, Returns the time and date in UTC, or unknown,
public:
std::string getCreationDataUTC() const;
// </FS:ND>
};
extern LLVFS *gVFS;
#endif

View File

@ -1,300 +0,0 @@
/**
* @file llvfsthread.cpp
* @brief LLVFSThread implementation
*
* $LicenseInfo:firstyear=2001&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 "llvfsthread.h"
#include "llstl.h"
//============================================================================
/*static*/ std::string LLVFSThread::sDataPath = "";
/*static*/ LLVFSThread* LLVFSThread::sLocal = NULL;
//============================================================================
// Run on MAIN thread
//static
void LLVFSThread::initClass(bool local_is_threaded)
{
llassert(sLocal == NULL);
sLocal = new LLVFSThread(local_is_threaded);
}
//static
S32 LLVFSThread::updateClass(U32 ms_elapsed)
{
sLocal->update((F32)ms_elapsed);
return sLocal->getPending();
}
//static
void LLVFSThread::cleanupClass()
{
sLocal->setQuitting();
while (sLocal->getPending())
{
sLocal->update(0);
}
delete sLocal;
sLocal = 0;
}
//----------------------------------------------------------------------------
LLVFSThread::LLVFSThread(bool threaded) :
LLQueuedThread("VFS", threaded)
{
}
LLVFSThread::~LLVFSThread()
{
// ~LLQueuedThread() will be called here
}
//----------------------------------------------------------------------------
LLVFSThread::handle_t LLVFSThread::read(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
U8* buffer, S32 offset, S32 numbytes, U32 priority, U32 flags)
{
handle_t handle = generateHandle();
priority = llmax(priority, (U32)PRIORITY_LOW); // All reads are at least PRIORITY_LOW
Request* req = new Request(handle, priority, flags, FILE_READ, vfs, file_id, file_type,
buffer, offset, numbytes);
bool res = addRequest(req);
if (!res)
{
LL_ERRS() << "LLVFSThread::read called after LLVFSThread::cleanupClass()" << LL_ENDL;
req->deleteRequest();
handle = nullHandle();
}
return handle;
}
S32 LLVFSThread::readImmediate(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
U8* buffer, S32 offset, S32 numbytes)
{
handle_t handle = generateHandle();
Request* req = new Request(handle, PRIORITY_IMMEDIATE, 0, FILE_READ, vfs, file_id, file_type,
buffer, offset, numbytes);
S32 res = addRequest(req) ? 1 : 0;
if (res == 0)
{
LL_ERRS() << "LLVFSThread::read called after LLVFSThread::cleanupClass()" << LL_ENDL;
req->deleteRequest();
}
else
{
llverify(waitForResult(handle, false) == true);
res = req->getBytesRead();
completeRequest(handle);
}
return res;
}
LLVFSThread::handle_t LLVFSThread::write(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
U8* buffer, S32 offset, S32 numbytes, U32 flags)
{
handle_t handle = generateHandle();
Request* req = new Request(handle, 0, flags, FILE_WRITE, vfs, file_id, file_type,
buffer, offset, numbytes);
bool res = addRequest(req);
if (!res)
{
LL_ERRS() << "LLVFSThread::read called after LLVFSThread::cleanupClass()" << LL_ENDL;
req->deleteRequest();
handle = nullHandle();
}
return handle;
}
S32 LLVFSThread::writeImmediate(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
U8* buffer, S32 offset, S32 numbytes)
{
handle_t handle = generateHandle();
Request* req = new Request(handle, PRIORITY_IMMEDIATE, 0, FILE_WRITE, vfs, file_id, file_type,
buffer, offset, numbytes);
S32 res = addRequest(req) ? 1 : 0;
if (res == 0)
{
LL_ERRS() << "LLVFSThread::read called after LLVFSThread::cleanupClass()" << LL_ENDL;
req->deleteRequest();
}
else
{
llverify(waitForResult(handle, false) == true);
res = req->getBytesRead();
completeRequest(handle);
}
return res;
}
// LLVFSThread::handle_t LLVFSThread::rename(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
// const LLUUID &new_id, const LLAssetType::EType new_type, U32 flags)
// {
// handle_t handle = generateHandle();
// LLUUID* new_idp = new LLUUID(new_id); // deleted with Request
// // new_type is passed as "numbytes"
// Request* req = new Request(handle, 0, flags, FILE_RENAME, vfs, file_id, file_type,
// (U8*)new_idp, 0, (S32)new_type);
// bool res = addRequest(req);
// if (!res)
// {
// LL_ERRS() << "LLVFSThread::read called after LLVFSThread::cleanupClass()" << LL_ENDL;
// req->deleteRequest();
// handle = nullHandle();
// }
// return handle;
// }
//============================================================================
LLVFSThread::Request::Request(handle_t handle, U32 priority, U32 flags,
operation_t op, LLVFS* vfs,
const LLUUID &file_id, const LLAssetType::EType file_type,
U8* buffer, S32 offset, S32 numbytes) :
QueuedRequest(handle, priority, flags),
mOperation(op),
mVFS(vfs),
mFileID(file_id),
mFileType(file_type),
mBuffer(buffer),
mOffset(offset),
mBytes(numbytes),
mBytesRead(0)
{
llassert(mBuffer);
if (numbytes <= 0 && mOperation != FILE_RENAME)
{
LL_WARNS() << "LLVFSThread: Request with numbytes = " << numbytes
<< " operation = " << op
<< " offset " << offset
<< " file_type " << file_type << LL_ENDL;
}
if (mOperation == FILE_WRITE)
{
S32 blocksize = mVFS->getMaxSize(mFileID, mFileType);
if (blocksize < 0)
{
LL_WARNS() << "VFS write to temporary block (shouldn't happen)" << LL_ENDL;
}
mVFS->incLock(mFileID, mFileType, VFSLOCK_APPEND);
}
else if (mOperation == FILE_RENAME)
{
mVFS->incLock(mFileID, mFileType, VFSLOCK_APPEND);
}
else // if (mOperation == FILE_READ)
{
mVFS->incLock(mFileID, mFileType, VFSLOCK_READ);
}
}
// dec locks as soon as a request finishes
void LLVFSThread::Request::finishRequest(bool completed)
{
if (mOperation == FILE_WRITE)
{
mVFS->decLock(mFileID, mFileType, VFSLOCK_APPEND);
}
else if (mOperation == FILE_RENAME)
{
mVFS->decLock(mFileID, mFileType, VFSLOCK_APPEND);
}
else // if (mOperation == FILE_READ)
{
mVFS->decLock(mFileID, mFileType, VFSLOCK_READ);
}
}
void LLVFSThread::Request::deleteRequest()
{
if (getStatus() == STATUS_QUEUED)
{
LL_ERRS() << "Attempt to delete a queued LLVFSThread::Request!" << LL_ENDL;
}
if (mOperation == FILE_WRITE)
{
if (mFlags & FLAG_AUTO_DELETE)
{
delete [] mBuffer;
}
}
else if (mOperation == FILE_RENAME)
{
LLUUID* new_idp = (LLUUID*)mBuffer;
delete new_idp;
}
LLQueuedThread::QueuedRequest::deleteRequest();
}
bool LLVFSThread::Request::processRequest()
{
bool complete = false;
if (mOperation == FILE_READ)
{
llassert(mOffset >= 0);
mBytesRead = mVFS->getData(mFileID, mFileType, mBuffer, mOffset, mBytes);
complete = true;
//LL_INFOS() << llformat("LLVFSThread::READ '%s': %d bytes arg:%d",getFilename(),mBytesRead) << LL_ENDL;
}
else if (mOperation == FILE_WRITE)
{
mBytesRead = mVFS->storeData(mFileID, mFileType, mBuffer, mOffset, mBytes);
complete = true;
//LL_INFOS() << llformat("LLVFSThread::WRITE '%s': %d bytes arg:%d",getFilename(),mBytesRead) << LL_ENDL;
}
else if (mOperation == FILE_RENAME)
{
LLUUID* new_idp = (LLUUID*)mBuffer;
LLAssetType::EType new_type = (LLAssetType::EType)mBytes;
mVFS->renameFile(mFileID, mFileType, *new_idp, new_type);
mFileID = *new_idp;
complete = true;
//LL_INFOS() << llformat("LLVFSThread::RENAME '%s': %d bytes arg:%d",getFilename(),mBytesRead) << LL_ENDL;
}
else
{
LL_ERRS() << llformat("LLVFSThread::unknown operation: %d", mOperation) << LL_ENDL;
}
return complete;
}
//============================================================================

View File

@ -1,140 +0,0 @@
/**
* @file llvfsthread.h
* @brief LLVFSThread definition
*
* $LicenseInfo:firstyear=2001&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$
*/
#ifndef LL_LLVFSTHREAD_H
#define LL_LLVFSTHREAD_H
#include <queue>
#include <string>
#include <map>
#include <set>
#include "llqueuedthread.h"
#include "llvfs.h"
//============================================================================
class LLVFSThread : public LLQueuedThread
{
//------------------------------------------------------------------------
public:
enum operation_t {
FILE_READ,
FILE_WRITE,
FILE_RENAME
};
//------------------------------------------------------------------------
public:
class Request : public QueuedRequest
{
protected:
~Request() {}; // use deleteRequest()
public:
Request(handle_t handle, U32 priority, U32 flags,
operation_t op, LLVFS* vfs,
const LLUUID &file_id, const LLAssetType::EType file_type,
U8* buffer, S32 offset, S32 numbytes);
S32 getBytesRead()
{
return mBytesRead;
}
S32 getOperation()
{
return mOperation;
}
U8* getBuffer()
{
return mBuffer;
}
LLVFS* getVFS()
{
return mVFS;
}
std::string getFilename()
{
std::string tstring;
mFileID.toString(tstring);
return tstring;
}
/*virtual*/ bool processRequest();
/*virtual*/ void finishRequest(bool completed);
/*virtual*/ void deleteRequest();
private:
operation_t mOperation;
LLVFS* mVFS;
LLUUID mFileID;
LLAssetType::EType mFileType;
U8* mBuffer; // dest for reads, source for writes, new UUID for rename
S32 mOffset; // offset into file, -1 = append (WRITE only)
S32 mBytes; // bytes to read from file, -1 = all (new mFileType for rename)
S32 mBytesRead; // bytes read from file
};
//------------------------------------------------------------------------
public:
static std::string sDataPath;
static LLVFSThread* sLocal; // Default worker thread
public:
LLVFSThread(bool threaded = TRUE);
~LLVFSThread();
// Return a Request handle
handle_t read(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type, /* Flawfinder: ignore */
U8* buffer, S32 offset, S32 numbytes, U32 pri=PRIORITY_NORMAL, U32 flags = 0);
handle_t write(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
U8* buffer, S32 offset, S32 numbytes, U32 flags);
// SJB: rename seems to have issues, especially when threaded
// handle_t rename(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
// const LLUUID &new_id, const LLAssetType::EType new_type, U32 flags);
// Return number of bytes read
S32 readImmediate(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
U8* buffer, S32 offset, S32 numbytes);
S32 writeImmediate(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
U8* buffer, S32 offset, S32 numbytes);
/*virtual*/ bool processRequest(QueuedRequest* req);
public:
static void initClass(bool local_is_threaded = TRUE); // Setup sLocal
static S32 updateClass(U32 ms_elapsed);
static void cleanupClass(); // Delete sLocal
static void setDataPath(const std::string& path) { sDataPath = path; }
};
//============================================================================
#endif // LL_LLVFSTHREAD_H

View File

@ -16,7 +16,7 @@ include(LLCommon)
include(LLImage)
include(LLMath)
include(LLRender)
include(LLVFS)
include(LLFileSystem)
include(LLWindow)
include(LLXML)
include(UI)
@ -26,7 +26,7 @@ include_directories(
${LLIMAGE_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
)
@ -72,7 +72,7 @@ if (LINUX)
${LLIMAGE_LIBRARIES}
${LLMATH_LIBRARIES}
${LLRENDER_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
#${LLWINDOW_LIBRARIES} # <FS:Ansariel> Don't link to itself - causes CMP0038
${LLXML_LIBRARIES}
${UI_LIBRARIES} # for GTK
@ -95,7 +95,7 @@ if (LINUX)
${LLIMAGE_LIBRARIES}
${LLMATH_LIBRARIES}
${LLRENDER_HEADLESS_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLWINDOW_HEADLESS_LIBRARIES}
${LLXML_LIBRARIES}
fontconfig # For FCInit and other FC* functions.

View File

@ -5,13 +5,13 @@ project(llxml)
include(00-Common)
include(LLCommon)
include(LLMath)
include(LLVFS)
include(LLFileSystem)
include(LLXML)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
)
include_directories(
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
@ -42,7 +42,7 @@ add_library (llxml ${llxml_SOURCE_FILES})
# Libraries on which this library depends, needed for Linux builds
# Sort by high-level to low-level
target_link_libraries( llxml
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES}
${EXPAT_LIBRARIES}

View File

@ -8,7 +8,7 @@ include(LLCoreHttp)
include(LLCrashLogger)
include(LLMath)
include(LLMessage)
include(LLVFS)
include(LLFilesystem)
include(LLXML)
include(Linking)
include(LLSharedLibs)
@ -19,7 +19,7 @@ include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLCRASHLOGGER_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
)
include_directories(SYSTEM
@ -68,11 +68,10 @@ find_library(COCOA_LIBRARY Cocoa)
target_link_libraries(mac-crash-logger
${LLCRASHLOGGER_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${COCOA_LIBRARIES}
${LLXML_LIBRARIES}
${LLMESSAGE_LIBRARIES}
${LLVFS_LIBRARIES}
${LLMATH_LIBRARIES}
${LLCOREHTTP_LIBRARIES}
${LLCOMMON_LIBRARIES}

View File

@ -27,7 +27,6 @@
#include "linden_common.h"
#include "llcrashloggermac.h"
#include "indra_constants.h"
#include "llpidlock.h"
#include <iostream>

View File

@ -39,7 +39,7 @@ include(LLPlugin)
include(LLPrimitive)
include(LLRender)
include(LLUI)
include(LLVFS)
include(LLFileSystem)
include(LLWindow)
include(LLXML)
include(NDOF)
@ -95,7 +95,7 @@ include_directories(
${LLPRIMITIVE_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
${LLUI_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLFILESYSTEM_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
${LLLOGIN_INCLUDE_DIRS}
@ -2471,7 +2471,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLRENDER_LIBRARIES}
${FREETYPE_LIBRARIES}
${LLUI_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLWINDOW_LIBRARIES}
${LLXML_LIBRARIES}
${LLMATH_LIBRARIES}
@ -3004,7 +3004,7 @@ if (LL_TESTS)
set(test_libs
${LLMESSAGE_LIBRARIES}
${WINDOWS_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES}
${GOOGLEMOCK_LIBRARIES}
@ -3019,7 +3019,7 @@ if (LL_TESTS)
set(test_libs
${WINDOWS_LIBRARIES}
${LLVFS_LIBRARIES}
${LLFILESYSTEM_LIBRARIES}
${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES}
${LLMESSAGE_LIBRARIES}

View File

@ -1 +1 @@
6.4.14
6.4.15

View File

@ -34,11 +34,11 @@
#include "llagentcamera.h"
#include "llanimationstates.h"
#include "llassetstorage.h"
#include "llfilesystem.h"
#include "llinventoryfunctions.h" // for ROOT_FIRESTORM_FOLDER
#include "llinventorymodel.h"
#include "llnotificationsutil.h"
#include "llstring.h"
#include "llvfs.h"
#include "llviewercontrol.h"
#include "llviewerinventory.h"
@ -1964,7 +1964,7 @@ bool AOEngine::importNotecard(const LLInventoryItem* item)
}
// static
void AOEngine::onNotecardLoadComplete(LLVFS* vfs, const LLUUID& assetUUID, LLAssetType::EType type,
void AOEngine::onNotecardLoadComplete(const LLUUID& assetUUID, LLAssetType::EType type,
void* userdata, S32 status, LLExtStat extStatus)
{
if (status != LL_ERR_NOERR)
@ -1977,10 +1977,13 @@ void AOEngine::onNotecardLoadComplete(LLVFS* vfs, const LLUUID& assetUUID, LLAss
}
LL_DEBUGS("AOEngine") << "Downloading import notecard complete." << LL_ENDL;
S32 notecardSize = vfs->getSize(assetUUID, type);
char* buffer = new char[notecardSize];
LLFileSystem file(assetUUID, type, LLFileSystem::READ);
S32 ret = vfs->getData(assetUUID, type, reinterpret_cast<U8*>(buffer), 0, notecardSize);
S32 notecardSize = file.getSize();
char* buffer = new char[notecardSize + 1];
buffer[notecardSize] = 0;
S32 ret = file.read((U8*)buffer, notecardSize);
if (ret > 0)
{
AOEngine::instance().parseNotecard(buffer);

View File

@ -185,7 +185,7 @@ class AOEngine
void onToggleAOStandsControl();
void onPauseAO();
static void onNotecardLoadComplete(LLVFS* vfs, const LLUUID& assetUUID, LLAssetType::EType type,
static void onNotecardLoadComplete(const LLUUID& assetUUID, LLAssetType::EType type,
void* userdata, S32 status, LLExtStat extStatus);
void parseNotecard(const char* buffer);

View File

@ -2930,6 +2930,39 @@
<key>Value</key>
<integer>23</integer>
</map>
<key>EnableCacheDebugInfo</key>
<map>
<key>Comment</key>
<string>When set, display additional cache debugging information</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>DiskCachePercentOfTotal</key>
<map>
<key>Comment</key>
<string>The percent of total cache size (defined by CacheSize) to use for the disk cache</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>20.0</real>
</map>
<key>DiskCacheDirName</key>
<map>
<key>Comment</key>
<string>The name of the disk cache (within the standard Viewer disk cache directory)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>cache</string>
</map>
<key>CacheLocation</key>
<map>
<key>Comment</key>
@ -4646,17 +4679,6 @@
<key>Value</key>
<integer>-1</integer>
</map>
<key>DebugStatModeVFSPendingOps</key>
<map>
<key>Comment</key>
<string>Mode of stat in Statistics floater</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>-1</integer>
</map>
<key>DebugStatModeTimeDialation</key>
<map>
<key>Comment</key>
@ -5702,19 +5724,6 @@
<key>Value</key>
<integer>4</integer>
</map>
<key>DumpVFSCaches</key>
<map>
<key>Comment</key>
<string>Dump VFS caches on startup.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
<key>Backup</key>
<integer>0</integer>
</map>
<key>DynamicCameraStrength</key>
<map>
<key>Comment</key>
@ -14668,7 +14677,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
</map>
<key>NearbyListShowIcons</key>
<map>
<key>Comment</key>
@ -17878,33 +17887,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>VFSOldSize</key>
<map>
<key>Comment</key>
<string>[DO NOT MODIFY] Controls resizing of local file cache</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>0</integer>
<key>Backup</key>
<integer>0</integer>
</map>
<key>VFSSalt</key>
<map>
<key>Comment</key>
<string>[DO NOT MODIFY] Controls local file caching behavior</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>1</integer>
<key>Backup</key>
<integer>0</integer>
</map>
<key>VelocityInterpolate</key>
<map>

View File

@ -34,7 +34,7 @@
#include "llaudioengine.h"
#include "llfloaterreg.h"
#include "llsdserialize.h"
#include "llvfs.h"
#include "llfilesystem.h"
#include "llxorcipher.h"
#include "llviewerobjectlist.h"
@ -175,7 +175,7 @@ void FSAssetBlacklist::addNewItemToBlacklistData(const LLUUID& id, const LLSD& d
if (type == LLAssetType::AT_SOUND)
{
gVFS->removeFile(id, LLAssetType::AT_SOUND);
LLFileSystem::removeFile(id, LLAssetType::AT_SOUND);
std::string wav_path = gDirUtilp->getExpandedFilename(LL_PATH_FS_SOUND_CACHE, id.asString()) + ".dsf";
if (gDirUtilp->fileExists(wav_path))
{

View File

@ -53,7 +53,7 @@
#include "llviewermedia.h"
#include "llviewernetwork.h"
#include "llxorcipher.h"
#include "llvfs.h"
#include "llfilesystem.h"
#include "message.h"
// [RLVa:KB]
@ -1071,7 +1071,7 @@ LLSD FSData::getSystemInfo()
{
sysinfo2 += llformat("Texture memory: %d MB (%.2f)\n", info["TEXTUREMEMORY"].asInteger(), info["TEXTUREMEMORYMULTIPLIER"].asReal());
}
sysinfo2 += "VFS (cache) creation time (UTC) " + info["VFS_DATE"].asString();
sysinfo2 += "Disk cache: " + info["DISK_CACHE_INFO"].asString();
LLSD sysinfos;
sysinfos["Part1"] = sysinfo1;

View File

@ -51,7 +51,7 @@
#include "lltexturectrl.h"
#include "lltrans.h"
#include "llversioninfo.h"
#include "llvfile.h"
#include "llfilesystem.h"
#include "llviewercontrol.h"
#include "llviewerinventory.h"
#include "llviewermenufile.h"
@ -619,7 +619,7 @@ bool FSFloaterObjectExport::exportTexture(const LLUUID& texture_id)
return mTextureChecked[texture_id];
}
if (gAssetStorage->mStaticVFS->getExists(texture_id, LLAssetType::AT_TEXTURE))
if (gAssetStorage->hasLocalAsset(texture_id, LLAssetType::AT_TEXTURE))
{
LL_DEBUGS("export") << "Texture " << texture_id.asString() << " is local static." << LL_ENDL;
// no need to save the texture data as the viewer already has it in a local file.
@ -838,7 +838,7 @@ void FSFloaterObjectExport::inventoryChanged(LLViewerObject* object, LLInventory
}
// static
void FSFloaterObjectExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status)
void FSFloaterObjectExport::onLoadComplete(const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status)
{
FSAssetResourceData* data = (FSAssetResourceData*)user_data;
FSFloaterObjectExport* self = (FSFloaterObjectExport*)data->user_data;
@ -853,7 +853,7 @@ void FSFloaterObjectExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid,
}
LL_DEBUGS("export") << "Saving asset " << asset_uuid.asString() << " of item " << item_uuid.asString() << LL_ENDL;
LLVFile file(vfs, asset_uuid, type);
LLFileSystem file(asset_uuid, type);
S32 file_length = file.getSize();
std::vector<U8> buffer(file_length);
file.read(&buffer[0], file_length);

View File

@ -71,7 +71,7 @@ public:
LLInventoryObject::object_list_t* inventory,
S32 serial_num,
void* user_data);
static void onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid,
static void onLoadComplete(const LLUUID& asset_uuid,
LLAssetType::EType type,
void* user_data, S32 status, LLExtStat ext_status);

View File

@ -57,8 +57,7 @@
#include "llviewerparcelmgr.h"
#include "llviewerstats.h"
#include "llviewerregion.h"
#include "llvfile.h"
#include "llvfs.h"
#include "llfilesystem.h"
#include "llvolumemessage.h"
#include "lltrace.h"
#include "fsexportperms.h"
@ -1459,7 +1458,8 @@ void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item)
tid.generate();
LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
LLVFile::writeFile((U8*)&asset_data[0], (S32)asset_data.size(), gVFS, new_asset_id, asset_type);
LLFileSystem file(new_asset_id, asset_type, LLFileSystem::WRITE);
file.write((U8*)&asset_data[0], (S32)asset_data.size());
LLResourceData* data( new LLResourceData );
data->mAssetInfo.mTransactionID = tid;
@ -1907,7 +1907,7 @@ void uploadCoroutine( LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &a_httpAdapter
return;
}
if (!gVFS->getExists(aAssetId, aAssetType))
if (!LLFileSystem::getExists(aAssetId, aAssetType))
{
LL_WARNS() << "Asset doesn't exist in VFS anymore. Nothing uploaded." << LL_ENDL;
self->pushNextAsset( LLUUID::null, fs_data->uuid, aResourceData->mAssetInfo.mType );
@ -1940,7 +1940,7 @@ void uploadCoroutine( LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &a_httpAdapter
LL_DEBUGS( "import" ) << "result: " << responseResult << " new_id: " << new_id << LL_ENDL;
// rename the file in the VFS to the actual asset id
gVFS->renameFile(aAssetId, aAssetType, new_id, aAssetType);
LLFileSystem::renameFile(aAssetId, aAssetType, new_id, aAssetType);
if( item_id.isNull() )
{

View File

@ -40,7 +40,7 @@
#include "llappviewer.h"
#include "llinventoryfunctions.h"
#include "lltrans.h"
#include "llvfile.h"
#include "llfilesystem.h"
#include "llviewercontrol.h"
#include "llcompilequeue.h"
#include "llnotificationsutil.h"
@ -720,7 +720,7 @@ void cache_script(std::string name, std::string content)
infile.close();
}
void FSLSLPreprocessor::FSProcCacheCallback(LLVFS *vfs, const LLUUID& iuuid, LLAssetType::EType type, void *userdata, S32 result, LLExtStat extstat)
void FSLSLPreprocessor::FSProcCacheCallback(const LLUUID& iuuid, LLAssetType::EType type, void *userdata, S32 result, LLExtStat extstat)
{
LLUUID uuid = iuuid;
LL_DEBUGS("FSLSLPreprocessor") << "cachecallback called" << LL_ENDL;
@ -732,7 +732,7 @@ void FSLSLPreprocessor::FSProcCacheCallback(LLVFS *vfs, const LLUUID& iuuid, LLA
std::string name = item->getName();
if (result == LL_ERR_NOERR)
{
LLVFile file(vfs, uuid, type);
LLFileSystem file(uuid, type);
S32 file_length = file.getSize();
std::string content;

View File

@ -63,7 +63,7 @@ public:
std::string lslcomp(std::string script);
static LLUUID findInventoryByName(std::string name);
static void FSProcCacheCallback(LLVFS *vfs, const LLUUID& uuid, LLAssetType::EType type,
static void FSProcCacheCallback(const LLUUID& uuid, LLAssetType::EType type,
void *userdata, S32 result, LLExtStat extstat);
void preprocess_script(BOOL close = FALSE, bool sync = false, bool defcache = false);
void preprocess_script(const LLUUID& asset_id, LLScriptQueueData* data, LLAssetType::EType type, const std::string& script_data);

View File

@ -98,6 +98,7 @@
#include "lllogininstance.h"
#include "llprogressview.h"
#include "llvocache.h"
#include "lldiskcache.h"
#include "llvopartgroup.h"
// [SL:KB] - Patch: Appearance-Misc | Checked: 2013-02-12 (Catznip-3.4)
#include "llappearancemgr.h"
@ -129,8 +130,6 @@
#include "llprimitive.h"
#include "llurlaction.h"
#include "llurlentry.h"
#include "llvfile.h"
#include "llvfsthread.h"
#include "llvolumemgr.h"
#include "llxfermanager.h"
#include "llphysicsextensions.h"
@ -370,9 +369,6 @@ bool gUseWireframe = FALSE;
//use for remember deferred mode in wireframe switch
bool gInitialDeferredModeForWireframe = FALSE;
// VFS globals - see llappviewer.h
LLVFS* gStaticVFS = NULL;
LLMemoryInfo gSysMemory;
U64Bytes gMemoryAllocated(0); // updated in display_stats() in llviewerdisplay.cpp
@ -493,11 +489,6 @@ void init_default_trans_args()
default_trans_args.insert("APP_NAME_ABBR"); // <FS:Ansariel> Appreviated application title
}
//----------------------------------------------------------------------------
// File scope definitons
const char *VFS_DATA_FILE_BASE = "data.db2.x.";
const char *VFS_INDEX_FILE_BASE = "index.db2.x.";
std::string gWindowTitle;
struct SettingsFile : public LLInitParam::Block<SettingsFile>
@ -1172,10 +1163,6 @@ bool LLAppViewer::init()
// *Note: this is where gViewerStats used to be created.
//
// Initialize the VFS, and gracefully handle initialization errors
//
if (!initCache())
{
LL_WARNS("InitInfo") << "Failed to init cache" << LL_ENDL;
@ -1609,7 +1596,6 @@ static LLTrace::BlockTimerStatHandle FTM_TEXTURE_CACHE("Texture Cache");
static LLTrace::BlockTimerStatHandle FTM_DECODE("Image Decode");
static LLTrace::BlockTimerStatHandle FTM_FETCH("Image Fetch");
static LLTrace::BlockTimerStatHandle FTM_VFS("VFS Thread");
static LLTrace::BlockTimerStatHandle FTM_LFS("LFS Thread");
static LLTrace::BlockTimerStatHandle FTM_PAUSE_THREADS("Pause Threads");
static LLTrace::BlockTimerStatHandle FTM_IDLE("Idle");
@ -1887,10 +1873,6 @@ bool LLAppViewer::doFrame()
work_pending += updateTextureThreads(max_time);
{
LL_RECORD_BLOCK_TIME(FTM_VFS);
io_pending += LLVFSThread::updateClass(1);
}
{
LL_RECORD_BLOCK_TIME(FTM_LFS);
io_pending += LLLFSThread::updateClass(1);
@ -1898,7 +1880,7 @@ bool LLAppViewer::doFrame()
if (io_pending > 1000)
{
ms_sleep(llmin(io_pending/100,100)); // give the vfs some time to catch up
ms_sleep(llmin(io_pending/100,100)); // give the lfs some time to catch up
}
total_work_pending += work_pending ;
@ -1915,7 +1897,6 @@ bool LLAppViewer::doFrame()
}
if(!total_io_pending) //pause file threads if nothing to process.
{
LLVFSThread::sLocal->pause();
LLLFSThread::sLocal->pause();
}
@ -1994,12 +1975,11 @@ S32 LLAppViewer::updateTextureThreads(F32 max_time)
return work_pending;
}
void LLAppViewer::flushVFSIO()
void LLAppViewer::flushLFSIO()
{
while (1)
{
S32 pending = LLVFSThread::updateClass(0);
pending += LLLFSThread::updateClass(0);
S32 pending = LLLFSThread::updateClass(0);
if (!pending)
{
break;
@ -2135,7 +2115,7 @@ bool LLAppViewer::cleanup()
LLKeyframeDataCache::clear();
// End TransferManager before deleting systems it depends on (Audio, VFS, AssetStorage)
// End TransferManager before deleting systems it depends on (Audio, AssetStorage)
#if 0 // this seems to get us stuck in an infinite loop...
gTransferManager.cleanup();
#endif
@ -2209,8 +2189,8 @@ bool LLAppViewer::cleanup()
LL_INFOS() << "Cache files removed" << LL_ENDL;
// Wait for any pending VFS IO
flushVFSIO();
// Wait for any pending LFS IO
flushLFSIO();
LL_INFOS() << "Shutting down Views" << LL_ENDL;
// Destroy the UI
@ -2294,15 +2274,6 @@ bool LLAppViewer::cleanup()
SUBSYSTEM_CLEANUP(LLWorldMapView);
SUBSYSTEM_CLEANUP(LLFolderViewItem);
//
// Shut down the VFS's AFTER the decode manager cleans up (since it cleans up vfiles).
// Also after viewerwindow is deleted, since it may have image pointers (which have vfiles)
// Also after shutting down the messaging system since it has VFS dependencies
//
LL_INFOS() << "Cleaning up VFS" << LL_ENDL;
SUBSYSTEM_CLEANUP(LLVFile);
LL_INFOS() << "Saving Data" << LL_ENDL;
// Store the time of our current logoff
@ -2427,7 +2398,6 @@ bool LLAppViewer::cleanup()
pending += LLAppViewer::getTextureCache()->update(1); // unpauses the worker thread
pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread
pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
pending += LLVFSThread::updateClass(0);
pending += LLLFSThread::updateClass(0);
F64 idle_time = idleTimer.getElapsedTimeF64();
if(!pending)
@ -2502,28 +2472,11 @@ bool LLAppViewer::cleanup()
gTextureList.shutdown(); // shutdown again in case a callback added something
LLUIImageList::getInstance()->cleanUp();
// This should eventually be done in LLAppViewer
SUBSYSTEM_CLEANUP(LLImage);
SUBSYSTEM_CLEANUP(LLVFSThread);
SUBSYSTEM_CLEANUP(LLLFSThread);
#ifndef LL_RELEASE_FOR_DOWNLOAD
LL_INFOS() << "Auditing VFS" << LL_ENDL;
if(gVFS)
{
gVFS->audit();
}
#endif
LL_INFOS() << "Misc Cleanup" << LL_ENDL;
// For safety, the LLVFS has to be deleted *after* LLVFSThread. This should be cleaned up.
// (LLVFS doesn't know about LLVFSThread so can't kill pending requests) -Steve
delete gStaticVFS;
gStaticVFS = NULL;
delete gVFS;
gVFS = NULL;
gSavedSettings.cleanup();
LLUIColorTable::instance().clear();
@ -2605,7 +2558,6 @@ bool LLAppViewer::initThreads()
LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
LLVFSThread::initClass(enable_threads && false);
LLLFSThread::initClass(enable_threads && false);
// Image decoding
@ -3894,10 +3846,6 @@ LLSD LLAppViewer::getViewerInfo() const
//info["RENDER_QUALITY"] = (F32)gSavedSettings.getU32("RenderQualityPerformance");
//info["GPU_SHADERS"] = gSavedSettings.getBOOL("RenderDeferred") ? "Enabled" : "Disabled";
//info["TEXTURE_MEMORY"] = gSavedSettings.getS32("TextureMemory");
//LLSD substitution;
//substitution["datetime"] = (S32)(gVFS ? gVFS->creationTime() : 0);
//info["VFS_TIME"] = LLTrans::getString("AboutTime", substitution);
// </FS>
#if LL_DARWIN
@ -3991,6 +3939,9 @@ LLSD LLAppViewer::getViewerInfo() const
info["SERVER_RELEASE_NOTES_URL"] = mServerReleaseNotesURL;
}
// populate field for new local disk cache with some details
info["DISK_CACHE_INFO"] = LLDiskCache::getInstance()->getCacheInfo();
// <FS:PP> FIRE-4785: Current render quality setting in sysinfo / about floater
switch (gSavedSettings.getU32("RenderQualityPerformance"))
{
@ -4051,13 +4002,6 @@ LLSD LLAppViewer::getViewerInfo() const
info["TEXTUREMEMORYGPURESERVE"] = gSavedSettings.getS32("FSDynamicTextureMemoryGPUReserve");
// </FS:Ansariel>
// <FS:ND> Add creation time of VFS (cache)
if( gVFS )
info["VFS_DATE"] = gVFS->getCreationDataUTC();
else
info["VFS_DATE"] = "unknown";
// </FS:ND>
return info;
}
@ -4140,9 +4084,9 @@ std::string LLAppViewer::getViewerInfoString(bool default_string) const
support << "\n" << LLTrans::getString("AboutTextureMemory", args, default_string);
}
}
if (info.has("VFS_DATE"))
if (info.has("DISK_CACHE_INFO"))
{
support << "\n" << LLTrans::getString("AboutVFS", args, default_string);
support << "\n" << LLTrans::getString("AboutCache", args, default_string);
}
// </FS>
if (info.has("COMPILER"))
@ -4760,7 +4704,7 @@ void LLAppViewer::forceQuit()
void LLAppViewer::fastQuit(S32 error_code)
{
// finish pending transfers
flushVFSIO();
flushLFSIO();
// let sim know we're logging out
sendLogoutRequest();
// flush network buffers by shutting down messaging system
@ -4961,39 +4905,6 @@ void LLAppViewer::migrateCacheDirectory()
#endif // LL_WINDOWS || LL_DARWIN
}
void dumpVFSCaches()
{
LL_INFOS() << "======= Static VFS ========" << LL_ENDL;
gStaticVFS->listFiles();
#if LL_WINDOWS
LL_INFOS() << "======= Dumping static VFS to StaticVFSDump ========" << LL_ENDL;
WCHAR w_str[MAX_PATH];
GetCurrentDirectory(MAX_PATH, w_str);
S32 res = LLFile::mkdir("StaticVFSDump");
if (res == -1)
{
LL_WARNS() << "Couldn't create dir StaticVFSDump" << LL_ENDL;
}
SetCurrentDirectory(utf8str_to_utf16str("StaticVFSDump").c_str());
gStaticVFS->dumpFiles();
SetCurrentDirectory(w_str);
#endif
LL_INFOS() << "========= Dynamic VFS ====" << LL_ENDL;
gVFS->listFiles();
#if LL_WINDOWS
LL_INFOS() << "========= Dumping dynamic VFS to VFSDump ====" << LL_ENDL;
res = LLFile::mkdir("VFSDump");
if (res == -1)
{
LL_WARNS() << "Couldn't create dir VFSDump" << LL_ENDL;
}
SetCurrentDirectory(utf8str_to_utf16str("VFSDump").c_str());
gVFS->dumpFiles();
SetCurrentDirectory(w_str);
#endif
}
//static
U32 LLAppViewer::getTextureCacheVersion()
{
@ -5020,6 +4931,19 @@ bool LLAppViewer::initCache()
LLAppViewer::getTextureCache()->setReadOnly(read_only) ;
LLVOCache::initParamSingleton(read_only);
// initialize the new disk cache using saved settings
const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName");
// note that the maximum size of this cache is defined as a percentage of the
// total cache size - the 'CacheSize' pref - for all caches.
const unsigned int cache_total_size_mb = gSavedSettings.getU32("CacheSize");
const double disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal");
const unsigned int disk_cache_mb = cache_total_size_mb * disk_cache_percent / 100;
const unsigned int disk_cache_bytes = disk_cache_mb * 1024 * 1024;
const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo");
const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name);
LLDiskCache::initParamSingleton(cache_dir, disk_cache_bytes, enable_cache_debug_info);
bool texture_cache_mismatch = false;
if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion())
{
@ -5089,10 +5013,21 @@ bool LLAppViewer::initCache()
}
// </FS:Ansariel>
if (mPurgeCache && !read_only)
if (!read_only)
{
LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
purgeCache();
if (mPurgeCache)
{
LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
purgeCache();
// clear the new C++ file system based cache
LLDiskCache::getInstance()->clearCache();
}
else
{
// purge excessive files from the new file system based cache
LLDiskCache::getInstance()->purge();
}
}
// <FS:Ansariel> FIRE-13066
@ -5127,172 +5062,18 @@ bool LLAppViewer::initCache()
const S32 MB = 1024 * 1024;
const S64 MIN_CACHE_SIZE = 256 * MB;
const S64 MAX_CACHE_SIZE = 9984ll * MB;
const S64 MAX_VFS_SIZE = 1024 * MB; // 1 GB
S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB;
cache_size = llclamp(cache_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE);
S64 vfs_size = llmin((S64)((cache_size * 2) / 10), MAX_VFS_SIZE);
S64 texture_cache_size = cache_size - vfs_size;
S64 texture_cache_size = cache_size;
S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
texture_cache_size -= extra;
LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion());
LLSplashScreen::update(LLTrans::getString("StartupInitializingVFS"));
// Init the VFS
vfs_size = llmin(vfs_size + extra, MAX_VFS_SIZE);
vfs_size = (vfs_size / MB) * MB; // make sure it is MB aligned
U32 vfs_size_u32 = (U32)vfs_size;
U32 old_vfs_size = gSavedSettings.getU32("VFSOldSize") * MB;
bool resize_vfs = (vfs_size_u32 != old_vfs_size);
if (resize_vfs)
{
gSavedSettings.setU32("VFSOldSize", vfs_size_u32 / MB);
}
LL_INFOS("AppCache") << "VFS CACHE SIZE: " << vfs_size / (1024*1024) << " MB" << LL_ENDL;
// This has to happen BEFORE starting the vfs
// time_t ltime;
srand(time(NULL)); // Flawfinder: ignore
U32 old_salt = gSavedSettings.getU32("VFSSalt");
U32 new_salt;
std::string old_vfs_data_file;
std::string old_vfs_index_file;
std::string new_vfs_data_file;
std::string new_vfs_index_file;
std::string static_vfs_index_file;
std::string static_vfs_data_file;
if (gSavedSettings.getBOOL("AllowMultipleViewers"))
{
// don't mess with renaming the VFS in this case
new_salt = old_salt;
}
else
{
do
{
new_salt = rand();
} while(new_salt == old_salt);
}
old_vfs_data_file = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, VFS_DATA_FILE_BASE) + llformat("%u", old_salt);
// make sure this file exists
llstat s;
S32 stat_result = LLFile::stat(old_vfs_data_file, &s);
if (stat_result)
{
// doesn't exist, look for a data file
std::string mask;
mask = VFS_DATA_FILE_BASE;
mask += "*";
std::string dir;
dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");
std::string found_file;
LLDirIterator iter(dir, mask);
if (iter.next(found_file))
{
old_vfs_data_file = gDirUtilp->add(dir, found_file);
S32 start_pos = found_file.find_last_of('.');
if (start_pos > 0)
{
sscanf(found_file.substr(start_pos+1).c_str(), "%d", &old_salt);
}
LL_DEBUGS("AppCache") << "Default vfs data file not present, found: " << old_vfs_data_file << " Old salt: " << old_salt << LL_ENDL;
}
}
old_vfs_index_file = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, VFS_INDEX_FILE_BASE) + llformat("%u", old_salt);
stat_result = LLFile::stat(old_vfs_index_file, &s);
if (stat_result)
{
// We've got a bad/missing index file, nukem!
LL_WARNS("AppCache") << "Bad or missing vfx index file " << old_vfs_index_file << LL_ENDL;
LL_WARNS("AppCache") << "Removing old vfs data file " << old_vfs_data_file << LL_ENDL;
LLFile::remove(old_vfs_data_file);
LLFile::remove(old_vfs_index_file);
// Just in case, nuke any other old cache files in the directory.
std::string dir;
dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");
std::string mask;
mask = VFS_DATA_FILE_BASE;
mask += "*";
gDirUtilp->deleteFilesInDir(dir, mask);
mask = VFS_INDEX_FILE_BASE;
mask += "*";
gDirUtilp->deleteFilesInDir(dir, mask);
}
new_vfs_data_file = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, VFS_DATA_FILE_BASE) + llformat("%u", new_salt);
new_vfs_index_file = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, VFS_INDEX_FILE_BASE) + llformat("%u", new_salt);
static_vfs_data_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "static_data.db2");
static_vfs_index_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "static_index.db2");
if (resize_vfs)
{
LL_DEBUGS("AppCache") << "Removing old vfs and re-sizing" << LL_ENDL;
LLFile::remove(old_vfs_data_file);
LLFile::remove(old_vfs_index_file);
}
else if (old_salt != new_salt)
{
// move the vfs files to a new name before opening
LL_DEBUGS("AppCache") << "Renaming " << old_vfs_data_file << " to " << new_vfs_data_file << LL_ENDL;
LL_DEBUGS("AppCache") << "Renaming " << old_vfs_index_file << " to " << new_vfs_index_file << LL_ENDL;
LLFile::rename(old_vfs_data_file, new_vfs_data_file);
LLFile::rename(old_vfs_index_file, new_vfs_index_file);
}
// Startup the VFS...
gSavedSettings.setU32("VFSSalt", new_salt);
// Don't remove VFS after viewer crashes. If user has corrupt data, they can reinstall. JC
gVFS = LLVFS::createLLVFS(new_vfs_index_file, new_vfs_data_file, false, vfs_size_u32, false);
if (!gVFS)
{
return false;
}
gStaticVFS = LLVFS::createLLVFS(static_vfs_index_file, static_vfs_data_file, true, 0, false);
if (!gStaticVFS)
{
return false;
}
BOOL success = gVFS->isValid() && gStaticVFS->isValid();
if (!success)
{
return false;
}
else
{
LLVFile::initClass();
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (gSavedSettings.getBOOL("DumpVFSCaches"))
{
dumpVFSCaches();
}
#endif
return true;
}
return true;
}
void LLAppViewer::addOnIdleCallback(const boost::function<void()>& cb)

View File

@ -1,4 +1,5 @@
/**
* @mainpage
* @mainpage
*
* This is the sources for the Second Life Viewer;
@ -83,7 +84,7 @@ public:
virtual bool frame(); // Override for application body logic
// Application control
void flushVFSIO(); // waits for vfs transfers to complete
void flushLFSIO(); // waits for lfs transfers to complete
void forceQuit(); // Puts the viewer into 'shutting down without error' mode.
void fastQuit(S32 error_code = 0); // Shuts down the viewer immediately after sending a logout message
void requestQuit(); // Request a quit. A kinder, gentler quit.
@ -418,12 +419,6 @@ extern BOOL gRestoreGL;
extern bool gUseWireframe;
extern bool gInitialDeferredModeForWireframe;
// VFS globals - gVFS is for general use
// gStaticVFS is read-only and is shipped w/ the viewer
// it has pre-cache data like the UI .TGAs
class LLVFS;
extern LLVFS *gStaticVFS;
extern LLMemoryInfo gSysMemory;
extern U64Bytes gMemoryAllocated;

View File

@ -631,7 +631,7 @@ void LLAppViewerWin32::disableWinErrorReporting()
}
}
const S32 MAX_CONSOLE_LINES = 500;
const S32 MAX_CONSOLE_LINES = 7500;
// Only defined in newer SDKs than we currently use
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 4

View File

@ -52,7 +52,7 @@
#include "lldir.h"
#include "llnotificationsutil.h"
#include "llviewerstats.h"
#include "llvfile.h"
#include "llfilesystem.h"
#include "lluictrlfactory.h"
#include "lltrans.h"
@ -135,7 +135,7 @@ namespace
}
// *NOTE$: A minor specialization of LLScriptAssetUpload, it does not require a buffer
// (and does not save a buffer to the vFS) and it finds the compile queue window and
// (and does not save a buffer to the cache) and it finds the compile queue window and
// displays a compiling message.
class LLQueuedScriptAssetUpload : public LLScriptAssetUpload
{
@ -153,8 +153,8 @@ public:
virtual LLSD prepareUpload()
{
/* *NOTE$: The parent class (LLScriptAssetUpload will attempt to save
* the script buffer into to the VFS. Since the resource is already in
* the VFS we don't want to do that. Just put a compiling message in
* the script buffer into to the cache. Since the resource is already in
* the cache we don't want to do that. Just put a compiling message in
* the window and move on
*/
LLFloaterCompileQueue* queue = LLFloaterReg::findTypedInstance<LLFloaterCompileQueue>("compile_queue", LLSD(mQueueId));
@ -360,11 +360,11 @@ void LLFloaterCompileQueue::handleHTTPResponse(std::string pumpName, const LLSD
LLEventPumps::instance().post(pumpName, expresult);
}
// *TODO: handleSCriptRetrieval is passed into the VFS via a legacy C function pointer
// *TODO: handleSCriptRetrieval is passed into the cache via a legacy C function pointer
// future project would be to convert these to C++ callables (std::function<>) so that
// we can use bind and remove the userData parameter.
//
void LLFloaterCompileQueue::handleScriptRetrieval(LLVFS *vfs, const LLUUID& assetId,
void LLFloaterCompileQueue::handleScriptRetrieval(const LLUUID& assetId,
LLAssetType::EType type, void* userData, S32 status, LLExtStat extStatus)
{
LLSD result(LLSD::emptyMap());
@ -401,7 +401,7 @@ void LLFloaterCompileQueue::handleScriptRetrieval(LLVFS *vfs, const LLUUID& asse
if (queue && queue->mLSLProc)
{
LLVFile file(vfs, assetId, type);
LLFileSystem file(assetId, type);
S32 file_length = file.getSize();
std::vector<char> script_data(file_length + 1);
file.read((U8*)&script_data[0], file_length);

View File

@ -162,7 +162,7 @@ protected:
//bool checkAssetId(const LLUUID &assetId);
static void handleHTTPResponse(std::string pumpName, const LLSD &expresult);
static void handleScriptRetrieval(LLVFS *vfs, const LLUUID& assetId, LLAssetType::EType type, void* userData, S32 status, LLExtStat extStatus);
static void handleScriptRetrieval(const LLUUID& assetId, LLAssetType::EType type, void* userData, S32 status, LLExtStat extStatus);
private:
static void processExperienceIdResults(LLSD result, LLUUID parent);

View File

@ -144,7 +144,7 @@ public:
S32 getFileCount() const { return (S32)mFiles.size(); }
// See llvfs/lldir.h : getBaseFileName and getDirName to extract base or directory names
// see lldir.h : getBaseFileName and getDirName to extract base or directory names
// clear any lists of buffers or whatever, and make sure the file
// picker isn't locked.

View File

@ -32,8 +32,7 @@
#include "llimagej2c.h"
#include "llimagetga.h"
#include "llparcel.h"
#include "llvfile.h"
#include "llvfs.h"
#include "llfilesystem.h"
#include "llwindow.h"
#include "message.h"
@ -208,7 +207,9 @@ void LLFloaterAuction::onClickSnapshot(void* data)
LLPointer<LLImageTGA> tga = new LLImageTGA;
tga->encode(raw);
LLVFile::writeFile(tga->getData(), tga->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_IMAGE_TGA);
LLFileSystem tga_file(self->mImageID, LLAssetType::AT_IMAGE_TGA, LLFileSystem::WRITE);
tga_file.write(tga->getData(), tga->getDataSize());
raw->biasedScaleToPowerOfTwo(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT);
@ -216,7 +217,9 @@ void LLFloaterAuction::onClickSnapshot(void* data)
LLPointer<LLImageJ2C> j2c = new LLImageJ2C;
j2c->encode(raw, 0.0f);
LLVFile::writeFile(j2c->getData(), j2c->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_TEXTURE);
LLFileSystem j2c_file(self->mImageID, LLAssetType::AT_TEXTURE, LLFileSystem::WRITE);
j2c_file.write(j2c->getData(), j2c->getDataSize());
self->mImage = LLViewerTextureManager::getLocalTexture((LLImageRaw*)raw, FALSE);
gGL.getTexUnit(0)->bind(self->mImage);

View File

@ -32,7 +32,7 @@
#include "lldatapacker.h"
#include "lldir.h"
#include "llnotificationsutil.h"
#include "llvfile.h"
#include "llfilesystem.h"
#include "llapr.h"
#include "llstring.h"
@ -1416,10 +1416,9 @@ void LLFloaterBvhPreview::onBtnOK(void* userdata)
LLDataPackerBinaryBuffer dp(buffer, file_size);
if (motionp->serialize(dp))
{
LLVFile file(gVFS, motionp->getID(), LLAssetType::AT_ANIMATION, LLVFile::APPEND);
LLFileSystem file(motionp->getID(), LLAssetType::AT_ANIMATION, LLFileSystem::APPEND);
S32 size = dp.getCurrentSize();
file.setMaxSize(size);
if (file.write((U8*)buffer, size))
{
std::string name = floaterp->getChild<LLUICtrl>("name_form")->getValue().asString();

View File

@ -60,6 +60,7 @@
#include "lltabcontainer.h"
#include "llcolorswatch.h" // <FS:Beq>
#include "lltrans.h"
#include "llfilesystem.h"
#include "llcallbacklist.h"
#include "llviewertexteditor.h"
#include "llviewernetwork.h"

Some files were not shown because too many files have changed in this diff Show More