Merge branch 'DRTVWR-519' into DRTVWR-552-cache-360
# Conflicts: # indra/newview/app_settings/settings.xmlmaster
commit
ab4d4a4817
|
|
@ -226,8 +226,15 @@ Ansariel Hiller
|
|||
SL-13364
|
||||
SL-13858
|
||||
SL-13697
|
||||
SL-14939
|
||||
SL-14940
|
||||
SL-14941
|
||||
SL-13395
|
||||
SL-3136
|
||||
SL-15200
|
||||
SL-15226
|
||||
SL-15227
|
||||
SL-15398
|
||||
Aralara Rajal
|
||||
Arare Chantilly
|
||||
CHUIBUG-191
|
||||
|
|
|
|||
|
|
@ -41,7 +41,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)
|
||||
|
||||
|
|
|
|||
|
|
@ -66,11 +66,10 @@ 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")
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ set(cmake_SOURCE_FILES
|
|||
LLSharedLibs.cmake
|
||||
LLTestCommand.cmake
|
||||
LLUI.cmake
|
||||
LLVFS.cmake
|
||||
LLFileSystem.cmake
|
||||
LLWindow.cmake
|
||||
LLXML.cmake
|
||||
Linking.cmake
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
set(LLFILESYSTEM_INCLUDE_DIRS
|
||||
${LIBS_OPEN_DIR}/llfilesystem
|
||||
)
|
||||
|
||||
set(LLFILESYSTEM_LIBRARIES llfilesystem)
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
set(LLVFS_INCLUDE_DIRS
|
||||
${LIBS_OPEN_DIR}/llvfs
|
||||
)
|
||||
|
||||
set(LLVFS_LIBRARIES llvfs)
|
||||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
#include "llassettype.h"
|
||||
#include "llframetimer.h"
|
||||
|
||||
class LLVFS;
|
||||
class LLVorbisDecodeState;
|
||||
|
||||
class LLAudioDecodeMgr
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -684,13 +684,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;
|
||||
|
|
@ -1018,13 +1014,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;
|
||||
|
|
@ -1225,7 +1220,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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -50,15 +50,6 @@ const F32 DEFAULT_MIN_DISTANCE = 2.0f;
|
|||
#define MAX_CHANNELS 30
|
||||
#define MAX_BUFFERS 40 // Some extra for preloading, maybe?
|
||||
|
||||
// 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;
|
||||
|
|
@ -67,11 +58,9 @@ class LLAudioBuffer;
|
|||
class LLStreamingAudioInterface;
|
||||
struct SoundData;
|
||||
|
||||
|
||||
//
|
||||
// LLAudioEngine definition
|
||||
//
|
||||
|
||||
class LLAudioEngine
|
||||
{
|
||||
friend class LLAudioChannelOpenAL; // bleh. channel needs some listener methods.
|
||||
|
|
@ -182,7 +171,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);
|
||||
|
||||
friend class LLPipeline; // For debugging
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -39,14 +39,13 @@
|
|||
#include "llendianswizzle.h"
|
||||
#include "llkeyframemotion.h"
|
||||
#include "llquantize.h"
|
||||
#include "llvfile.h"
|
||||
#include "m3math.h"
|
||||
#include "message.h"
|
||||
#include "llfilesystem.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Static Definitions
|
||||
//-----------------------------------------------------------------------------
|
||||
LLVFS* LLKeyframeMotion::sVFS = NULL;
|
||||
LLKeyframeDataCache::keyframe_data_map_t LLKeyframeDataCache::sKeyframeDataMap;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -515,7 +514,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;
|
||||
}
|
||||
|
||||
|
|
@ -559,13 +558,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;
|
||||
|
|
@ -2296,10 +2290,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;
|
||||
|
||||
|
|
@ -2331,7 +2324,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];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -106,7 +106,8 @@ BOOL LLApp::sDisableCrashlogger = FALSE;
|
|||
BOOL LLApp::sLogInSignal = FALSE;
|
||||
|
||||
// static
|
||||
LLApp::EAppStatus LLApp::sStatus = LLApp::APP_STATUS_STOPPED; // Keeps track of application status
|
||||
// Keeps track of application status
|
||||
LLScalarCond<LLApp::EAppStatus> LLApp::sStatus{LLApp::APP_STATUS_STOPPED};
|
||||
LLAppErrorHandler LLApp::sErrorHandler = NULL;
|
||||
BOOL LLApp::sErrorThreadRunning = FALSE;
|
||||
|
||||
|
|
@ -452,7 +453,8 @@ static std::map<LLApp::EAppStatus, const char*> statusDesc
|
|||
// static
|
||||
void LLApp::setStatus(EAppStatus status)
|
||||
{
|
||||
sStatus = status;
|
||||
// notify everyone waiting on sStatus any time its value changes
|
||||
sStatus.set_all(status);
|
||||
|
||||
// This can also happen very late in the application lifecycle -- don't
|
||||
// resurrect a deleted LLSingleton
|
||||
|
|
@ -514,28 +516,28 @@ void LLApp::setStopped()
|
|||
// static
|
||||
bool LLApp::isStopped()
|
||||
{
|
||||
return (APP_STATUS_STOPPED == sStatus);
|
||||
return (APP_STATUS_STOPPED == sStatus.get());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
bool LLApp::isRunning()
|
||||
{
|
||||
return (APP_STATUS_RUNNING == sStatus);
|
||||
return (APP_STATUS_RUNNING == sStatus.get());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
bool LLApp::isError()
|
||||
{
|
||||
return (APP_STATUS_ERROR == sStatus);
|
||||
return (APP_STATUS_ERROR == sStatus.get());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
bool LLApp::isQuitting()
|
||||
{
|
||||
return (APP_STATUS_QUITTING == sStatus);
|
||||
return (APP_STATUS_QUITTING == sStatus.get());
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
|||
|
|
@ -28,9 +28,11 @@
|
|||
#define LL_LLAPP_H
|
||||
|
||||
#include <map>
|
||||
#include "llcond.h"
|
||||
#include "llrun.h"
|
||||
#include "llsd.h"
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
// Forward declarations
|
||||
class LLErrorThread;
|
||||
class LLLiveFile;
|
||||
|
|
@ -207,6 +209,36 @@ public:
|
|||
static bool isExiting(); // Either quitting or error (app is exiting, cleanly or not)
|
||||
static int getPid();
|
||||
|
||||
//
|
||||
// Sleep for specified time while still running
|
||||
//
|
||||
// For use by a coroutine or thread that performs some maintenance on a
|
||||
// periodic basis. (See also LLEventTimer.) This method supports the
|
||||
// pattern of an "infinite" loop that sleeps for some time, performs some
|
||||
// action, then sleeps again. The trouble with literally sleeping a worker
|
||||
// thread is that it could potentially sleep right through attempted
|
||||
// application shutdown. This method avoids that by returning false as
|
||||
// soon as the application status changes away from APP_STATUS_RUNNING
|
||||
// (isRunning()).
|
||||
//
|
||||
// sleep() returns true if it sleeps undisturbed for the entire specified
|
||||
// duration. The idea is that you can code 'while sleep(duration) ...',
|
||||
// which will break the loop once shutdown begins.
|
||||
//
|
||||
// Since any time-based LLUnit should be implicitly convertible to
|
||||
// F32Milliseconds, accept that specific type as a proxy.
|
||||
static bool sleep(F32Milliseconds duration);
|
||||
// Allow any duration defined in terms of <chrono>.
|
||||
// One can imagine a wonderfully general bidirectional conversion system
|
||||
// between any type derived from LLUnits::LLUnit<T, LLUnits::Seconds> and
|
||||
// any std::chrono::duration -- but that doesn't yet exist.
|
||||
template <typename Rep, typename Period>
|
||||
bool sleep(const std::chrono::duration<Rep, Period>& duration)
|
||||
{
|
||||
// wait_for_unequal() has the opposite bool return convention
|
||||
return ! sStatus.wait_for_unequal(duration, APP_STATUS_RUNNING);
|
||||
}
|
||||
|
||||
/** @name Error handling methods */
|
||||
//@{
|
||||
/**
|
||||
|
|
@ -236,8 +268,8 @@ public:
|
|||
|
||||
// Return the Google Breakpad minidump filename after a crash.
|
||||
char *getMiniDumpFilename() { return mMinidumpPath; }
|
||||
std::string* getStaticDebugFile() { return &mStaticDebugFileName; }
|
||||
std::string* getDynamicDebugFile() { return &mDynamicDebugFileName; }
|
||||
std::string* getStaticDebugFile() { return &mStaticDebugFileName; }
|
||||
std::string* getDynamicDebugFile() { return &mDynamicDebugFileName; }
|
||||
|
||||
// Write out a Google Breakpad minidump file.
|
||||
void writeMiniDump();
|
||||
|
|
@ -265,7 +297,7 @@ public:
|
|||
protected:
|
||||
|
||||
static void setStatus(EAppStatus status); // Use this to change the application status.
|
||||
static EAppStatus sStatus; // Reflects current application status
|
||||
static LLScalarCond<EAppStatus> sStatus; // Reflects current application status
|
||||
static BOOL sErrorThreadRunning; // Set while the error thread is running
|
||||
static BOOL sDisableCrashlogger; // Let the OS handle crashes for us.
|
||||
std::wstring mCrashReportPipeStr; //Name of pipe to use for crash reporting.
|
||||
|
|
|
|||
|
|
@ -194,23 +194,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)
|
||||
{
|
||||
|
|
@ -229,11 +270,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)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#ifndef LL_LLTHREAD_H
|
||||
#define LL_LLTHREAD_H
|
||||
|
||||
#include "llapp.h"
|
||||
#include "llapr.h"
|
||||
#include "boost/intrusive_ptr.hpp"
|
||||
#include "llrefcount.h"
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include <iphlpapi.h>
|
||||
#endif
|
||||
|
||||
#include "llapp.h"
|
||||
#include "lldefs.h"
|
||||
#include "llerror.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file llpidlock.h
|
||||
* @file llcrashlock.h
|
||||
* @brief Maintainence of disk locking files for crash reporting
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
|
|
|
|||
|
|
@ -596,7 +596,7 @@ bool LLCrashLogger::init()
|
|||
#if LL_WINDOWS
|
||||
Sleep(1000);
|
||||
#else
|
||||
sleep(1);
|
||||
::sleep(1);
|
||||
#endif
|
||||
locked = mKeyMaster.checkMaster();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}")
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
#include <unistd.h>
|
||||
#include <glob.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include "llvfs_objc.h"
|
||||
#include "lldir_utils_objc.h"
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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()
|
||||
|
|
@ -0,0 +1,410 @@
|
|||
/**
|
||||
* @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 "llapp.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 uintmax_t 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);
|
||||
}
|
||||
|
||||
// WARNING: purge() is called by LLPurgeDiskCacheThread. As such it must
|
||||
// NOT touch any LLDiskCache data without introducing and locking a mutex!
|
||||
|
||||
// Interaction through the filesystem itself should be safe. Let’s say thread
|
||||
// A is accessing the cache file for reading/writing and thread B is trimming
|
||||
// the cache. Let’s also assume using llifstream to open a file and
|
||||
// boost::filesystem::remove are not atomic (which will be pretty much the
|
||||
// case).
|
||||
|
||||
// Now, A is trying to open the file using llifstream ctor. It does some
|
||||
// checks if the file exists and whatever else it might be doing, but has not
|
||||
// issued the call to the OS to actually open the file yet. Now B tries to
|
||||
// delete the file: If the file has been already marked as in use by the OS,
|
||||
// deleting the file will fail and B will continue with the next file. A can
|
||||
// safely continue opening the file. If the file has not yet been marked as in
|
||||
// use, B will delete the file. Now A actually wants to open it, operation
|
||||
// will fail, subsequent check via llifstream.is_open will fail, asset will
|
||||
// have to be re-requested. (Assuming here the viewer will actually handle
|
||||
// this situation properly, that can also happen if there is a file containing
|
||||
// garbage.)
|
||||
|
||||
// Other situation: B is trimming the cache and A wants to read a file that is
|
||||
// about to get deleted. boost::filesystem::remove does whatever it is doing
|
||||
// before actually deleting the file. If A opens the file before the file is
|
||||
// actually gone, the OS call from B to delete the file will fail since the OS
|
||||
// will prevent this. B continues with the next file. If the file is already
|
||||
// gone before A finally gets to open it, this operation will fail and the
|
||||
// asset will have to be re-requested.
|
||||
void LLDiskCache::purge()
|
||||
{
|
||||
if (mEnableCacheDebugInfo)
|
||||
{
|
||||
LL_INFOS() << "Total dir size before purge is " << dirFileSize(mCacheDir) << LL_ENDL;
|
||||
}
|
||||
|
||||
boost::system::error_code ec;
|
||||
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, ec) && !ec.failed())
|
||||
{
|
||||
for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
|
||||
{
|
||||
if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
|
||||
{
|
||||
if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
{
|
||||
uintmax_t file_size = boost::filesystem::file_size(entry, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const std::string file_path = entry.path().string();
|
||||
const std::time_t file_time = boost::filesystem::last_write_time(entry, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
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, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
LL_WARNS() << "Failed to delete cache file " << entry.second.second << ": " << ec.message() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
boost::system::error_code ec;
|
||||
#if LL_WINDOWS
|
||||
// file last write time
|
||||
const std::time_t last_write_time = boost::filesystem::last_write_time(utf8str_to_utf16str(file_path), ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
LL_WARNS() << "Failed to read last write time for cache file " << file_path << ": " << ec.message() << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
// 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, ec);
|
||||
}
|
||||
#else
|
||||
// file last write time
|
||||
const std::time_t last_write_time = boost::filesystem::last_write_time(file_path, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
LL_WARNS() << "Failed to read last write time for cache file " << file_path << ": " << ec.message() << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
// 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, ec);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ec.failed())
|
||||
{
|
||||
LL_WARNS() << "Failed to update last write time for cache file " << file_path << ": " << ec.message() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
boost::system::error_code ec;
|
||||
#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, ec) && !ec.failed())
|
||||
{
|
||||
for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
|
||||
{
|
||||
if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
|
||||
{
|
||||
if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
{
|
||||
boost::filesystem::remove(entry, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
LL_WARNS() << "Failed to delete cache file " << entry << ": " << ec.message() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
boost::system::error_code ec;
|
||||
#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, ec) && !ec.failed())
|
||||
{
|
||||
for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(dir_path, ec), {}))
|
||||
{
|
||||
if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
|
||||
{
|
||||
if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
{
|
||||
uintmax_t file_size = boost::filesystem::file_size(entry, ec);
|
||||
if (!ec.failed())
|
||||
{
|
||||
total_file_size += file_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return total_file_size;
|
||||
}
|
||||
|
||||
LLPurgeDiskCacheThread::LLPurgeDiskCacheThread() :
|
||||
LLThread("PurgeDiskCacheThread", nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void LLPurgeDiskCacheThread::run()
|
||||
{
|
||||
constexpr std::chrono::seconds CHECK_INTERVAL{60};
|
||||
|
||||
while (LLApp::instance()->sleep(CHECK_INTERVAL))
|
||||
{
|
||||
LLDiskCache::instance().purge();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
/**
|
||||
* @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 uintmax_t 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.
|
||||
*
|
||||
* WARNING: purge() is called by LLPurgeDiskCacheThread. As such it must
|
||||
* NOT touch any LLDiskCache data without introducing and locking a mutex!
|
||||
*
|
||||
* Purging the disk cache involves nontrivial work on the viewer's
|
||||
* filesystem. If called on the main thread, this causes a noticeable
|
||||
* freeze.
|
||||
*/
|
||||
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;
|
||||
};
|
||||
|
||||
class LLPurgeDiskCacheThread : public LLThread
|
||||
{
|
||||
public:
|
||||
LLPurgeDiskCacheThread();
|
||||
|
||||
protected:
|
||||
void run() override;
|
||||
};
|
||||
#endif // _LLDISKCACHE
|
||||
|
|
@ -0,0 +1,326 @@
|
|||
/**
|
||||
* @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;
|
||||
|
||||
// This block of code was originally called in the read() method but after comments here:
|
||||
// https://bitbucket.org/lindenlab/viewer/commits/e28c1b46e9944f0215a13cab8ee7dded88d7fc90#comment-10537114
|
||||
// we decided to follow Henri's suggestion and move the code to update the last access time here.
|
||||
if (mode == LLFileSystem::READ)
|
||||
{
|
||||
// build the filename (TODO: we do this in a few places - perhaps we should factor into a single function)
|
||||
std::string id;
|
||||
mFileID.toString(id);
|
||||
const std::string extra_info = "";
|
||||
const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id, mFileType, extra_info);
|
||||
|
||||
// update the last access time for the file if it exists - 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
|
||||
bool exists = gDirUtilp->fileExists(filename);
|
||||
if (exists)
|
||||
{
|
||||
LLDiskCache::getInstance()->updateFileAccessTime(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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, int suppress_error /*= 0*/)
|
||||
{
|
||||
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(), suppress_error);
|
||||
|
||||
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, ENOENT);
|
||||
|
||||
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 = FALSE;
|
||||
|
||||
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 = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
mPosition = ofs.tellp(); // <FS:Ansariel> Fix asset caching
|
||||
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
// <FS:Ansariel> Fix asset caching
|
||||
else if (mMode == READ_WRITE)
|
||||
{
|
||||
// Don't truncate if file already exists
|
||||
llofstream ofs(filename, std::ios::in | std::ios::binary);
|
||||
if (ofs)
|
||||
{
|
||||
ofs.seekp(mPosition, std::ios::beg);
|
||||
ofs.write((const char*)buffer, bytes);
|
||||
mPosition += bytes;
|
||||
success = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// File doesn't exist - open in write mode
|
||||
ofs.open(filename, std::ios::binary);
|
||||
if (ofs.is_open())
|
||||
{
|
||||
ofs.write((const char*)buffer, bytes);
|
||||
mPosition += bytes;
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
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;
|
||||
}
|
||||
|
|
@ -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, int suppress_error = 0);
|
||||
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
|
||||
|
|
@ -6,7 +6,7 @@ include(00-Common)
|
|||
include(LLCommon)
|
||||
include(LLImage)
|
||||
include(LLMath)
|
||||
include(LLVFS)
|
||||
include(LLFileSystem)
|
||||
include(LLKDU)
|
||||
include(LLImageJ2COJ)
|
||||
include(ZLIB)
|
||||
|
|
@ -18,7 +18,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}
|
||||
)
|
||||
|
|
@ -69,7 +69,7 @@ else (USE_KDU)
|
|||
endif (USE_KDU)
|
||||
|
||||
target_link_libraries(llimage
|
||||
${LLVFS_LIBRARIES}
|
||||
${LLFILESYSTEM_LIBRARIES}
|
||||
${LLMATH_LIBRARIES}
|
||||
${LLCOMMON_LIBRARIES}
|
||||
${JPEG_LIBRARIES}
|
||||
|
|
|
|||
|
|
@ -2224,20 +2224,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);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ include(LLCommon)
|
|||
include(LLCoreHttp)
|
||||
include(LLMath)
|
||||
include(LLMessage)
|
||||
include(LLVFS)
|
||||
include(LLFileSystem)
|
||||
include(LLXML)
|
||||
|
||||
include_directories(
|
||||
|
|
@ -81,7 +81,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)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ include(LLCommon)
|
|||
include(LLCoreHttp)
|
||||
include(LLMath)
|
||||
include(LLMessage)
|
||||
include(LLVFS)
|
||||
include(LLFileSystem)
|
||||
include(LLAddBuildTest)
|
||||
include(Python)
|
||||
include(Tut)
|
||||
|
|
@ -23,7 +23,7 @@ include_directories(
|
|||
${LLCOREHTTP_INCLUDE_DIRS}
|
||||
${LLMATH_INCLUDE_DIRS}
|
||||
${LLMESSAGE_INCLUDE_DIRS}
|
||||
${LLVFS_INCLUDE_DIRS}
|
||||
${LLFILESYSTEM_INCLUDE_DIRS}
|
||||
${JSONCPP_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
|
|
@ -209,7 +209,7 @@ target_link_libraries(
|
|||
llmessage
|
||||
${CURL_LIBRARIES}
|
||||
${LLCOMMON_LIBRARIES}
|
||||
${LLVFS_LIBRARIES}
|
||||
${LLFILESYSTEM_LIBRARIES}
|
||||
${LLMATH_LIBRARIES}
|
||||
${JSONCPP_LIBRARIES}
|
||||
${OPENSSL_LIBRARIES}
|
||||
|
|
@ -227,7 +227,7 @@ target_link_libraries(
|
|||
llmessage
|
||||
${CURL_LIBRARIES}
|
||||
${LLCOMMON_LIBRARIES}
|
||||
${LLVFS_LIBRARIES}
|
||||
${LLFILESYSTEM_LIBRARIES}
|
||||
${LLMATH_LIBRARIES}
|
||||
${JSONCPP_LIBRARIES}
|
||||
${OPENSSL_LIBRARIES}
|
||||
|
|
@ -257,7 +257,7 @@ if (LL_TESTS)
|
|||
if (LINUX)
|
||||
set(test_libs
|
||||
${WINDOWS_LIBRARIES}
|
||||
${LLVFS_LIBRARIES}
|
||||
${LLFILESYSTEM_LIBRARIES}
|
||||
${LLMATH_LIBRARIES}
|
||||
${CURL_LIBRARIES}
|
||||
${NGHTTP2_LIBRARIES}
|
||||
|
|
@ -273,7 +273,7 @@ if (LINUX)
|
|||
else (LINUX)
|
||||
set(test_libs
|
||||
${WINDOWS_LIBRARIES}
|
||||
${LLVFS_LIBRARIES}
|
||||
${LLFILESYSTEM_LIBRARIES}
|
||||
${LLMATH_LIBRARIES}
|
||||
${CURL_LIBRARIES}
|
||||
${NGHTTP2_LIBRARIES}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#include "llsdserialize.h"
|
||||
#include "reader.h" // JSON
|
||||
#include "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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include "apr_poll.h"
|
||||
|
||||
// linden library headers
|
||||
#include "llapp.h"
|
||||
#include "indra_constants.h"
|
||||
#include "lldir.h"
|
||||
#include "llerror.h"
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llapp.h"
|
||||
#include "llpluginprocessparent.h"
|
||||
#include "llpluginmessagepipe.h"
|
||||
#include "llpluginmessageclasses.h"
|
||||
|
|
|
|||
|
|
@ -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})
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
@ -285,7 +285,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}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -1,183 +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;
|
||||
};
|
||||
|
||||
extern LLVFS *gVFS;
|
||||
|
||||
#endif
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
|
@ -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
|
||||
|
|
@ -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}
|
||||
${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.
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ include(LLPlugin)
|
|||
include(LLPrimitive)
|
||||
include(LLRender)
|
||||
include(LLUI)
|
||||
include(LLVFS)
|
||||
include(LLFileSystem)
|
||||
include(LLWindow)
|
||||
include(LLXML)
|
||||
include(NDOF)
|
||||
|
|
@ -85,7 +85,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}
|
||||
|
|
@ -2038,7 +2038,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
|
|||
${LLRENDER_LIBRARIES}
|
||||
${FREETYPE_LIBRARIES}
|
||||
${LLUI_LIBRARIES}
|
||||
${LLVFS_LIBRARIES}
|
||||
${LLFILESYSTEM_LIBRARIES}
|
||||
${LLWINDOW_LIBRARIES}
|
||||
${LLXML_LIBRARIES}
|
||||
${LLMATH_LIBRARIES}
|
||||
|
|
@ -2461,7 +2461,7 @@ if (LL_TESTS)
|
|||
set(test_libs
|
||||
${LLMESSAGE_LIBRARIES}
|
||||
${WINDOWS_LIBRARIES}
|
||||
${LLVFS_LIBRARIES}
|
||||
${LLFILESYSTEM_LIBRARIES}
|
||||
${LLMATH_LIBRARIES}
|
||||
${LLCOMMON_LIBRARIES}
|
||||
${GOOGLEMOCK_LIBRARIES}
|
||||
|
|
@ -2476,7 +2476,7 @@ if (LL_TESTS)
|
|||
|
||||
set(test_libs
|
||||
${WINDOWS_LIBRARIES}
|
||||
${LLVFS_LIBRARIES}
|
||||
${LLFILESYSTEM_LIBRARIES}
|
||||
${LLMATH_LIBRARIES}
|
||||
${LLCOMMON_LIBRARIES}
|
||||
${LLMESSAGE_LIBRARIES}
|
||||
|
|
|
|||
|
|
@ -1362,6 +1362,39 @@
|
|||
<key>Value</key>
|
||||
<integer>23</integer>
|
||||
</map>
|
||||
<key>EnableDiskCacheDebugInfo</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>
|
||||
|
|
@ -2848,17 +2881,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>
|
||||
|
|
@ -3651,17 +3673,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>
|
||||
</map>
|
||||
<key>DynamicCameraStrength</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -14307,28 +14318,6 @@
|
|||
<key>Value</key>
|
||||
<string/>
|
||||
</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>
|
||||
</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>
|
||||
</map>
|
||||
<key>VelocityInterpolate</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -16682,6 +16671,28 @@
|
|||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>CefVerboseLog</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable/disable CEF verbose loggingk</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>ResetUIScaleOnFirstRun</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Resets the UI scale factor on first run due to changed display scaling behavior</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>360CaptureUseInterestListCap</key>
|
||||
<map>
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -101,6 +101,7 @@
|
|||
#include "lllogininstance.h"
|
||||
#include "llprogressview.h"
|
||||
#include "llvocache.h"
|
||||
#include "lldiskcache.h"
|
||||
#include "llvopartgroup.h"
|
||||
#include "llweb.h"
|
||||
#include "llfloatertexturefetchdebugger.h"
|
||||
|
|
@ -118,8 +119,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"
|
||||
|
|
@ -343,9 +342,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
|
||||
|
||||
|
|
@ -434,12 +430,6 @@ void init_default_trans_args()
|
|||
default_trans_args.insert("create_account_url");
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// File scope definitons
|
||||
const char *VFS_DATA_FILE_BASE = "data.db2.x.";
|
||||
const char *VFS_INDEX_FILE_BASE = "index.db2.x.";
|
||||
|
||||
|
||||
struct SettingsFile : public LLInitParam::Block<SettingsFile>
|
||||
{
|
||||
Mandatory<std::string> name;
|
||||
|
|
@ -667,6 +657,7 @@ LLAppViewer* LLAppViewer::sInstance = NULL;
|
|||
LLTextureCache* LLAppViewer::sTextureCache = NULL;
|
||||
LLImageDecodeThread* LLAppViewer::sImageDecodeThread = NULL;
|
||||
LLTextureFetch* LLAppViewer::sTextureFetch = NULL;
|
||||
LLPurgeDiskCacheThread* LLAppViewer::sPurgeDiskCacheThread = NULL;
|
||||
|
||||
std::string getRuntime()
|
||||
{
|
||||
|
|
@ -963,10 +954,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;
|
||||
|
|
@ -1380,7 +1367,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");
|
||||
|
|
@ -1618,10 +1604,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);
|
||||
|
|
@ -1629,7 +1611,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 ;
|
||||
|
|
@ -1646,7 +1628,6 @@ bool LLAppViewer::doFrame()
|
|||
}
|
||||
if(!total_io_pending) //pause file threads if nothing to process.
|
||||
{
|
||||
LLVFSThread::sLocal->pause();
|
||||
LLLFSThread::sLocal->pause();
|
||||
}
|
||||
|
||||
|
|
@ -1711,12 +1692,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;
|
||||
|
|
@ -1808,7 +1788,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
|
||||
|
|
@ -1875,8 +1855,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
|
||||
|
|
@ -1960,15 +1940,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
|
||||
|
|
@ -2057,7 +2028,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)
|
||||
|
|
@ -2085,6 +2055,7 @@ bool LLAppViewer::cleanup()
|
|||
sTextureFetch->shutdown();
|
||||
sTextureCache->shutdown();
|
||||
sImageDecodeThread->shutdown();
|
||||
sPurgeDiskCacheThread->shutdown();
|
||||
|
||||
sTextureFetch->shutDownTextureCacheThread() ;
|
||||
sTextureFetch->shutDownImageDecodeThread() ;
|
||||
|
|
@ -2107,6 +2078,8 @@ bool LLAppViewer::cleanup()
|
|||
sImageDecodeThread = NULL;
|
||||
delete mFastTimerLogThread;
|
||||
mFastTimerLogThread = NULL;
|
||||
delete sPurgeDiskCacheThread;
|
||||
sPurgeDiskCacheThread = NULL;
|
||||
|
||||
if (LLFastTimerView::sAnalyzePerformance)
|
||||
{
|
||||
|
|
@ -2132,28 +2105,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();
|
||||
|
||||
|
|
@ -2213,7 +2169,6 @@ bool LLAppViewer::initThreads()
|
|||
|
||||
LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
|
||||
|
||||
LLVFSThread::initClass(enable_threads && false);
|
||||
LLLFSThread::initClass(enable_threads && false);
|
||||
|
||||
// Image decoding
|
||||
|
|
@ -2223,6 +2178,7 @@ bool LLAppViewer::initThreads()
|
|||
sImageDecodeThread,
|
||||
enable_threads && true,
|
||||
app_metrics_qa_mode);
|
||||
LLAppViewer::sPurgeDiskCacheThread = new LLPurgeDiskCacheThread();
|
||||
|
||||
if (LLTrace::BlockTimer::sLog || LLTrace::BlockTimer::sMetricLog)
|
||||
{
|
||||
|
|
@ -3240,10 +3196,6 @@ LLSD LLAppViewer::getViewerInfo() const
|
|||
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);
|
||||
|
||||
#if LL_DARWIN
|
||||
info["HIDPI"] = gHiDPISupport;
|
||||
#endif
|
||||
|
|
@ -3335,6 +3287,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();
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
|
@ -4013,7 +3968,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
|
||||
|
|
@ -4202,44 +4157,14 @@ 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()
|
||||
{
|
||||
//viewer texture cache version, change if the texture cache format changes.
|
||||
const U32 TEXTURE_CACHE_VERSION = 8;
|
||||
// Viewer texture cache version, change if the texture cache format changes.
|
||||
// 2021-03-10 Bumping up by one to help obviate texture cache issues with
|
||||
// Simple Cache Viewer - see SL-14985 for more information
|
||||
//const U32 TEXTURE_CACHE_VERSION = 8;
|
||||
const U32 TEXTURE_CACHE_VERSION = 9;
|
||||
|
||||
return TEXTURE_CACHE_VERSION ;
|
||||
}
|
||||
|
|
@ -4261,6 +4186,17 @@ 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 uintmax_t disk_cache_bytes = disk_cache_mb * 1024 * 1024;
|
||||
const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo");
|
||||
|
||||
bool texture_cache_mismatch = false;
|
||||
if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion())
|
||||
{
|
||||
|
|
@ -4295,6 +4231,7 @@ bool LLAppViewer::initCache()
|
|||
LL_INFOS("AppCache") << "Cache location changed, cache needs purging" << LL_ENDL;
|
||||
gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"));
|
||||
purgeCache(); // purge old cache
|
||||
gDirUtilp->deleteDirAndContents(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name));
|
||||
gSavedSettings.setString("CacheLocation", new_cache_location);
|
||||
gSavedSettings.setString("CacheLocationTopFolder", gDirUtilp->getBaseFileName(new_cache_location));
|
||||
}
|
||||
|
|
@ -4307,11 +4244,26 @@ bool LLAppViewer::initCache()
|
|||
gSavedSettings.setString("CacheLocationTopFolder", "");
|
||||
}
|
||||
|
||||
if (mPurgeCache && !read_only)
|
||||
const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name);
|
||||
LLDiskCache::initParamSingleton(cache_dir, disk_cache_bytes, enable_cache_debug_info);
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
LLAppViewer::getPurgeDiskCacheThread()->start();
|
||||
|
||||
LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache"));
|
||||
|
||||
|
|
@ -4320,172 +4272,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)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/**
|
||||
* @mainpage
|
||||
* @mainpage
|
||||
*
|
||||
* This is the sources for the Second Life Viewer;
|
||||
|
|
@ -57,6 +58,7 @@ class LLImageDecodeThread;
|
|||
class LLTextureFetch;
|
||||
class LLWatchdogTimeout;
|
||||
class LLViewerJoystick;
|
||||
class LLPurgeDiskCacheThread;
|
||||
class LLViewerRegion;
|
||||
|
||||
extern LLTrace::BlockTimerStatHandle FTM_FRAME;
|
||||
|
|
@ -83,7 +85,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.
|
||||
|
|
@ -116,6 +118,7 @@ public:
|
|||
static LLTextureCache* getTextureCache() { return sTextureCache; }
|
||||
static LLImageDecodeThread* getImageDecodeThread() { return sImageDecodeThread; }
|
||||
static LLTextureFetch* getTextureFetch() { return sTextureFetch; }
|
||||
static LLPurgeDiskCacheThread* getPurgeDiskCacheThread() { return sPurgeDiskCacheThread; }
|
||||
|
||||
static U32 getTextureCacheVersion() ;
|
||||
static U32 getObjectCacheVersion() ;
|
||||
|
|
@ -284,6 +287,7 @@ private:
|
|||
static LLTextureCache* sTextureCache;
|
||||
static LLImageDecodeThread* sImageDecodeThread;
|
||||
static LLTextureFetch* sTextureFetch;
|
||||
static LLPurgeDiskCacheThread* sPurgeDiskCacheThread;
|
||||
|
||||
S32 mNumSessions;
|
||||
|
||||
|
|
@ -382,12 +386,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;
|
||||
|
||||
|
|
|
|||
|
|
@ -504,7 +504,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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
@ -116,7 +116,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
|
||||
{
|
||||
|
|
@ -134,8 +134,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));
|
||||
|
|
@ -283,11 +283,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());
|
||||
|
|
|
|||
|
|
@ -135,7 +135,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);
|
||||
|
|
|
|||
|
|
@ -136,7 +136,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.
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
@ -202,7 +201,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);
|
||||
|
||||
|
|
@ -210,7 +211,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);
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
@ -997,10 +997,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();
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
#include "llspinctrl.h"
|
||||
#include "lltabcontainer.h"
|
||||
#include "lltrans.h"
|
||||
#include "llfilesystem.h"
|
||||
#include "llcallbacklist.h"
|
||||
#include "llviewertexteditor.h"
|
||||
#include "llviewernetwork.h"
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ protected:
|
|||
void onBtnOK(const LLSD& userdata);
|
||||
void onBtnCancel(const LLSD& userdata);
|
||||
|
||||
void onClickClearCache(); // Clear viewer texture cache, vfs, and VO cache on next startup
|
||||
void onClickClearCache(); // Clear viewer texture cache, file cache on next startup
|
||||
void onClickBrowserClearCache(); // Clear web history and caches as well as viewer caches above
|
||||
void onLanguageChange();
|
||||
void onNotificationsChange(const std::string& OptionName);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
#include "llglheaders.h"
|
||||
#include "llregionflags.h"
|
||||
#include "llstl.h"
|
||||
#include "llvfile.h"
|
||||
#include "llfilesystem.h"
|
||||
#include "llxfermanager.h"
|
||||
#include "indra_constants.h"
|
||||
#include "message.h"
|
||||
|
|
@ -2252,10 +2252,9 @@ void LLPanelEstateCovenant::loadInvItem(LLInventoryItem *itemp)
|
|||
}
|
||||
|
||||
// static
|
||||
void LLPanelEstateCovenant::onLoadComplete(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status)
|
||||
void LLPanelEstateCovenant::onLoadComplete(const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LL_INFOS() << "LLPanelEstateCovenant::onLoadComplete()" << LL_ENDL;
|
||||
LLPanelEstateCovenant* panelp = (LLPanelEstateCovenant*)user_data;
|
||||
|
|
@ -2263,7 +2262,7 @@ void LLPanelEstateCovenant::onLoadComplete(LLVFS *vfs,
|
|||
{
|
||||
if(0 == status)
|
||||
{
|
||||
LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
|
||||
LLFileSystem file(asset_uuid, type, LLFileSystem::READ);
|
||||
|
||||
S32 file_length = file.getSize();
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ class LLRadioGroup;
|
|||
class LLSliderCtrl;
|
||||
class LLSpinCtrl;
|
||||
class LLTextBox;
|
||||
class LLVFS;
|
||||
|
||||
class LLPanelRegionGeneralInfo;
|
||||
class LLPanelRegionDebugInfo;
|
||||
|
|
@ -357,8 +356,7 @@ public:
|
|||
static bool confirmResetCovenantCallback(const LLSD& notification, const LLSD& response);
|
||||
void sendChangeCovenantID(const LLUUID &asset_id);
|
||||
void loadInvItem(LLInventoryItem *itemp);
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -44,8 +44,7 @@
|
|||
#include "llnotificationsutil.h"
|
||||
#include "llstring.h"
|
||||
#include "llsys.h"
|
||||
#include "llvfile.h"
|
||||
#include "llvfs.h"
|
||||
#include "llfilesystem.h"
|
||||
#include "mean_collision_data.h"
|
||||
#include "message.h"
|
||||
#include "v3math.h"
|
||||
|
|
@ -896,12 +895,9 @@ void LLFloaterReporter::takeScreenshot(bool use_prev_screenshot)
|
|||
mResourceDatap->mAssetInfo.setName("screenshot_name");
|
||||
mResourceDatap->mAssetInfo.setDescription("screenshot_descr");
|
||||
|
||||
// store in VFS
|
||||
LLVFile::writeFile(upload_data->getData(),
|
||||
upload_data->getDataSize(),
|
||||
gVFS,
|
||||
mResourceDatap->mAssetInfo.mUuid,
|
||||
mResourceDatap->mAssetInfo.mType);
|
||||
// store in cache
|
||||
LLFileSystem j2c_file(mResourceDatap->mAssetInfo.mUuid, mResourceDatap->mAssetInfo.mType, LLFileSystem::WRITE);
|
||||
j2c_file.write(upload_data->getData(), upload_data->getDataSize());
|
||||
|
||||
// store in the image list so it doesn't try to fetch from the server
|
||||
LLPointer<LLViewerFetchedTexture> image_in_list =
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
#include "lltextbox.h"
|
||||
#include "llui.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llvfile.h"
|
||||
#include "llfilesystem.h"
|
||||
#include "message.h"
|
||||
#include "llstartup.h" // login_alert_done
|
||||
#include "llcorehttputil.h"
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@
|
|||
|
||||
class LLButton;
|
||||
class LLRadioGroup;
|
||||
class LLVFS;
|
||||
class LLTextEditor;
|
||||
class LLUUID;
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue