DRTVWR-546 merge up to 6.5.2
commit
cf35d27dfb
|
|
@ -57,6 +57,7 @@ indra/newview/search_history.txt
|
||||||
indra/newview/teleport_history.txt
|
indra/newview/teleport_history.txt
|
||||||
indra/newview/typed_locations.txt
|
indra/newview/typed_locations.txt
|
||||||
indra/newview/vivox-runtime
|
indra/newview/vivox-runtime
|
||||||
|
indra/newview/skins/default/html/common/equirectangular/js
|
||||||
indra/server-linux-*
|
indra/server-linux-*
|
||||||
indra/temp
|
indra/temp
|
||||||
indra/test/linden_file.dat
|
indra/test/linden_file.dat
|
||||||
|
|
|
||||||
166
autobuild.xml
166
autobuild.xml
|
|
@ -367,6 +367,58 @@
|
||||||
<key>version</key>
|
<key>version</key>
|
||||||
<string>2.3.557064</string>
|
<string>2.3.557064</string>
|
||||||
</map>
|
</map>
|
||||||
|
<key>cubemaptoequirectangular</key>
|
||||||
|
<map>
|
||||||
|
<key>copyright</key>
|
||||||
|
<string>Copyright (c) 2017 Jaume Sanchez Elias, http://www.clicktorelease.com</string>
|
||||||
|
<key>license</key>
|
||||||
|
<string>MIT</string>
|
||||||
|
<key>license_file</key>
|
||||||
|
<string>LICENSES/CUBEMAPTOEQUIRECTANGULAR_LICENSE.txt</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>cubemaptoequirectangular</string>
|
||||||
|
<key>platforms</key>
|
||||||
|
<map>
|
||||||
|
<key>darwin64</key>
|
||||||
|
<map>
|
||||||
|
<key>archive</key>
|
||||||
|
<map>
|
||||||
|
<key>hash</key>
|
||||||
|
<string>7e4622b497bc465b01ff6d3e7e0b4214</string>
|
||||||
|
<key>url</key>
|
||||||
|
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89303/815402/cubemaptoequirectangular-1.1.0-darwin64-564841.tar.bz2</string>
|
||||||
|
</map>
|
||||||
|
<key>name</key>
|
||||||
|
<string>darwin64</string>
|
||||||
|
</map>
|
||||||
|
<key>windows</key>
|
||||||
|
<map>
|
||||||
|
<key>archive</key>
|
||||||
|
<map>
|
||||||
|
<key>hash</key>
|
||||||
|
<string>b5ea7097ae10037024b0c2b3df9812b5</string>
|
||||||
|
<key>url</key>
|
||||||
|
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89307/815434/cubemaptoequirectangular-1.1.0-windows-564841.tar.bz2</string>
|
||||||
|
</map>
|
||||||
|
<key>name</key>
|
||||||
|
<string>windows</string>
|
||||||
|
</map>
|
||||||
|
<key>windows64</key>
|
||||||
|
<map>
|
||||||
|
<key>archive</key>
|
||||||
|
<map>
|
||||||
|
<key>hash</key>
|
||||||
|
<string>ac54672e0b38f52726f5c99047c913e4</string>
|
||||||
|
<key>url</key>
|
||||||
|
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89306/815431/cubemaptoequirectangular-1.1.0-windows64-564841.tar.bz2</string>
|
||||||
|
</map>
|
||||||
|
<key>name</key>
|
||||||
|
<string>windows64</string>
|
||||||
|
</map>
|
||||||
|
</map>
|
||||||
|
<key>version</key>
|
||||||
|
<string>1.1.0</string>
|
||||||
|
</map>
|
||||||
<key>curl</key>
|
<key>curl</key>
|
||||||
<map>
|
<map>
|
||||||
<key>copyright</key>
|
<key>copyright</key>
|
||||||
|
|
@ -1307,6 +1359,58 @@
|
||||||
<key>version</key>
|
<key>version</key>
|
||||||
<string>2012.1-2</string>
|
<string>2012.1-2</string>
|
||||||
</map>
|
</map>
|
||||||
|
<key>jpegencoderbasic</key>
|
||||||
|
<map>
|
||||||
|
<key>copyright</key>
|
||||||
|
<string>Andreas Ritter, www.bytestrom.eu, 11/2009</string>
|
||||||
|
<key>license</key>
|
||||||
|
<string>NONE</string>
|
||||||
|
<key>license_file</key>
|
||||||
|
<string>LICENSES/JPEG_ENCODER_BASIC_LICENSE.txt</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>jpegencoderbasic</string>
|
||||||
|
<key>platforms</key>
|
||||||
|
<map>
|
||||||
|
<key>darwin64</key>
|
||||||
|
<map>
|
||||||
|
<key>archive</key>
|
||||||
|
<map>
|
||||||
|
<key>hash</key>
|
||||||
|
<string>c3c9e60bdc12b35e0e3d6b67d5635f60</string>
|
||||||
|
<key>url</key>
|
||||||
|
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89304/815407/jpegencoderbasic-1.0-darwin64-564842.tar.bz2</string>
|
||||||
|
</map>
|
||||||
|
<key>name</key>
|
||||||
|
<string>darwin64</string>
|
||||||
|
</map>
|
||||||
|
<key>windows</key>
|
||||||
|
<map>
|
||||||
|
<key>archive</key>
|
||||||
|
<map>
|
||||||
|
<key>hash</key>
|
||||||
|
<string>0a376676dbb43fdd0c81ffdfbc5e6f81</string>
|
||||||
|
<key>url</key>
|
||||||
|
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89308/815432/jpegencoderbasic-1.0-windows-564842.tar.bz2</string>
|
||||||
|
</map>
|
||||||
|
<key>name</key>
|
||||||
|
<string>windows</string>
|
||||||
|
</map>
|
||||||
|
<key>windows64</key>
|
||||||
|
<map>
|
||||||
|
<key>archive</key>
|
||||||
|
<map>
|
||||||
|
<key>hash</key>
|
||||||
|
<string>e70898903475d8ac2e81ff33278fc987</string>
|
||||||
|
<key>url</key>
|
||||||
|
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89309/815433/jpegencoderbasic-1.0-windows64-564842.tar.bz2</string>
|
||||||
|
</map>
|
||||||
|
<key>name</key>
|
||||||
|
<string>windows64</string>
|
||||||
|
</map>
|
||||||
|
</map>
|
||||||
|
<key>version</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
</map>
|
||||||
<key>jpeglib</key>
|
<key>jpeglib</key>
|
||||||
<map>
|
<map>
|
||||||
<key>copyright</key>
|
<key>copyright</key>
|
||||||
|
|
@ -2939,6 +3043,58 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
||||||
<key>version</key>
|
<key>version</key>
|
||||||
<string>4.10.0000.32327.5fc3fe7c.558436</string>
|
<string>4.10.0000.32327.5fc3fe7c.558436</string>
|
||||||
</map>
|
</map>
|
||||||
|
<key>threejs</key>
|
||||||
|
<map>
|
||||||
|
<key>copyright</key>
|
||||||
|
<string>Copyright © 2010-2021 three.js authors</string>
|
||||||
|
<key>license</key>
|
||||||
|
<string>MIT</string>
|
||||||
|
<key>license_file</key>
|
||||||
|
<string>LICENSES/THREEJS_LICENSE.txt</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>threejs</string>
|
||||||
|
<key>platforms</key>
|
||||||
|
<map>
|
||||||
|
<key>darwin64</key>
|
||||||
|
<map>
|
||||||
|
<key>archive</key>
|
||||||
|
<map>
|
||||||
|
<key>hash</key>
|
||||||
|
<string>24440e8219e59d81423b68d3be381fef</string>
|
||||||
|
<key>url</key>
|
||||||
|
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89305/815412/threejs-0.132.2-darwin64-564843.tar.bz2</string>
|
||||||
|
</map>
|
||||||
|
<key>name</key>
|
||||||
|
<string>darwin64</string>
|
||||||
|
</map>
|
||||||
|
<key>windows</key>
|
||||||
|
<map>
|
||||||
|
<key>archive</key>
|
||||||
|
<map>
|
||||||
|
<key>hash</key>
|
||||||
|
<string>e1303fb9f2242a79aee5fd9f97726ace</string>
|
||||||
|
<key>url</key>
|
||||||
|
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89311/815452/threejs-0.132.2-windows-564843.tar.bz2</string>
|
||||||
|
</map>
|
||||||
|
<key>name</key>
|
||||||
|
<string>windows</string>
|
||||||
|
</map>
|
||||||
|
<key>windows64</key>
|
||||||
|
<map>
|
||||||
|
<key>archive</key>
|
||||||
|
<map>
|
||||||
|
<key>hash</key>
|
||||||
|
<string>46edf0f55417f8ef0d33a5c007bc3644</string>
|
||||||
|
<key>url</key>
|
||||||
|
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89310/815451/threejs-0.132.2-windows64-564843.tar.bz2</string>
|
||||||
|
</map>
|
||||||
|
<key>name</key>
|
||||||
|
<string>windows64</string>
|
||||||
|
</map>
|
||||||
|
</map>
|
||||||
|
<key>version</key>
|
||||||
|
<string>0.132.2</string>
|
||||||
|
</map>
|
||||||
<key>tracy</key>
|
<key>tracy</key>
|
||||||
<map>
|
<map>
|
||||||
<key>canonical_repo</key>
|
<key>canonical_repo</key>
|
||||||
|
|
@ -3142,9 +3298,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
||||||
<key>archive</key>
|
<key>archive</key>
|
||||||
<map>
|
<map>
|
||||||
<key>hash</key>
|
<key>hash</key>
|
||||||
<string>97fac6d88480445c856083ed20d78093</string>
|
<string>a3c8357a2f5a62cd7de43181b02553bc</string>
|
||||||
<key>url</key>
|
<key>url</key>
|
||||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/85206/790666/viewer_manager-2.0.562101-darwin64-562101.tar.bz2</string>
|
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/91396/829032/viewer_manager-2.0.566227-darwin64-566227.tar.bz2</string>
|
||||||
</map>
|
</map>
|
||||||
<key>name</key>
|
<key>name</key>
|
||||||
<string>darwin64</string>
|
<string>darwin64</string>
|
||||||
|
|
@ -3166,9 +3322,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
||||||
<key>archive</key>
|
<key>archive</key>
|
||||||
<map>
|
<map>
|
||||||
<key>hash</key>
|
<key>hash</key>
|
||||||
<string>3f6271ec0e2e2f0cc1067d4c4102bb4c</string>
|
<string>0654b449d9bdf3507664cf5caa67336f</string>
|
||||||
<key>url</key>
|
<key>url</key>
|
||||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/85208/790681/viewer_manager-2.0.562101-windows-562101.tar.bz2</string>
|
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/91397/829041/viewer_manager-2.0.566227-windows-566227.tar.bz2</string>
|
||||||
</map>
|
</map>
|
||||||
<key>name</key>
|
<key>name</key>
|
||||||
<string>windows</string>
|
<string>windows</string>
|
||||||
|
|
@ -3179,7 +3335,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
||||||
<key>source_type</key>
|
<key>source_type</key>
|
||||||
<string>hg</string>
|
<string>hg</string>
|
||||||
<key>version</key>
|
<key>version</key>
|
||||||
<string>2.0.562101</string>
|
<string>2.0.566227</string>
|
||||||
</map>
|
</map>
|
||||||
<key>vlc-bin</key>
|
<key>vlc-bin</key>
|
||||||
<map>
|
<map>
|
||||||
|
|
|
||||||
|
|
@ -226,8 +226,15 @@ Ansariel Hiller
|
||||||
SL-13364
|
SL-13364
|
||||||
SL-13858
|
SL-13858
|
||||||
SL-13697
|
SL-13697
|
||||||
|
SL-14939
|
||||||
|
SL-14940
|
||||||
|
SL-14941
|
||||||
SL-13395
|
SL-13395
|
||||||
SL-3136
|
SL-3136
|
||||||
|
SL-15200
|
||||||
|
SL-15226
|
||||||
|
SL-15227
|
||||||
|
SL-15398
|
||||||
Aralara Rajal
|
Aralara Rajal
|
||||||
Arare Chantilly
|
Arare Chantilly
|
||||||
CHUIBUG-191
|
CHUIBUG-191
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llmeshoptimizer)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llmessage)
|
add_subdirectory(${LIBS_OPEN_PREFIX}llmessage)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llprimitive)
|
add_subdirectory(${LIBS_OPEN_PREFIX}llprimitive)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llrender)
|
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}llwindow)
|
||||||
add_subdirectory(${LIBS_OPEN_PREFIX}llxml)
|
add_subdirectory(${LIBS_OPEN_PREFIX}llxml)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,6 @@ if (WINDOWS)
|
||||||
if( ADDRESS_SIZE EQUAL 32 )
|
if( ADDRESS_SIZE EQUAL 32 )
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /p:PreferredToolArchitecture=x64")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /p:PreferredToolArchitecture=x64")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Preserve first-pass-through versions (ie no FORCE overwrite). Prevents recursive addition of /Zo (04/2021)
|
# Preserve first-pass-through versions (ie no FORCE overwrite). Prevents recursive addition of /Zo (04/2021)
|
||||||
set(OG_CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} CACHE STRING "OG_CXX_FLAGS_RELEASE")
|
set(OG_CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} CACHE STRING "OG_CXX_FLAGS_RELEASE")
|
||||||
set(OG_CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} CACHE STRING "OG_CXX_FLAGS_RELWITHDEBINFO")
|
set(OG_CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} CACHE STRING "OG_CXX_FLAGS_RELWITHDEBINFO")
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ set(cmake_SOURCE_FILES
|
||||||
LLSharedLibs.cmake
|
LLSharedLibs.cmake
|
||||||
LLTestCommand.cmake
|
LLTestCommand.cmake
|
||||||
LLUI.cmake
|
LLUI.cmake
|
||||||
LLVFS.cmake
|
LLFileSystem.cmake
|
||||||
LLWindow.cmake
|
LLWindow.cmake
|
||||||
LLXML.cmake
|
LLXML.cmake
|
||||||
Linking.cmake
|
Linking.cmake
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
# -*- cmake -*-
|
||||||
|
use_prebuilt_binary(cubemaptoequirectangular)
|
||||||
|
|
||||||
|
# Main JS file
|
||||||
|
configure_file("${AUTOBUILD_INSTALL_DIR}/js/CubemapToEquirectangular.js" "${CMAKE_SOURCE_DIR}/newview/skins/default/html/common/equirectangular/js/CubemapToEquirectangular.js" COPYONLY)
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
# -*- cmake -*-
|
||||||
|
use_prebuilt_binary(jpegencoderbasic)
|
||||||
|
|
||||||
|
# Main JS file
|
||||||
|
configure_file("${AUTOBUILD_INSTALL_DIR}/js/jpeg_encoder_basic.js" "${CMAKE_SOURCE_DIR}/newview/skins/default/html/common/equirectangular/js/jpeg_encoder_basic.js" COPYONLY)
|
||||||
|
|
@ -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)
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
# -*- cmake -*-
|
||||||
|
use_prebuilt_binary(threejs)
|
||||||
|
|
||||||
|
# Main three.js file
|
||||||
|
configure_file("${AUTOBUILD_INSTALL_DIR}/js/three.min.js" "${CMAKE_SOURCE_DIR}/newview/skins/default/html/common/equirectangular/js/three.min.js" COPYONLY)
|
||||||
|
|
||||||
|
# Controls to move around the scene using mouse or keyboard
|
||||||
|
configure_file("${AUTOBUILD_INSTALL_DIR}/js/OrbitControls.js" "${CMAKE_SOURCE_DIR}/newview/skins/default/html/common/equirectangular/js/OrbitControls.js" COPYONLY)
|
||||||
|
|
@ -10,11 +10,11 @@ include(LLImage)
|
||||||
include(LLMath)
|
include(LLMath)
|
||||||
include(LLImageJ2COJ)
|
include(LLImageJ2COJ)
|
||||||
include(LLKDU)
|
include(LLKDU)
|
||||||
include(LLVFS)
|
include(LLFileSystem)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${LLCOMMON_INCLUDE_DIRS}
|
${LLCOMMON_INCLUDE_DIRS}
|
||||||
${LLVFS_INCLUDE_DIRS}
|
${LLFILESYSTEM_INCLUDE_DIRS}
|
||||||
${LLIMAGE_INCLUDE_DIRS}
|
${LLIMAGE_INCLUDE_DIRS}
|
||||||
${LLMATH_INCLUDE_DIRS}
|
${LLMATH_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
@ -66,7 +66,7 @@ endif (DARWIN)
|
||||||
target_link_libraries(llimage_libtest
|
target_link_libraries(llimage_libtest
|
||||||
${LEGACY_STDIO_LIBS}
|
${LEGACY_STDIO_LIBS}
|
||||||
${LLCOMMON_LIBRARIES}
|
${LLCOMMON_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${LLIMAGE_LIBRARIES}
|
${LLIMAGE_LIBRARIES}
|
||||||
${LLKDU_LIBRARIES}
|
${LLKDU_LIBRARIES}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ include(LLMessage)
|
||||||
include(LLRender)
|
include(LLRender)
|
||||||
include(LLWindow)
|
include(LLWindow)
|
||||||
include(LLUI)
|
include(LLUI)
|
||||||
include(LLVFS) # ugh, needed for LLDir
|
include(LLFileSystem)
|
||||||
include(LLXML)
|
include(LLXML)
|
||||||
include(Hunspell)
|
include(Hunspell)
|
||||||
include(Linking)
|
include(Linking)
|
||||||
|
|
@ -29,7 +29,7 @@ include_directories(
|
||||||
${LLMATH_INCLUDE_DIRS}
|
${LLMATH_INCLUDE_DIRS}
|
||||||
${LLRENDER_INCLUDE_DIRS}
|
${LLRENDER_INCLUDE_DIRS}
|
||||||
${LLUI_INCLUDE_DIRS}
|
${LLUI_INCLUDE_DIRS}
|
||||||
${LLVFS_INCLUDE_DIRS}
|
${LLFILESYSTEM_INCLUDE_DIRS}
|
||||||
${LLWINDOW_INCLUDE_DIRS}
|
${LLWINDOW_INCLUDE_DIRS}
|
||||||
${LLXML_INCLUDE_DIRS}
|
${LLXML_INCLUDE_DIRS}
|
||||||
${LIBS_PREBUILD_DIR}/include/hunspell
|
${LIBS_PREBUILD_DIR}/include/hunspell
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ include(LLCommon)
|
||||||
include(LLCrashLogger)
|
include(LLCrashLogger)
|
||||||
include(LLMath)
|
include(LLMath)
|
||||||
include(LLMessage)
|
include(LLMessage)
|
||||||
include(LLVFS)
|
include(LLFileSystem)
|
||||||
include(LLXML)
|
include(LLXML)
|
||||||
include(Linking)
|
include(Linking)
|
||||||
include(UI)
|
include(UI)
|
||||||
|
|
@ -21,7 +21,7 @@ include_directories(
|
||||||
${LLCOMMON_INCLUDE_DIRS}
|
${LLCOMMON_INCLUDE_DIRS}
|
||||||
${LLCRASHLOGGER_INCLUDE_DIRS}
|
${LLCRASHLOGGER_INCLUDE_DIRS}
|
||||||
${LLMATH_INCLUDE_DIRS}
|
${LLMATH_INCLUDE_DIRS}
|
||||||
${LLVFS_INCLUDE_DIRS}
|
${LLFILESYSTEM_INCLUDE_DIRS}
|
||||||
${LLXML_INCLUDE_DIRS}
|
${LLXML_INCLUDE_DIRS}
|
||||||
${FREETYPE_INCLUDE_DIRS}
|
${FREETYPE_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
@ -62,10 +62,9 @@ set(LIBRT_LIBRARY rt)
|
||||||
|
|
||||||
target_link_libraries(linux-crash-logger
|
target_link_libraries(linux-crash-logger
|
||||||
${LLCRASHLOGGER_LIBRARIES}
|
${LLCRASHLOGGER_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLXML_LIBRARIES}
|
${LLXML_LIBRARIES}
|
||||||
${LLMESSAGE_LIBRARIES}
|
${LLMESSAGE_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${LLCOREHTTP_LIBRARIES}
|
${LLCOREHTTP_LIBRARIES}
|
||||||
${LLCOMMON_LIBRARIES}
|
${LLCOMMON_LIBRARIES}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ include(LLMath)
|
||||||
include(LLMessage)
|
include(LLMessage)
|
||||||
include(LLCoreHttp)
|
include(LLCoreHttp)
|
||||||
include(LLRender)
|
include(LLRender)
|
||||||
include(LLVFS)
|
include(LLFileSystem)
|
||||||
include(LLWindow)
|
include(LLWindow)
|
||||||
include(LLXML)
|
include(LLXML)
|
||||||
include(Linking)
|
include(Linking)
|
||||||
|
|
@ -23,7 +23,7 @@ include_directories(
|
||||||
${LLINVENTORY_INCLUDE_DIRS}
|
${LLINVENTORY_INCLUDE_DIRS}
|
||||||
${LLMATH_INCLUDE_DIRS}
|
${LLMATH_INCLUDE_DIRS}
|
||||||
${LLRENDER_INCLUDE_DIRS}
|
${LLRENDER_INCLUDE_DIRS}
|
||||||
${LLVFS_INCLUDE_DIRS}
|
${LLFILESYSTEM_INCLUDE_DIRS}
|
||||||
${LLWINDOW_INCLUDE_DIRS}
|
${LLWINDOW_INCLUDE_DIRS}
|
||||||
${LLXML_INCLUDE_DIRS}
|
${LLXML_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
@ -83,7 +83,7 @@ target_link_libraries(llappearance
|
||||||
${LLINVENTORY_LIBRARIES}
|
${LLINVENTORY_LIBRARIES}
|
||||||
${LLIMAGE_LIBRARIES}
|
${LLIMAGE_LIBRARIES}
|
||||||
${LLRENDER_LIBRARIES}
|
${LLRENDER_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${LLXML_LIBRARIES}
|
${LLXML_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
|
|
@ -100,7 +100,7 @@ if (BUILD_HEADLESS)
|
||||||
${LLINVENTORY_LIBRARIES}
|
${LLINVENTORY_LIBRARIES}
|
||||||
${LLIMAGE_LIBRARIES}
|
${LLIMAGE_LIBRARIES}
|
||||||
${LLRENDERHEADLESS_LIBRARIES}
|
${LLRENDERHEADLESS_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${LLXML_LIBRARIES}
|
${LLXML_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
|
|
@ -109,15 +109,3 @@ if (BUILD_HEADLESS)
|
||||||
${LLCOMMON_LIBRARIES}
|
${LLCOMMON_LIBRARIES}
|
||||||
)
|
)
|
||||||
endif (BUILD_HEADLESS)
|
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 "llimagej2c.h"
|
||||||
#include "llimagetga.h"
|
#include "llimagetga.h"
|
||||||
#include "lldir.h"
|
#include "lldir.h"
|
||||||
#include "llvfile.h"
|
|
||||||
#include "llvfs.h"
|
|
||||||
#include "lltexlayerparams.h"
|
#include "lltexlayerparams.h"
|
||||||
#include "lltexturemanagerbridge.h"
|
#include "lltexturemanagerbridge.h"
|
||||||
#include "lllocaltextureobject.h"
|
#include "lllocaltextureobject.h"
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,14 @@ include(OPENAL)
|
||||||
include(LLCommon)
|
include(LLCommon)
|
||||||
include(LLMath)
|
include(LLMath)
|
||||||
include(LLMessage)
|
include(LLMessage)
|
||||||
include(LLVFS)
|
include(LLFileSystem)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${LLAUDIO_INCLUDE_DIRS}
|
${LLAUDIO_INCLUDE_DIRS}
|
||||||
${LLCOMMON_INCLUDE_DIRS}
|
${LLCOMMON_INCLUDE_DIRS}
|
||||||
${LLMATH_INCLUDE_DIRS}
|
${LLMATH_INCLUDE_DIRS}
|
||||||
${LLMESSAGE_INCLUDE_DIRS}
|
${LLMESSAGE_INCLUDE_DIRS}
|
||||||
${LLVFS_INCLUDE_DIRS}
|
${LLFILESYSTEM_INCLUDE_DIRS}
|
||||||
${OGG_INCLUDE_DIRS}
|
${OGG_INCLUDE_DIRS}
|
||||||
${VORBISENC_INCLUDE_DIRS}
|
${VORBISENC_INCLUDE_DIRS}
|
||||||
${VORBISFILE_INCLUDE_DIRS}
|
${VORBISFILE_INCLUDE_DIRS}
|
||||||
|
|
@ -86,7 +86,7 @@ target_link_libraries(
|
||||||
${LLCOMMON_LIBRARIES}
|
${LLCOMMON_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${LLMESSAGE_LIBRARIES}
|
${LLMESSAGE_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${VORBISENC_LIBRARIES}
|
${VORBISENC_LIBRARIES}
|
||||||
${VORBISFILE_LIBRARIES}
|
${VORBISFILE_LIBRARIES}
|
||||||
${VORBIS_LIBRARIES}
|
${VORBIS_LIBRARIES}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
#include "llaudioengine.h"
|
#include "llaudioengine.h"
|
||||||
#include "lllfsthread.h"
|
#include "lllfsthread.h"
|
||||||
#include "llvfile.h"
|
#include "llfilesystem.h"
|
||||||
#include "llstring.h"
|
#include "llstring.h"
|
||||||
#include "lldir.h"
|
#include "lldir.h"
|
||||||
#include "llendianswizzle.h"
|
#include "llendianswizzle.h"
|
||||||
|
|
@ -90,19 +90,17 @@ protected:
|
||||||
LLUUID mUUID;
|
LLUUID mUUID;
|
||||||
|
|
||||||
std::vector<U8> mWAVBuffer;
|
std::vector<U8> mWAVBuffer;
|
||||||
#if !defined(USE_WAV_VFILE)
|
|
||||||
std::string mOutFilename;
|
std::string mOutFilename;
|
||||||
LLLFSThread::handle_t mFileHandle;
|
LLLFSThread::handle_t mFileHandle;
|
||||||
#endif
|
|
||||||
|
|
||||||
LLVFile *mInFilep;
|
LLFileSystem *mInFilep;
|
||||||
OggVorbis_File mVF;
|
OggVorbis_File mVF;
|
||||||
S32 mCurrentSection;
|
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*/
|
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)
|
if (offset > S32_MAX)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -137,7 +135,7 @@ S32 vfs_seek(void *datasource, ogg_int64_t offset, S32 whence)
|
||||||
origin = -1;
|
origin = -1;
|
||||||
break;
|
break;
|
||||||
default:
|
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;
|
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;
|
delete file;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
long vfs_tell (void *datasource)
|
long cache_tell (void *datasource)
|
||||||
{
|
{
|
||||||
LLVFile *file = (LLVFile *)datasource;
|
LLFileSystem *file = (LLFileSystem *)datasource;
|
||||||
return file->tell();
|
return file->tell();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -172,11 +170,10 @@ LLVorbisDecodeState::LLVorbisDecodeState(const LLUUID &uuid, const std::string &
|
||||||
mUUID = uuid;
|
mUUID = uuid;
|
||||||
mInFilep = NULL;
|
mInFilep = NULL;
|
||||||
mCurrentSection = 0;
|
mCurrentSection = 0;
|
||||||
#if !defined(USE_WAV_VFILE)
|
|
||||||
mOutFilename = out_filename;
|
mOutFilename = out_filename;
|
||||||
mFileHandle = LLLFSThread::nullHandle();
|
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.
|
// Hey, let's zero it anyway, for predictability.
|
||||||
memset(&mVF, 0, sizeof(mVF));
|
memset(&mVF, 0, sizeof(mVF));
|
||||||
}
|
}
|
||||||
|
|
@ -193,15 +190,15 @@ LLVorbisDecodeState::~LLVorbisDecodeState()
|
||||||
|
|
||||||
BOOL LLVorbisDecodeState::initDecode()
|
BOOL LLVorbisDecodeState::initDecode()
|
||||||
{
|
{
|
||||||
ov_callbacks vfs_callbacks;
|
ov_callbacks cache_callbacks;
|
||||||
vfs_callbacks.read_func = vfs_read;
|
cache_callbacks.read_func = cache_read;
|
||||||
vfs_callbacks.seek_func = vfs_seek;
|
cache_callbacks.seek_func = cache_seek;
|
||||||
vfs_callbacks.close_func = vfs_close;
|
cache_callbacks.close_func = cache_close;
|
||||||
vfs_callbacks.tell_func = vfs_tell;
|
cache_callbacks.tell_func = cache_tell;
|
||||||
|
|
||||||
LL_DEBUGS("AudioEngine") << "Initing decode from vfile: " << mUUID << LL_ENDL;
|
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())
|
if (!mInFilep || !mInFilep->getSize())
|
||||||
{
|
{
|
||||||
LL_WARNS("AudioEngine") << "unable to open vorbis source vfile for reading" << LL_ENDL;
|
LL_WARNS("AudioEngine") << "unable to open vorbis source vfile for reading" << LL_ENDL;
|
||||||
|
|
@ -210,7 +207,7 @@ BOOL LLVorbisDecodeState::initDecode()
|
||||||
return FALSE;
|
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)
|
if(r < 0)
|
||||||
{
|
{
|
||||||
LL_WARNS("AudioEngine") << r << " Input to vorbis decode does not appear to be an Ogg bitstream: " << mUUID << LL_ENDL;
|
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)
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
if (mDone)
|
if (mDone)
|
||||||
|
|
@ -420,9 +417,7 @@ BOOL LLVorbisDecodeState::finishDecode()
|
||||||
return TRUE; // We've finished
|
return TRUE; // We've finished
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(USE_WAV_VFILE)
|
|
||||||
if (mFileHandle == LLLFSThread::nullHandle())
|
if (mFileHandle == LLLFSThread::nullHandle())
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
ov_clear(&mVF);
|
ov_clear(&mVF);
|
||||||
|
|
||||||
|
|
@ -495,11 +490,9 @@ BOOL LLVorbisDecodeState::finishDecode()
|
||||||
mValid = FALSE;
|
mValid = FALSE;
|
||||||
return TRUE; // we've finished
|
return TRUE; // we've finished
|
||||||
}
|
}
|
||||||
#if !defined(USE_WAV_VFILE)
|
|
||||||
mBytesRead = -1;
|
mBytesRead = -1;
|
||||||
mFileHandle = LLLFSThread::sLocal->write(mOutFilename, &mWAVBuffer[0], 0, mWAVBuffer.size(),
|
mFileHandle = LLLFSThread::sLocal->write(mOutFilename, &mWAVBuffer[0], 0, mWAVBuffer.size(),
|
||||||
new WriteResponder(this));
|
new WriteResponder(this));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mFileHandle != LLLFSThread::nullHandle())
|
if (mFileHandle != LLLFSThread::nullHandle())
|
||||||
|
|
@ -521,11 +514,6 @@ BOOL LLVorbisDecodeState::finishDecode()
|
||||||
|
|
||||||
mDone = TRUE;
|
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;
|
LL_DEBUGS("AudioEngine") << "Finished decode for " << getUUID() << LL_ENDL;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
@ -535,7 +523,7 @@ void LLVorbisDecodeState::flushBadFile()
|
||||||
{
|
{
|
||||||
if (mInFilep)
|
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();
|
mInFilep->remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@
|
||||||
#include "llassettype.h"
|
#include "llassettype.h"
|
||||||
#include "llframetimer.h"
|
#include "llframetimer.h"
|
||||||
|
|
||||||
class LLVFS;
|
|
||||||
class LLVorbisDecodeState;
|
class LLVorbisDecodeState;
|
||||||
|
|
||||||
class LLAudioDecodeMgr
|
class LLAudioDecodeMgr
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
#include "sound_ids.h" // temporary hack for min/max distances
|
#include "sound_ids.h" // temporary hack for min/max distances
|
||||||
|
|
||||||
#include "llvfs.h"
|
#include "llfilesystem.h"
|
||||||
#include "lldir.h"
|
#include "lldir.h"
|
||||||
#include "llaudiodecodemgr.h"
|
#include "llaudiodecodemgr.h"
|
||||||
#include "llassetstorage.h"
|
#include "llassetstorage.h"
|
||||||
|
|
@ -684,13 +684,9 @@ bool LLAudioEngine::preloadSound(const LLUUID &uuid)
|
||||||
return true;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LLAudioEngine::isWindEnabled()
|
bool LLAudioEngine::isWindEnabled()
|
||||||
{
|
{
|
||||||
return mEnableWind;
|
return mEnableWind;
|
||||||
|
|
@ -1018,13 +1014,12 @@ bool LLAudioEngine::hasDecodedFile(const LLUUID &uuid)
|
||||||
|
|
||||||
bool LLAudioEngine::hasLocalFile(const LLUUID &uuid)
|
bool LLAudioEngine::hasLocalFile(const LLUUID &uuid)
|
||||||
{
|
{
|
||||||
// See if it's in the VFS.
|
// See if it's in the cache.
|
||||||
bool have_local = gVFS->getExists(uuid, LLAssetType::AT_SOUND);
|
bool have_local = LLFileSystem::getExists(uuid, LLAssetType::AT_SOUND);
|
||||||
LL_DEBUGS("AudioEngine") << "sound uuid "<<uuid<<" exists in VFS"<<LL_ENDL;
|
LL_DEBUGS("AudioEngine") << "sound uuid " << uuid << " exists in cache" << LL_ENDL;
|
||||||
return have_local;
|
return have_local;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LLAudioEngine::startNextTransfer()
|
void LLAudioEngine::startNextTransfer()
|
||||||
{
|
{
|
||||||
//LL_INFOS() << "LLAudioEngine::startNextTransfer()" << LL_ENDL;
|
//LL_INFOS() << "LLAudioEngine::startNextTransfer()" << LL_ENDL;
|
||||||
|
|
@ -1225,7 +1220,7 @@ void LLAudioEngine::startNextTransfer()
|
||||||
|
|
||||||
|
|
||||||
// static
|
// 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)
|
if (!gAudiop)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -50,15 +50,6 @@ const F32 DEFAULT_MIN_DISTANCE = 2.0f;
|
||||||
#define MAX_CHANNELS 30
|
#define MAX_CHANNELS 30
|
||||||
#define MAX_BUFFERS 40 // Some extra for preloading, maybe?
|
#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 LLAudioSource;
|
||||||
class LLAudioData;
|
class LLAudioData;
|
||||||
class LLAudioChannel;
|
class LLAudioChannel;
|
||||||
|
|
@ -67,11 +58,9 @@ class LLAudioBuffer;
|
||||||
class LLStreamingAudioInterface;
|
class LLStreamingAudioInterface;
|
||||||
struct SoundData;
|
struct SoundData;
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// LLAudioEngine definition
|
// LLAudioEngine definition
|
||||||
//
|
//
|
||||||
|
|
||||||
class LLAudioEngine
|
class LLAudioEngine
|
||||||
{
|
{
|
||||||
friend class LLAudioChannelOpenAL; // bleh. channel needs some listener methods.
|
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.
|
// Asset callback when we're retrieved a sound from the asset server.
|
||||||
void startNextTransfer();
|
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
|
friend class LLPipeline; // For debugging
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,14 @@ include(00-Common)
|
||||||
include(LLCommon)
|
include(LLCommon)
|
||||||
include(LLMath)
|
include(LLMath)
|
||||||
include(LLMessage)
|
include(LLMessage)
|
||||||
include(LLVFS)
|
include(LLFileSystem)
|
||||||
include(LLXML)
|
include(LLXML)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${LLCOMMON_INCLUDE_DIRS}
|
${LLCOMMON_INCLUDE_DIRS}
|
||||||
${LLMATH_INCLUDE_DIRS}
|
${LLMATH_INCLUDE_DIRS}
|
||||||
${LLMESSAGE_INCLUDE_DIRS}
|
${LLMESSAGE_INCLUDE_DIRS}
|
||||||
${LLVFS_INCLUDE_DIRS}
|
${LLFILESYSTEM_INCLUDE_DIRS}
|
||||||
${LLXML_INCLUDE_DIRS}
|
${LLXML_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
include_directories(SYSTEM
|
include_directories(SYSTEM
|
||||||
|
|
@ -85,18 +85,6 @@ target_link_libraries(
|
||||||
${LLCOMMON_LIBRARIES}
|
${LLCOMMON_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${LLMESSAGE_LIBRARIES}
|
${LLMESSAGE_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLXML_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
|
// load keyframe data, setup pose and joint states
|
||||||
LLMotion::LLMotionInitStatus result = LLKeyframeMotion::onInitialize(character);
|
LLMotion::LLMotionInitStatus result = LLKeyframeMotion::onInitialize(character);
|
||||||
|
|
||||||
|
if (result != LLMotion::STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
for (U32 jm=0; jm<mJointMotionList->getNumJointMotions(); jm++)
|
for (U32 jm=0; jm<mJointMotionList->getNumJointMotions(); jm++)
|
||||||
{
|
{
|
||||||
if (!mJointStates[jm]->getJoint())
|
if (!mJointStates[jm]->getJoint())
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,13 @@
|
||||||
#include "llendianswizzle.h"
|
#include "llendianswizzle.h"
|
||||||
#include "llkeyframemotion.h"
|
#include "llkeyframemotion.h"
|
||||||
#include "llquantize.h"
|
#include "llquantize.h"
|
||||||
#include "llvfile.h"
|
|
||||||
#include "m3math.h"
|
#include "m3math.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
#include "llfilesystem.h"
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Static Definitions
|
// Static Definitions
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
LLVFS* LLKeyframeMotion::sVFS = NULL;
|
|
||||||
LLKeyframeDataCache::keyframe_data_map_t LLKeyframeDataCache::sKeyframeDataMap;
|
LLKeyframeDataCache::keyframe_data_map_t LLKeyframeDataCache::sKeyframeDataMap;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -515,7 +514,7 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
default:
|
default:
|
||||||
// we don't know what state the asset is in yet, so keep going
|
// 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -559,13 +558,8 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact
|
||||||
U8 *anim_data;
|
U8 *anim_data;
|
||||||
S32 anim_file_size;
|
S32 anim_file_size;
|
||||||
|
|
||||||
if (!sVFS)
|
|
||||||
{
|
|
||||||
LL_ERRS() << "Must call LLKeyframeMotion::setVFS() first before loading a keyframe file!" << LL_ENDL;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL success = FALSE;
|
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())
|
if (!anim_file || !anim_file->getSize())
|
||||||
{
|
{
|
||||||
delete anim_file;
|
delete anim_file;
|
||||||
|
|
@ -2297,10 +2291,9 @@ void LLKeyframeMotion::setLoopOut(F32 out_point)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// onLoadComplete()
|
// onLoadComplete()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
|
void LLKeyframeMotion::onLoadComplete(const LLUUID& asset_uuid,
|
||||||
const LLUUID& asset_uuid,
|
LLAssetType::EType type,
|
||||||
LLAssetType::EType type,
|
void* user_data, S32 status, LLExtStat ext_status)
|
||||||
void* user_data, S32 status, LLExtStat ext_status)
|
|
||||||
{
|
{
|
||||||
LLUUID* id = (LLUUID*)user_data;
|
LLUUID* id = (LLUUID*)user_data;
|
||||||
|
|
||||||
|
|
@ -2332,7 +2325,7 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
|
||||||
// asset already loaded
|
// asset already loaded
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
|
LLFileSystem file(asset_uuid, type, LLFileSystem::READ);
|
||||||
S32 size = file.getSize();
|
S32 size = file.getSize();
|
||||||
|
|
||||||
U8* buffer = new U8[size];
|
U8* buffer = new U8[size];
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@
|
||||||
#include "llbvhconsts.h"
|
#include "llbvhconsts.h"
|
||||||
|
|
||||||
class LLKeyframeDataCache;
|
class LLKeyframeDataCache;
|
||||||
class LLVFS;
|
|
||||||
class LLDataPacker;
|
class LLDataPacker;
|
||||||
|
|
||||||
#define MIN_REQUIRED_PIXEL_AREA_KEYFRAME (40.f)
|
#define MIN_REQUIRED_PIXEL_AREA_KEYFRAME (40.f)
|
||||||
|
|
@ -141,10 +140,7 @@ public:
|
||||||
|
|
||||||
virtual void setStopTime(F32 time);
|
virtual void setStopTime(F32 time);
|
||||||
|
|
||||||
static void setVFS(LLVFS* vfs) { sVFS = vfs; }
|
static void onLoadComplete(const LLUUID& asset_uuid,
|
||||||
|
|
||||||
static void onLoadComplete(LLVFS *vfs,
|
|
||||||
const LLUUID& asset_uuid,
|
|
||||||
LLAssetType::EType type,
|
LLAssetType::EType type,
|
||||||
void* user_data, S32 status, LLExtStat ext_status);
|
void* user_data, S32 status, LLExtStat ext_status);
|
||||||
|
|
||||||
|
|
@ -416,13 +412,7 @@ public:
|
||||||
U32 getNumJointMotions() const { return mJointMotionArray.size(); }
|
U32 getNumJointMotions() const { return mJointMotionArray.size(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static LLVFS* sVFS;
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
// Member Data
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
JointMotionList* mJointMotionList;
|
JointMotionList* mJointMotionList;
|
||||||
std::vector<LLPointer<LLJointState> > mJointStates;
|
std::vector<LLPointer<LLJointState> > mJointStates;
|
||||||
LLJoint* mPelvisp;
|
LLJoint* mPelvisp;
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,8 @@ BOOL LLApp::sDisableCrashlogger = FALSE;
|
||||||
BOOL LLApp::sLogInSignal = FALSE;
|
BOOL LLApp::sLogInSignal = FALSE;
|
||||||
|
|
||||||
// static
|
// 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;
|
LLAppErrorHandler LLApp::sErrorHandler = NULL;
|
||||||
BOOL LLApp::sErrorThreadRunning = FALSE;
|
BOOL LLApp::sErrorThreadRunning = FALSE;
|
||||||
|
|
||||||
|
|
@ -452,7 +453,8 @@ static std::map<LLApp::EAppStatus, const char*> statusDesc
|
||||||
// static
|
// static
|
||||||
void LLApp::setStatus(EAppStatus status)
|
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
|
// This can also happen very late in the application lifecycle -- don't
|
||||||
// resurrect a deleted LLSingleton
|
// resurrect a deleted LLSingleton
|
||||||
|
|
@ -514,28 +516,28 @@ void LLApp::setStopped()
|
||||||
// static
|
// static
|
||||||
bool LLApp::isStopped()
|
bool LLApp::isStopped()
|
||||||
{
|
{
|
||||||
return (APP_STATUS_STOPPED == sStatus);
|
return (APP_STATUS_STOPPED == sStatus.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool LLApp::isRunning()
|
bool LLApp::isRunning()
|
||||||
{
|
{
|
||||||
return (APP_STATUS_RUNNING == sStatus);
|
return (APP_STATUS_RUNNING == sStatus.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool LLApp::isError()
|
bool LLApp::isError()
|
||||||
{
|
{
|
||||||
return (APP_STATUS_ERROR == sStatus);
|
return (APP_STATUS_ERROR == sStatus.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool LLApp::isQuitting()
|
bool LLApp::isQuitting()
|
||||||
{
|
{
|
||||||
return (APP_STATUS_QUITTING == sStatus);
|
return (APP_STATUS_QUITTING == sStatus.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,11 @@
|
||||||
#define LL_LLAPP_H
|
#define LL_LLAPP_H
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include "llcond.h"
|
||||||
#include "llrun.h"
|
#include "llrun.h"
|
||||||
#include "llsd.h"
|
#include "llsd.h"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
class LLErrorThread;
|
class LLErrorThread;
|
||||||
class LLLiveFile;
|
class LLLiveFile;
|
||||||
|
|
@ -207,6 +209,36 @@ public:
|
||||||
static bool isExiting(); // Either quitting or error (app is exiting, cleanly or not)
|
static bool isExiting(); // Either quitting or error (app is exiting, cleanly or not)
|
||||||
static int getPid();
|
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 */
|
/** @name Error handling methods */
|
||||||
//@{
|
//@{
|
||||||
/**
|
/**
|
||||||
|
|
@ -236,8 +268,8 @@ public:
|
||||||
|
|
||||||
// Return the Google Breakpad minidump filename after a crash.
|
// Return the Google Breakpad minidump filename after a crash.
|
||||||
char *getMiniDumpFilename() { return mMinidumpPath; }
|
char *getMiniDumpFilename() { return mMinidumpPath; }
|
||||||
std::string* getStaticDebugFile() { return &mStaticDebugFileName; }
|
std::string* getStaticDebugFile() { return &mStaticDebugFileName; }
|
||||||
std::string* getDynamicDebugFile() { return &mDynamicDebugFileName; }
|
std::string* getDynamicDebugFile() { return &mDynamicDebugFileName; }
|
||||||
|
|
||||||
// Write out a Google Breakpad minidump file.
|
// Write out a Google Breakpad minidump file.
|
||||||
void writeMiniDump();
|
void writeMiniDump();
|
||||||
|
|
@ -265,7 +297,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
static void setStatus(EAppStatus status); // Use this to change the application status.
|
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 sErrorThreadRunning; // Set while the error thread is running
|
||||||
static BOOL sDisableCrashlogger; // Let the OS handle crashes for us.
|
static BOOL sDisableCrashlogger; // Let the OS handle crashes for us.
|
||||||
std::wstring mCrashReportPipeStr; //Name of pipe to use for crash reporting.
|
std::wstring mCrashReportPipeStr; //Name of pipe to use for crash reporting.
|
||||||
|
|
|
||||||
|
|
@ -197,13 +197,37 @@ namespace {
|
||||||
return LLError::getEnabledLogTypesMask() & 0x04;
|
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)
|
LL_FORCE_INLINE std::string createANSI(const std::string& color)
|
||||||
{
|
{
|
||||||
std::string ansi_code;
|
std::string ansi_code;
|
||||||
ansi_code += '\033';
|
ansi_code += '\033';
|
||||||
ansi_code += "[";
|
ansi_code += "[";
|
||||||
|
ansi_code += "38;5;";
|
||||||
ansi_code += color;
|
ansi_code += color;
|
||||||
ansi_code += "m";
|
ansi_code += "m";
|
||||||
|
|
||||||
return ansi_code;
|
return ansi_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,9 +235,26 @@ namespace {
|
||||||
const std::string& message) override
|
const std::string& message) override
|
||||||
{
|
{
|
||||||
LL_PROFILE_ZONE_SCOPED
|
LL_PROFILE_ZONE_SCOPED
|
||||||
static std::string s_ansi_error = createANSI("31"); // red
|
// The default colors for error, warn and debug are now a bit more pastel
|
||||||
static std::string s_ansi_warn = createANSI("34"); // blue
|
// and easier to read on the default (black) terminal background but you
|
||||||
static std::string s_ansi_debug = createANSI("35"); // magenta
|
// 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)
|
if (mUseANSI)
|
||||||
{
|
{
|
||||||
|
|
@ -224,7 +265,7 @@ namespace {
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LL_PROFILE_ZONE_NAMED("fprintf");
|
LL_PROFILE_ZONE_NAMED("fprintf");
|
||||||
fprintf(stderr, "%s\n", message.c_str());
|
fprintf(stderr, "%s\n", message.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,11 +275,11 @@ namespace {
|
||||||
LL_FORCE_INLINE void writeANSI(const std::string& ansi_code, const std::string& message)
|
LL_FORCE_INLINE void writeANSI(const std::string& ansi_code, const std::string& message)
|
||||||
{
|
{
|
||||||
LL_PROFILE_ZONE_SCOPED
|
LL_PROFILE_ZONE_SCOPED
|
||||||
static std::string s_ansi_bold = createANSI("1"); // bold
|
static std::string s_ansi_bold = createBoldANSI(); // bold text
|
||||||
static std::string s_ansi_reset = createANSI("0"); // reset
|
static std::string s_ansi_reset = createResetANSI(); // reset
|
||||||
// ANSI color code escape sequence, message, and reset in one fprintf call
|
// 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.
|
// 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)
|
static bool checkANSI(void)
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@
|
||||||
#ifndef LL_LLTHREAD_H
|
#ifndef LL_LLTHREAD_H
|
||||||
#define LL_LLTHREAD_H
|
#define LL_LLTHREAD_H
|
||||||
|
|
||||||
#include "llapp.h"
|
|
||||||
#include "llapr.h"
|
#include "llapr.h"
|
||||||
#include "boost/intrusive_ptr.hpp"
|
#include "boost/intrusive_ptr.hpp"
|
||||||
#include "llrefcount.h"
|
#include "llrefcount.h"
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "llapp.h"
|
||||||
#include "lldefs.h"
|
#include "lldefs.h"
|
||||||
#include "llerror.h"
|
#include "llerror.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ include(LLCoreHttp)
|
||||||
include(LLCommon)
|
include(LLCommon)
|
||||||
include(LLMath)
|
include(LLMath)
|
||||||
include(LLMessage)
|
include(LLMessage)
|
||||||
include(LLVFS)
|
include(LLFileSystem)
|
||||||
include(LLXML)
|
include(LLXML)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
|
|
@ -15,7 +15,7 @@ include_directories(
|
||||||
${LLCOMMON_INCLUDE_DIRS}
|
${LLCOMMON_INCLUDE_DIRS}
|
||||||
${LLMATH_INCLUDE_DIRS}
|
${LLMATH_INCLUDE_DIRS}
|
||||||
${LLMESSAGE_INCLUDE_DIRS}
|
${LLMESSAGE_INCLUDE_DIRS}
|
||||||
${LLVFS_INCLUDE_DIRS}
|
${LLFILESYSTEM_INCLUDE_DIRS}
|
||||||
${LLXML_INCLUDE_DIRS}
|
${LLXML_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
include_directories(SYSTEM
|
include_directories(SYSTEM
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @file llpidlock.h
|
* @file llcrashlock.h
|
||||||
* @brief Maintainence of disk locking files for crash reporting
|
* @brief Maintainence of disk locking files for crash reporting
|
||||||
*
|
*
|
||||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||||
|
|
|
||||||
|
|
@ -596,7 +596,7 @@ bool LLCrashLogger::init()
|
||||||
#if LL_WINDOWS
|
#if LL_WINDOWS
|
||||||
Sleep(1000);
|
Sleep(1000);
|
||||||
#else
|
#else
|
||||||
sleep(1);
|
::sleep(1);
|
||||||
#endif
|
#endif
|
||||||
locked = mKeyMaster.checkMaster();
|
locked = mKeyMaster.checkMaster();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# -*- cmake -*-
|
# -*- cmake -*-
|
||||||
|
|
||||||
project(llvfs)
|
project(llfilesystem)
|
||||||
|
|
||||||
include(00-Common)
|
include(00-Common)
|
||||||
include(LLCommon)
|
include(LLCommon)
|
||||||
|
|
@ -11,39 +11,34 @@ include_directories(
|
||||||
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
|
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
set(llvfs_SOURCE_FILES
|
set(llfilesystem_SOURCE_FILES
|
||||||
lldir.cpp
|
lldir.cpp
|
||||||
lldiriterator.cpp
|
lldiriterator.cpp
|
||||||
lllfsthread.cpp
|
lllfsthread.cpp
|
||||||
llpidlock.cpp
|
lldiskcache.cpp
|
||||||
llvfile.cpp
|
llfilesystem.cpp
|
||||||
llvfs.cpp
|
|
||||||
llvfsthread.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(llvfs_HEADER_FILES
|
set(llfilesystem_HEADER_FILES
|
||||||
CMakeLists.txt
|
CMakeLists.txt
|
||||||
|
|
||||||
lldir.h
|
lldir.h
|
||||||
lldirguard.h
|
lldirguard.h
|
||||||
lldiriterator.h
|
lldiriterator.h
|
||||||
lllfsthread.h
|
lllfsthread.h
|
||||||
llpidlock.h
|
lldiskcache.h
|
||||||
llvfile.h
|
llfilesystem.h
|
||||||
llvfs.h
|
|
||||||
llvfsthread.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (DARWIN)
|
if (DARWIN)
|
||||||
LIST(APPEND llvfs_SOURCE_FILES lldir_mac.cpp)
|
LIST(APPEND llfilesystem_SOURCE_FILES lldir_utils_objc.mm)
|
||||||
LIST(APPEND llvfs_HEADER_FILES lldir_mac.h)
|
LIST(APPEND llfilesystem_SOURCE_FILES lldir_utils_objc.h)
|
||||||
LIST(APPEND llvfs_SOURCE_FILES llvfs_objc.mm)
|
LIST(APPEND llfilesystem_SOURCE_FILES lldir_mac.cpp)
|
||||||
LIST(APPEND llvfs_HEADER_FILES llvfs_objc.h)
|
LIST(APPEND llfilesystem_HEADER_FILES lldir_mac.h)
|
||||||
endif (DARWIN)
|
endif (DARWIN)
|
||||||
|
|
||||||
if (LINUX)
|
if (LINUX)
|
||||||
LIST(APPEND llvfs_SOURCE_FILES lldir_linux.cpp)
|
LIST(APPEND llfilesystem_SOURCE_FILES lldir_linux.cpp)
|
||||||
LIST(APPEND llvfs_HEADER_FILES lldir_linux.h)
|
LIST(APPEND llfilesystem_HEADER_FILES lldir_linux.h)
|
||||||
|
|
||||||
if (INSTALL)
|
if (INSTALL)
|
||||||
set_source_files_properties(lldir_linux.cpp
|
set_source_files_properties(lldir_linux.cpp
|
||||||
|
|
@ -54,31 +49,31 @@ if (LINUX)
|
||||||
endif (LINUX)
|
endif (LINUX)
|
||||||
|
|
||||||
if (WINDOWS)
|
if (WINDOWS)
|
||||||
LIST(APPEND llvfs_SOURCE_FILES lldir_win32.cpp)
|
LIST(APPEND llfilesystem_SOURCE_FILES lldir_win32.cpp)
|
||||||
LIST(APPEND llvfs_HEADER_FILES lldir_win32.h)
|
LIST(APPEND llfilesystem_HEADER_FILES lldir_win32.h)
|
||||||
endif (WINDOWS)
|
endif (WINDOWS)
|
||||||
|
|
||||||
set_source_files_properties(${llvfs_HEADER_FILES}
|
set_source_files_properties(${llfilesystem_HEADER_FILES}
|
||||||
PROPERTIES HEADER_FILE_ONLY TRUE)
|
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_FILESYSTEM_LIBRARY}
|
||||||
${BOOST_SYSTEM_LIBRARY}
|
${BOOST_SYSTEM_LIBRARY}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(llvfs
|
target_link_libraries(llfilesystem
|
||||||
${LLCOMMON_LIBRARIES}
|
${LLCOMMON_LIBRARIES}
|
||||||
${vfs_BOOST_LIBRARIES}
|
${cache_BOOST_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (DARWIN)
|
if (DARWIN)
|
||||||
include(CMakeFindFrameworks)
|
include(CMakeFindFrameworks)
|
||||||
find_library(COCOA_LIBRARY Cocoa)
|
find_library(COCOA_LIBRARY Cocoa)
|
||||||
target_link_libraries(llvfs ${COCOA_LIBRARY})
|
target_link_libraries(llfilesystem ${COCOA_LIBRARY})
|
||||||
endif (DARWIN)
|
endif (DARWIN)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -86,18 +81,18 @@ endif (DARWIN)
|
||||||
if (LL_TESTS)
|
if (LL_TESTS)
|
||||||
include(LLAddBuildTest)
|
include(LLAddBuildTest)
|
||||||
# UNIT TESTS
|
# UNIT TESTS
|
||||||
SET(llvfs_TEST_SOURCE_FILES
|
SET(llfilesystem_TEST_SOURCE_FILES
|
||||||
lldiriterator.cpp
|
lldiriterator.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set_source_files_properties(lldiriterator.cpp
|
set_source_files_properties(lldiriterator.cpp
|
||||||
PROPERTIES
|
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
|
# 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.
|
# TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests.
|
||||||
LL_ADD_INTEGRATION_TEST(lldir "" "${test_libs}")
|
LL_ADD_INTEGRATION_TEST(lldir "" "${test_libs}")
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
#include <boost/filesystem.hpp>
|
#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
|
* @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
|
* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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.
|
#error This header must not be included when compiling for any target other than Mac OS. Consider including lldir.h instead.
|
||||||
#endif // !LL_DARWIN
|
#endif // !LL_DARWIN
|
||||||
|
|
||||||
#ifndef LL_LLVFS_OBJC_H
|
#ifndef LL_LLDIR_UTILS_OBJC_H
|
||||||
#define LL_LLVFS_OBJC_H
|
#define LL_LLDIR_UTILS_OBJC_H
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
@ -40,4 +40,4 @@ std::string* getSystemResourceFolder();
|
||||||
std::string* getSystemExecutableFolder();
|
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
|
* @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
|
* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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
|
//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>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
std::string* getSystemTempFolder()
|
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(LLCommon)
|
||||||
include(LLImage)
|
include(LLImage)
|
||||||
include(LLMath)
|
include(LLMath)
|
||||||
include(LLVFS)
|
include(LLFileSystem)
|
||||||
include(LLKDU)
|
include(LLKDU)
|
||||||
include(LLImageJ2COJ)
|
include(LLImageJ2COJ)
|
||||||
include(ZLIB)
|
include(ZLIB)
|
||||||
|
|
@ -18,7 +18,7 @@ include_directories(
|
||||||
${LLCOMMON_INCLUDE_DIRS}
|
${LLCOMMON_INCLUDE_DIRS}
|
||||||
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
|
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
|
||||||
${LLMATH_INCLUDE_DIRS}
|
${LLMATH_INCLUDE_DIRS}
|
||||||
${LLVFS_INCLUDE_DIRS}
|
${LLFILESYSTEM_INCLUDE_DIRS}
|
||||||
${PNG_INCLUDE_DIRS}
|
${PNG_INCLUDE_DIRS}
|
||||||
${ZLIB_INCLUDE_DIRS}
|
${ZLIB_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
@ -69,7 +69,7 @@ else (USE_KDU)
|
||||||
endif (USE_KDU)
|
endif (USE_KDU)
|
||||||
|
|
||||||
target_link_libraries(llimage
|
target_link_libraries(llimage
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${LLCOMMON_LIBRARIES}
|
${LLCOMMON_LIBRARIES}
|
||||||
${JPEG_LIBRARIES}
|
${JPEG_LIBRARIES}
|
||||||
|
|
|
||||||
|
|
@ -2219,20 +2219,11 @@ bool LLImageFormatted::save(const std::string &filename)
|
||||||
return true;
|
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
|
S8 LLImageFormatted::getCodec() const
|
||||||
{
|
{
|
||||||
return mCodec;
|
return mCodec;
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
static void avg4_colors4(const U8* a, const U8* b, const U8* c, const U8* d, U8* dst)
|
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);
|
dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ include(LLCommon)
|
||||||
include(LLCoreHttp)
|
include(LLCoreHttp)
|
||||||
include(LLMath)
|
include(LLMath)
|
||||||
include(LLMessage)
|
include(LLMessage)
|
||||||
include(LLVFS)
|
include(LLFileSystem)
|
||||||
include(LLXML)
|
include(LLXML)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
|
|
@ -81,7 +81,7 @@ if (LL_TESTS)
|
||||||
LL_ADD_PROJECT_UNIT_TESTS(llinventory "${llinventory_TEST_SOURCE_FILES}")
|
LL_ADD_PROJECT_UNIT_TESTS(llinventory "${llinventory_TEST_SOURCE_FILES}")
|
||||||
|
|
||||||
#set(TEST_DEBUG on)
|
#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(inventorymisc "" "${test_libs}")
|
||||||
LL_ADD_INTEGRATION_TEST(llparcel "" "${test_libs}")
|
LL_ADD_INTEGRATION_TEST(llparcel "" "${test_libs}")
|
||||||
endif (LL_TESTS)
|
endif (LL_TESTS)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ include(LLCommon)
|
||||||
include(LLCoreHttp)
|
include(LLCoreHttp)
|
||||||
include(LLMath)
|
include(LLMath)
|
||||||
include(LLMessage)
|
include(LLMessage)
|
||||||
include(LLVFS)
|
include(LLFileSystem)
|
||||||
include(LLAddBuildTest)
|
include(LLAddBuildTest)
|
||||||
include(Python)
|
include(Python)
|
||||||
include(Tut)
|
include(Tut)
|
||||||
|
|
@ -23,7 +23,7 @@ include_directories(
|
||||||
${LLCOREHTTP_INCLUDE_DIRS}
|
${LLCOREHTTP_INCLUDE_DIRS}
|
||||||
${LLMATH_INCLUDE_DIRS}
|
${LLMATH_INCLUDE_DIRS}
|
||||||
${LLMESSAGE_INCLUDE_DIRS}
|
${LLMESSAGE_INCLUDE_DIRS}
|
||||||
${LLVFS_INCLUDE_DIRS}
|
${LLFILESYSTEM_INCLUDE_DIRS}
|
||||||
${JSONCPP_INCLUDE_DIR}
|
${JSONCPP_INCLUDE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -209,7 +209,7 @@ target_link_libraries(
|
||||||
llmessage
|
llmessage
|
||||||
${CURL_LIBRARIES}
|
${CURL_LIBRARIES}
|
||||||
${LLCOMMON_LIBRARIES}
|
${LLCOMMON_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${JSONCPP_LIBRARIES}
|
${JSONCPP_LIBRARIES}
|
||||||
${OPENSSL_LIBRARIES}
|
${OPENSSL_LIBRARIES}
|
||||||
|
|
@ -227,7 +227,7 @@ target_link_libraries(
|
||||||
llmessage
|
llmessage
|
||||||
${CURL_LIBRARIES}
|
${CURL_LIBRARIES}
|
||||||
${LLCOMMON_LIBRARIES}
|
${LLCOMMON_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${JSONCPP_LIBRARIES}
|
${JSONCPP_LIBRARIES}
|
||||||
${OPENSSL_LIBRARIES}
|
${OPENSSL_LIBRARIES}
|
||||||
|
|
@ -257,7 +257,7 @@ if (LL_TESTS)
|
||||||
if (LINUX)
|
if (LINUX)
|
||||||
set(test_libs
|
set(test_libs
|
||||||
${WINDOWS_LIBRARIES}
|
${WINDOWS_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${CURL_LIBRARIES}
|
${CURL_LIBRARIES}
|
||||||
${NGHTTP2_LIBRARIES}
|
${NGHTTP2_LIBRARIES}
|
||||||
|
|
@ -273,7 +273,7 @@ if (LINUX)
|
||||||
else (LINUX)
|
else (LINUX)
|
||||||
set(test_libs
|
set(test_libs
|
||||||
${WINDOWS_LIBRARIES}
|
${WINDOWS_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${CURL_LIBRARIES}
|
${CURL_LIBRARIES}
|
||||||
${NGHTTP2_LIBRARIES}
|
${NGHTTP2_LIBRARIES}
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,7 @@
|
||||||
// this library includes
|
// this library includes
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "llxfermanager.h"
|
#include "llxfermanager.h"
|
||||||
#include "llvfile.h"
|
#include "llfilesystem.h"
|
||||||
#include "llvfs.h"
|
|
||||||
#include "lldbstrings.h"
|
#include "lldbstrings.h"
|
||||||
|
|
||||||
#include "lltransfersourceasset.h"
|
#include "lltransfersourceasset.h"
|
||||||
|
|
@ -202,7 +201,7 @@ LLBaseDownloadRequest::LLBaseDownloadRequest(const LLUUID &uuid, const LLAssetTy
|
||||||
mIsTemp(FALSE),
|
mIsTemp(FALSE),
|
||||||
mIsPriority(FALSE),
|
mIsPriority(FALSE),
|
||||||
mDataSentInFirstPacket(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
|
// 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.
|
// running a message system loop.
|
||||||
|
|
@ -266,7 +265,8 @@ LLSD LLAssetRequest::getFullDetails() const
|
||||||
sd["is_local"] = mIsLocal;
|
sd["is_local"] = mIsLocal;
|
||||||
sd["is_priority"] = mIsPriority;
|
sd["is_priority"] = mIsPriority;
|
||||||
sd["data_send_in_first_packet"] = mDataSentInFirstPacket;
|
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;
|
return sd;
|
||||||
}
|
}
|
||||||
|
|
@ -330,28 +330,23 @@ LLBaseDownloadRequest* LLEstateAssetRequest::getCopy()
|
||||||
// TODO: rework tempfile handling?
|
// 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,
|
LLAssetStorage::LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer)
|
||||||
LLVFS *vfs, LLVFS *static_vfs)
|
|
||||||
{
|
{
|
||||||
_init(msg, xfer, vfs, static_vfs, LLHost());
|
_init(msg, xfer, LLHost());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLAssetStorage::_init(LLMessageSystem *msg,
|
void LLAssetStorage::_init(LLMessageSystem *msg,
|
||||||
LLXferManager *xfer,
|
LLXferManager *xfer,
|
||||||
LLVFS *vfs,
|
|
||||||
LLVFS *static_vfs,
|
|
||||||
const LLHost &upstream_host)
|
const LLHost &upstream_host)
|
||||||
{
|
{
|
||||||
mShutDown = FALSE;
|
mShutDown = FALSE;
|
||||||
mMessageSys = msg;
|
mMessageSys = msg;
|
||||||
mXferManager = xfer;
|
mXferManager = xfer;
|
||||||
mVFS = vfs;
|
|
||||||
mStaticVFS = static_vfs;
|
|
||||||
|
|
||||||
setUpstream(upstream_host);
|
setUpstream(upstream_host);
|
||||||
msg->setHandlerFuncFast(_PREHASH_AssetUploadComplete, processUploadComplete, (void **)this);
|
msg->setHandlerFuncFast(_PREHASH_AssetUploadComplete, processUploadComplete, (void **)this);
|
||||||
|
|
@ -430,7 +425,7 @@ void LLAssetStorage::_cleanupRequests(BOOL all, S32 error)
|
||||||
}
|
}
|
||||||
if (tmp->mDownCallback)
|
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)
|
if (tmp->mInfoCallback)
|
||||||
{
|
{
|
||||||
|
|
@ -443,10 +438,10 @@ void LLAssetStorage::_cleanupRequests(BOOL all, S32 error)
|
||||||
|
|
||||||
BOOL LLAssetStorage::hasLocalAsset(const LLUUID &uuid, const LLAssetType::EType type)
|
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)
|
LLGetAssetCallback callback, void *user_data)
|
||||||
{
|
{
|
||||||
if (user_data)
|
if (user_data)
|
||||||
|
|
@ -455,17 +450,17 @@ bool LLAssetStorage::findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAsse
|
||||||
llassert(callback != NULL);
|
llassert(callback != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL exists = mStaticVFS->getExists(uuid, type);
|
BOOL exists = LLFileSystem::getExists(uuid, type);
|
||||||
if (exists)
|
if (exists)
|
||||||
{
|
{
|
||||||
LLVFile file(mStaticVFS, uuid, type);
|
LLFileSystem file(uuid, type);
|
||||||
U32 size = file.getSize();
|
U32 size = file.getSize();
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
{
|
{
|
||||||
// we've already got the file
|
// we've already got the file
|
||||||
if (callback)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -506,7 +501,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
|
||||||
if (callback)
|
if (callback)
|
||||||
{
|
{
|
||||||
add(sFailedDownloadCount, 1);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -517,20 +512,19 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
|
||||||
if (callback)
|
if (callback)
|
||||||
{
|
{
|
||||||
add(sFailedDownloadCount, 1);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try static VFS first.
|
if (findInCacheAndInvokeCallback(uuid,type,callback,user_data))
|
||||||
if (findInStaticVFSAndInvokeCallback(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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL exists = mVFS->getExists(uuid, type);
|
BOOL exists = LLFileSystem::getExists(uuid, type);
|
||||||
LLVFile file(mVFS, uuid, type);
|
LLFileSystem file(uuid, type);
|
||||||
U32 size = exists ? file.getSize() : 0;
|
U32 size = exists ? file.getSize() : 0;
|
||||||
|
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
|
|
@ -540,10 +534,10 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
|
||||||
// unless there's a weird error
|
// unless there's a weird error
|
||||||
if (callback)
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -616,7 +610,7 @@ void LLAssetStorage::removeAndCallbackPendingDownloads(const LLUUID& file_id, LL
|
||||||
{
|
{
|
||||||
add(sFailedDownloadCount, 1);
|
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;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -670,7 +664,7 @@ void LLAssetStorage::downloadCompleteCallback(
|
||||||
if (LL_ERR_NOERR == result)
|
if (LL_ERR_NOERR == result)
|
||||||
{
|
{
|
||||||
// we might have gotten a zero-size file
|
// 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)
|
if (vfile.getSize() <= 0)
|
||||||
{
|
{
|
||||||
LL_WARNS("AssetStorage") << "downloadCompleteCallback has non-existent or zero-size asset " << callback_id << LL_ENDL;
|
LL_WARNS("AssetStorage") << "downloadCompleteCallback has non-existent or zero-size asset " << callback_id << LL_ENDL;
|
||||||
|
|
@ -719,19 +713,19 @@ void LLAssetStorage::getEstateAsset(
|
||||||
if (callback)
|
if (callback)
|
||||||
{
|
{
|
||||||
add(sFailedDownloadCount, 1);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try static VFS first.
|
// Try static first.
|
||||||
if (findInStaticVFSAndInvokeCallback(asset_id,atype,callback,user_data))
|
if (findInCacheAndInvokeCallback(asset_id,atype,callback,user_data))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL exists = mVFS->getExists(asset_id, atype);
|
BOOL exists = LLFileSystem::getExists(asset_id, atype);
|
||||||
LLVFile file(mVFS, asset_id, atype);
|
LLFileSystem file(asset_id, atype);
|
||||||
U32 size = exists ? file.getSize() : 0;
|
U32 size = exists ? file.getSize() : 0;
|
||||||
|
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
|
|
@ -741,7 +735,7 @@ void LLAssetStorage::getEstateAsset(
|
||||||
// unless there's a weird error
|
// unless there's a weird error
|
||||||
if (callback)
|
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
|
else
|
||||||
|
|
@ -792,7 +786,7 @@ void LLAssetStorage::getEstateAsset(
|
||||||
if (callback)
|
if (callback)
|
||||||
{
|
{
|
||||||
add(sFailedDownloadCount, 1);
|
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)
|
if (LL_ERR_NOERR == result)
|
||||||
{
|
{
|
||||||
// we might have gotten a zero-size file
|
// 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)
|
if (vfile.getSize() <= 0)
|
||||||
{
|
{
|
||||||
LL_WARNS("AssetStorage") << "downloadCompleteCallback has non-existent or zero-size asset!" << LL_ENDL;
|
LL_WARNS("AssetStorage") << "downloadCompleteCallback has non-existent or zero-size asset!" << LL_ENDL;
|
||||||
|
|
@ -838,7 +832,7 @@ void LLAssetStorage::downloadEstateAssetCompleteCallback(
|
||||||
{
|
{
|
||||||
add(sFailedDownloadCount, 1);
|
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(
|
void LLAssetStorage::getInvItemAsset(
|
||||||
|
|
@ -861,14 +855,13 @@ void LLAssetStorage::getInvItemAsset(
|
||||||
|
|
||||||
if(asset_id.notNull())
|
if(asset_id.notNull())
|
||||||
{
|
{
|
||||||
// Try static VFS first.
|
if (findInCacheAndInvokeCallback( asset_id, atype, callback, user_data))
|
||||||
if (findInStaticVFSAndInvokeCallback( asset_id, atype, callback, user_data))
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
exists = mVFS->getExists(asset_id, atype);
|
exists = LLFileSystem::getExists(asset_id, atype);
|
||||||
LLVFile file(mVFS, asset_id, atype);
|
LLFileSystem file(asset_id, atype);
|
||||||
size = exists ? file.getSize() : 0;
|
size = exists ? file.getSize() : 0;
|
||||||
if(exists && size < 1)
|
if(exists && size < 1)
|
||||||
{
|
{
|
||||||
|
|
@ -885,7 +878,7 @@ void LLAssetStorage::getInvItemAsset(
|
||||||
// unless there's a weird error
|
// unless there's a weird error
|
||||||
if (callback)
|
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
|
else
|
||||||
|
|
@ -936,7 +929,7 @@ void LLAssetStorage::getInvItemAsset(
|
||||||
if (callback)
|
if (callback)
|
||||||
{
|
{
|
||||||
add(sFailedDownloadCount, 1);
|
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)
|
if (LL_ERR_NOERR == result)
|
||||||
{
|
{
|
||||||
// we might have gotten a zero-size file
|
// 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)
|
if (vfile.getSize() <= 0)
|
||||||
{
|
{
|
||||||
LL_WARNS("AssetStorage") << "downloadCompleteCallback has non-existent or zero-size asset!" << LL_ENDL;
|
LL_WARNS("AssetStorage") << "downloadCompleteCallback has non-existent or zero-size asset!" << LL_ENDL;
|
||||||
|
|
@ -982,7 +975,7 @@ void LLAssetStorage::downloadInvItemCompleteCallback(
|
||||||
{
|
{
|
||||||
add(sFailedDownloadCount, 1);
|
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)
|
if (req->mDownCallback)
|
||||||
{
|
{
|
||||||
add(sFailedDownloadCount, 1);
|
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)
|
if (req->mInfoCallback)
|
||||||
{
|
{
|
||||||
|
|
@ -1363,8 +1356,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
|
||||||
{
|
{
|
||||||
LLAssetRequest* tmp = *iter++;
|
LLAssetRequest* tmp = *iter++;
|
||||||
|
|
||||||
//void(*const* cbptr)(LLVFS *, const LLUUID &, LLAssetType::EType, void *, S32, LLExtStat)
|
auto cbptr = tmp->mDownCallback.target<void(*)(const LLUUID &, LLAssetType::EType, void *, S32, LLExtStat)>();
|
||||||
auto cbptr = tmp->mDownCallback.target<void(*)(LLVFS *, const LLUUID &, LLAssetType::EType, void *, S32, LLExtStat)>();
|
|
||||||
|
|
||||||
if (type == tmp->getType() &&
|
if (type == tmp->getType() &&
|
||||||
uuid == tmp->getUUID() &&
|
uuid == tmp->getUUID() &&
|
||||||
|
|
@ -1389,8 +1381,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void LLAssetStorage::legacyGetDataCallback(LLVFS *vfs,
|
void LLAssetStorage::legacyGetDataCallback(const LLUUID &uuid,
|
||||||
const LLUUID &uuid,
|
|
||||||
LLAssetType::EType type,
|
LLAssetType::EType type,
|
||||||
void *user_data,
|
void *user_data,
|
||||||
S32 status,
|
S32 status,
|
||||||
|
|
@ -1405,7 +1396,7 @@ void LLAssetStorage::legacyGetDataCallback(LLVFS *vfs,
|
||||||
if ( !status
|
if ( !status
|
||||||
&& !toxic )
|
&& !toxic )
|
||||||
{
|
{
|
||||||
LLVFile file(vfs, uuid, type);
|
LLFileSystem file(uuid, type);
|
||||||
|
|
||||||
std::string uuid_str;
|
std::string uuid_str;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@
|
||||||
class LLMessageSystem;
|
class LLMessageSystem;
|
||||||
class LLXferManager;
|
class LLXferManager;
|
||||||
class LLAssetStorage;
|
class LLAssetStorage;
|
||||||
class LLVFS;
|
|
||||||
class LLSD;
|
class LLSD;
|
||||||
|
|
||||||
// anything that takes longer than this to download will abort.
|
// 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_INSUFFICIENT_PERMISSIONS = -5;
|
||||||
const int LL_ERR_PRICE_MISMATCH = -23018;
|
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
|
// future project would be to convert these to C++ callables (std::function<>) so that
|
||||||
// we can use bind and remove the userData parameter.
|
// 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;
|
typedef std::function<void(const LLUUID &asset_id, void *user_data, S32 status, LLExtStat ext_status)> LLStoreAssetCallback;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -120,7 +119,6 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LLGetAssetCallback mDownCallback;
|
LLGetAssetCallback mDownCallback;
|
||||||
// void(*mDownCallback)(LLVFS*, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat);
|
|
||||||
|
|
||||||
void *mUserData;
|
void *mUserData;
|
||||||
LLHost mHost;
|
LLHost mHost;
|
||||||
|
|
@ -128,7 +126,7 @@ public:
|
||||||
F64Seconds mTime; // Message system time
|
F64Seconds mTime; // Message system time
|
||||||
BOOL mIsPriority;
|
BOOL mIsPriority;
|
||||||
BOOL mDataSentInFirstPacket;
|
BOOL mDataSentInFirstPacket;
|
||||||
BOOL mDataIsInVFS;
|
BOOL mDataIsInCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LLAssetRequest : public LLBaseDownloadRequest
|
class LLAssetRequest : public LLBaseDownloadRequest
|
||||||
|
|
@ -198,9 +196,6 @@ typedef std::map<LLUUID,U64,lluuid_less> toxic_asset_map_t;
|
||||||
class LLAssetStorage
|
class LLAssetStorage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// VFS member is public because static child methods need it :(
|
|
||||||
LLVFS *mVFS;
|
|
||||||
LLVFS *mStaticVFS;
|
|
||||||
typedef ::LLStoreAssetCallback LLStoreAssetCallback;
|
typedef ::LLStoreAssetCallback LLStoreAssetCallback;
|
||||||
typedef ::LLGetAssetCallback LLGetAssetCallback;
|
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
|
toxic_asset_map_t mToxicAssetMap; // Objects in this list are known to cause problems and are not loaded
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
|
LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, const LLHost &upstream_host);
|
||||||
LLVFS *vfs, LLVFS *static_vfs, const LLHost &upstream_host);
|
|
||||||
|
|
||||||
LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
|
LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer);
|
||||||
LLVFS *vfs, LLVFS *static_vfs);
|
|
||||||
virtual ~LLAssetStorage();
|
virtual ~LLAssetStorage();
|
||||||
|
|
||||||
void setUpstream(const LLHost &upstream_host);
|
void setUpstream(const LLHost &upstream_host);
|
||||||
|
|
@ -284,7 +277,7 @@ public:
|
||||||
void markAssetToxic( const LLUUID& uuid );
|
void markAssetToxic( const LLUUID& uuid );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAssetType::EType type,
|
bool findInCacheAndInvokeCallback(const LLUUID& uuid, LLAssetType::EType type,
|
||||||
LLGetAssetCallback callback, void *user_data);
|
LLGetAssetCallback callback, void *user_data);
|
||||||
|
|
||||||
LLSD getPendingDetailsImpl(const request_list_t* requests,
|
LLSD getPendingDetailsImpl(const request_list_t* requests,
|
||||||
|
|
@ -375,7 +368,7 @@ public:
|
||||||
bool user_waiting = false,
|
bool user_waiting = false,
|
||||||
F64Seconds timeout = LL_ASSET_STORAGE_TIMEOUT) = 0;
|
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);
|
static void legacyStoreDataCallback(const LLUUID &uuid, void *user_data, S32 status, LLExtStat ext_status);
|
||||||
|
|
||||||
// add extra methods to handle metadata
|
// 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);
|
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,
|
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,
|
void *user_data, BOOL duplicate,
|
||||||
BOOL is_priority) = 0;
|
BOOL is_priority) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _init(LLMessageSystem *msg,
|
void _init(LLMessageSystem *msg,
|
||||||
LLXferManager *xfer,
|
LLXferManager *xfer,
|
||||||
LLVFS *vfs,
|
|
||||||
LLVFS *static_vfs,
|
|
||||||
const LLHost &upstream_host);
|
const LLHost &upstream_host);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -408,7 +398,7 @@ protected:
|
||||||
MR_FILE_NONEXIST = 3, // Old format store call - source file does not exist
|
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_FILENAME = 4, // Old format store call - source filename is NULL/0-length
|
||||||
MR_NO_UPSTREAM = 5, // Upstream provider is missing
|
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;
|
static class LLMetrics *metric_recipient;
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
#include "llsdserialize.h"
|
#include "llsdserialize.h"
|
||||||
#include "reader.h" // JSON
|
#include "reader.h" // JSON
|
||||||
#include "writer.h" // JSON
|
#include "writer.h" // JSON
|
||||||
#include "llvfile.h"
|
#include "llfilesystem.h"
|
||||||
|
|
||||||
#include "message.h" // for getting the port
|
#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.
|
// scoping for our streams so that they go away when we no longer need them.
|
||||||
{
|
{
|
||||||
LLCore::BufferArrayStream outs(fileData.get());
|
LLCore::BufferArrayStream outs(fileData.get());
|
||||||
LLVFile vfile(gVFS, assetId, assetType, LLVFile::READ);
|
LLFileSystem vfile(assetId, assetType, LLFileSystem::READ);
|
||||||
|
|
||||||
S32 fileSize = vfile.getSize();
|
S32 fileSize = vfile.getSize();
|
||||||
U8* fileBuffer;
|
U8* fileBuffer;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* @file llextendedstatus.h
|
* @file llextendedstatus.h
|
||||||
* @date August 2007
|
* @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$
|
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||||
* Second Life Viewer Source Code
|
* 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
|
// Status provider groups - Top bits indicate which status type it is
|
||||||
// Zero is common status code (next section)
|
// Zero is common status code (next section)
|
||||||
CURL_RESULT = 1UL<<30, // serviced by curl - use 1L if we really implement the below
|
CURL_RESULT = 1UL<<30, // serviced by curl - use 1L if we really implement the below
|
||||||
RES_RESULT = 2UL<<30, // serviced by resident copy
|
RES_RESULT = 2UL<<30, // serviced by resident copy
|
||||||
VFS_RESULT = 3UL<<30, // serviced by vfs
|
CACHE_RESULT = 3UL<<30, // serviced by cache
|
||||||
|
|
||||||
|
|
||||||
// Common Status Codes
|
// Common Status Codes
|
||||||
|
|
@ -54,9 +54,9 @@ enum class LLExtStat: uint32_t
|
||||||
// Memory-Resident status codes:
|
// Memory-Resident status codes:
|
||||||
// None at present
|
// None at present
|
||||||
|
|
||||||
// VFS status codes:
|
// CACHE status codes:
|
||||||
VFS_CACHED = VFS_RESULT | 0x0001,
|
CACHE_CACHED = CACHE_RESULT | 0x0001,
|
||||||
VFS_CORRUPT = VFS_RESULT | 0x0002,
|
CACHE_CORRUPT = CACHE_RESULT | 0x0002,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "lldatapacker.h"
|
#include "lldatapacker.h"
|
||||||
#include "lldir.h"
|
#include "lldir.h"
|
||||||
#include "llvfile.h"
|
#include "llfilesystem.h"
|
||||||
|
|
||||||
LLTransferSourceAsset::LLTransferSourceAsset(const LLUUID &request_id, const F32 priority) :
|
LLTransferSourceAsset::LLTransferSourceAsset(const LLUUID &request_id, const F32 priority) :
|
||||||
LLTransferSource(LLTST_ASSET, request_id, priority),
|
LLTransferSource(LLTST_ASSET, request_id, priority),
|
||||||
|
|
@ -99,7 +99,7 @@ LLTSCode LLTransferSourceAsset::dataCallback(const S32 packet_id,
|
||||||
return LLTS_SKIP;
|
return LLTS_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVFile vf(gAssetStorage->mVFS, mParams.getAssetID(), mParams.getAssetType(), LLVFile::READ);
|
LLFileSystem vf(mParams.getAssetID(), mParams.getAssetType(), LLFileSystem::READ);
|
||||||
|
|
||||||
if (!vf.getSize())
|
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 )
|
void *user_data, S32 result, LLExtStat ext_status )
|
||||||
{
|
{
|
||||||
LLUUID *tidp = ((LLUUID*) user_data);
|
LLUUID *tidp = ((LLUUID*) user_data);
|
||||||
|
|
@ -198,7 +198,7 @@ void LLTransferSourceAsset::responderCallback(LLVFS *vfs, const LLUUID& uuid, LL
|
||||||
if (LL_ERR_NOERR == result)
|
if (LL_ERR_NOERR == result)
|
||||||
{
|
{
|
||||||
// Everything's OK.
|
// Everything's OK.
|
||||||
LLVFile vf(gAssetStorage->mVFS, uuid, type, LLVFile::READ);
|
LLFileSystem vf(uuid, type, LLFileSystem::READ);
|
||||||
tsap->mSize = vf.getSize();
|
tsap->mSize = vf.getSize();
|
||||||
status = LLTS_OK;
|
status = LLTS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
#include "lltransfermanager.h"
|
#include "lltransfermanager.h"
|
||||||
#include "llassetstorage.h"
|
#include "llassetstorage.h"
|
||||||
|
|
||||||
class LLVFile;
|
class LLFileSystem;
|
||||||
|
|
||||||
class LLTransferSourceParamsAsset : public LLTransferSourceParams
|
class LLTransferSourceParamsAsset : public LLTransferSourceParams
|
||||||
{
|
{
|
||||||
|
|
@ -56,7 +56,7 @@ public:
|
||||||
LLTransferSourceAsset(const LLUUID &request_id, const F32 priority);
|
LLTransferSourceAsset(const LLUUID &request_id, const F32 priority);
|
||||||
virtual ~LLTransferSourceAsset();
|
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 );
|
void *user_data, S32 result, LLExtStat ext_status );
|
||||||
protected:
|
protected:
|
||||||
/*virtual*/ void initTransfer();
|
/*virtual*/ void initTransfer();
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
#include "lldatapacker.h"
|
#include "lldatapacker.h"
|
||||||
#include "llerror.h"
|
#include "llerror.h"
|
||||||
#include "llvfile.h"
|
#include "llfilesystem.h"
|
||||||
|
|
||||||
//static
|
//static
|
||||||
void LLTransferTargetVFile::updateQueue(bool shutdown)
|
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() << "LLTransferTargetFile::dataCallback" << LL_ENDL;
|
||||||
//LL_INFOS() << "Packet: " << packet_id << 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)
|
if (mNeedsCreate)
|
||||||
{
|
{
|
||||||
vf.setMaxSize(mSize);
|
|
||||||
mNeedsCreate = FALSE;
|
mNeedsCreate = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -176,7 +175,7 @@ void LLTransferTargetVFile::completionCallback(const LLTSCode status)
|
||||||
case LLTS_DONE:
|
case LLTS_DONE:
|
||||||
if (!mNeedsCreate)
|
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()))
|
if (!file.rename(mParams.getAssetID(), mParams.getAssetType()))
|
||||||
{
|
{
|
||||||
LL_ERRS() << "LLTransferTargetVFile: rename failed" << LL_ENDL;
|
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.
|
// We're aborting this transfer, we don't want to keep this file.
|
||||||
LL_WARNS() << "Aborting vfile transfer for " << mParams.getAssetID() << LL_ENDL;
|
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();
|
vf.remove();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,9 @@
|
||||||
|
|
||||||
#include "lltransfermanager.h"
|
#include "lltransfermanager.h"
|
||||||
#include "llassetstorage.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
|
// Lame, an S32 for now until I figure out the deal with how we want to do
|
||||||
// error codes.
|
// error codes.
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,7 @@
|
||||||
#include "lluuid.h"
|
#include "lluuid.h"
|
||||||
#include "llerror.h"
|
#include "llerror.h"
|
||||||
#include "llmath.h"
|
#include "llmath.h"
|
||||||
#include "llvfile.h"
|
#include "llfilesystem.h"
|
||||||
#include "llvfs.h"
|
|
||||||
#include "lldir.h"
|
#include "lldir.h"
|
||||||
|
|
||||||
// size of chunks read from/written to disk
|
// 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_VFile::LLXfer_VFile ()
|
||||||
: LLXfer(-1)
|
: 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)
|
: 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;
|
mLocalID = local_id;
|
||||||
mType = type;
|
mType = type;
|
||||||
|
|
||||||
|
|
@ -82,14 +79,14 @@ void LLXfer_VFile::cleanup ()
|
||||||
if (mTempID.notNull() &&
|
if (mTempID.notNull() &&
|
||||||
mDeleteTempFile)
|
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();
|
file.remove();
|
||||||
}
|
}
|
||||||
else
|
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;
|
<< ", mRemoteID is " << mRemoteID << LL_ENDL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -103,7 +100,6 @@ void LLXfer_VFile::cleanup ()
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
S32 LLXfer_VFile::initializeRequest(U64 xfer_id,
|
S32 LLXfer_VFile::initializeRequest(U64 xfer_id,
|
||||||
LLVFS* vfs,
|
|
||||||
const LLUUID& local_id,
|
const LLUUID& local_id,
|
||||||
const LLUUID& remote_id,
|
const LLUUID& remote_id,
|
||||||
LLAssetType::EType type,
|
LLAssetType::EType type,
|
||||||
|
|
@ -115,7 +111,6 @@ S32 LLXfer_VFile::initializeRequest(U64 xfer_id,
|
||||||
|
|
||||||
mRemoteHost = remote_host;
|
mRemoteHost = remote_host;
|
||||||
|
|
||||||
mVFS = vfs;
|
|
||||||
mLocalID = local_id;
|
mLocalID = local_id;
|
||||||
mRemoteID = remote_id;
|
mRemoteID = remote_id;
|
||||||
mType = type;
|
mType = type;
|
||||||
|
|
@ -192,13 +187,13 @@ S32 LLXfer_VFile::startSend (U64 xfer_id, const LLHost &remote_host)
|
||||||
|
|
||||||
delete mVFile;
|
delete mVFile;
|
||||||
mVFile = NULL;
|
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)
|
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;
|
<< " has unexpected file size of " << mVFile->getSize() << LL_ENDL;
|
||||||
delete mVFile;
|
delete mVFile;
|
||||||
mVFile = NULL;
|
mVFile = NULL;
|
||||||
|
|
@ -214,7 +209,7 @@ S32 LLXfer_VFile::startSend (U64 xfer_id, const LLHost &remote_host)
|
||||||
}
|
}
|
||||||
else
|
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;
|
retval = LL_ERR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,13 +235,13 @@ S32 LLXfer_VFile::reopenFileHandle()
|
||||||
|
|
||||||
if (mVFile == NULL)
|
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
|
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;
|
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
|
// It would be nice if LLXFers could tell which end of the pipe they were
|
||||||
if (! mVFile)
|
if (! mVFile)
|
||||||
{
|
{
|
||||||
LLVFile file(mVFS, mTempID, mType, LLVFile::APPEND);
|
LLFileSystem file(mTempID, mType, LLFileSystem::APPEND);
|
||||||
file.setMaxSize(xfer_size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -320,7 +314,7 @@ S32 LLXfer_VFile::flush()
|
||||||
S32 retval = 0;
|
S32 retval = 0;
|
||||||
if (mBufferLength)
|
if (mBufferLength)
|
||||||
{
|
{
|
||||||
LLVFile file(mVFS, mTempID, mType, LLVFile::APPEND);
|
LLFileSystem file(mTempID, mType, LLFileSystem::APPEND);
|
||||||
|
|
||||||
file.write((U8*)mBuffer, mBufferLength);
|
file.write((U8*)mBuffer, mBufferLength);
|
||||||
|
|
||||||
|
|
@ -340,22 +334,15 @@ S32 LLXfer_VFile::processEOF()
|
||||||
|
|
||||||
if (!mCallbackResult)
|
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))
|
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
|
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
|
// Rename worked: the original file is gone. Clear mDeleteTempFile
|
||||||
// so we don't attempt to delete the file in cleanup()
|
// so we don't attempt to delete the file in cleanup()
|
||||||
mDeleteTempFile = FALSE;
|
mDeleteTempFile = FALSE;
|
||||||
|
|
@ -363,7 +350,7 @@ S32 LLXfer_VFile::processEOF()
|
||||||
}
|
}
|
||||||
else
|
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 "llxfer.h"
|
||||||
#include "llassetstorage.h"
|
#include "llassetstorage.h"
|
||||||
|
|
||||||
class LLVFS;
|
class LLFileSystem;
|
||||||
class LLVFile;
|
|
||||||
|
|
||||||
class LLXfer_VFile : public LLXfer
|
class LLXfer_VFile : public LLXfer
|
||||||
{
|
{
|
||||||
|
|
@ -41,9 +40,7 @@ class LLXfer_VFile : public LLXfer
|
||||||
LLUUID mTempID;
|
LLUUID mTempID;
|
||||||
LLAssetType::EType mType;
|
LLAssetType::EType mType;
|
||||||
|
|
||||||
LLVFile *mVFile;
|
LLFileSystem *mVFile;
|
||||||
|
|
||||||
LLVFS *mVFS;
|
|
||||||
|
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
|
|
@ -51,14 +48,13 @@ class LLXfer_VFile : public LLXfer
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LLXfer_VFile ();
|
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 ~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 void cleanup();
|
||||||
|
|
||||||
virtual S32 initializeRequest(U64 xfer_id,
|
virtual S32 initializeRequest(U64 xfer_id,
|
||||||
LLVFS *vfs,
|
|
||||||
const LLUUID &local_id,
|
const LLUUID &local_id,
|
||||||
const LLUUID &remote_id,
|
const LLUUID &remote_id,
|
||||||
const LLAssetType::EType type,
|
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();
|
cleanup();
|
||||||
|
|
||||||
|
|
@ -78,8 +78,6 @@ void LLXferManager::init (LLVFS *vfs)
|
||||||
setHardLimitOutgoingXfersPerCircuit(LL_DEFAULT_MAX_HARD_LIMIT_SIMULTANEOUS_XFERS);
|
setHardLimitOutgoingXfersPerCircuit(LL_DEFAULT_MAX_HARD_LIMIT_SIMULTANEOUS_XFERS);
|
||||||
setMaxIncomingXfers(LL_DEFAULT_MAX_REQUEST_FIFO_XFERS);
|
setMaxIncomingXfers(LL_DEFAULT_MAX_REQUEST_FIFO_XFERS);
|
||||||
|
|
||||||
mVFS = vfs;
|
|
||||||
|
|
||||||
// Turn on or off ack throttling
|
// Turn on or off ack throttling
|
||||||
mUseAckThrottling = FALSE;
|
mUseAckThrottling = FALSE;
|
||||||
setAckThrottleBPS(100000);
|
setAckThrottleBPS(100000);
|
||||||
|
|
@ -462,7 +460,7 @@ U64 LLXferManager::requestFile(const std::string& local_filename,
|
||||||
|
|
||||||
void LLXferManager::requestVFile(const LLUUID& local_id,
|
void LLXferManager::requestVFile(const LLUUID& local_id,
|
||||||
const LLUUID& remote_id,
|
const LLUUID& remote_id,
|
||||||
LLAssetType::EType type, LLVFS* vfs,
|
LLAssetType::EType type,
|
||||||
const LLHost& remote_host,
|
const LLHost& remote_host,
|
||||||
void (*callback)(void**,S32,LLExtStat),
|
void (*callback)(void**,S32,LLExtStat),
|
||||||
void** user_data,
|
void** user_data,
|
||||||
|
|
@ -508,7 +506,6 @@ void LLXferManager::requestVFile(const LLUUID& local_id,
|
||||||
|
|
||||||
addToList(xfer_p, mReceiveList, is_priority);
|
addToList(xfer_p, mReceiveList, is_priority);
|
||||||
((LLXfer_VFile *)xfer_p)->initializeRequest(getNextID(),
|
((LLXfer_VFile *)xfer_p)->initializeRequest(getNextID(),
|
||||||
vfs,
|
|
||||||
local_id,
|
local_id,
|
||||||
remote_id,
|
remote_id,
|
||||||
type,
|
type,
|
||||||
|
|
@ -784,33 +781,17 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
|
||||||
LLXfer *xferp;
|
LLXfer *xferp;
|
||||||
|
|
||||||
if (uuid != LLUUID::null)
|
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))
|
if(NULL == LLAssetType::lookup(type))
|
||||||
{
|
{
|
||||||
LL_WARNS("Xfer") << "Invalid type for xfer request: " << uuid << ":"
|
LL_WARNS("Xfer") << "Invalid type for xfer request: " << uuid << ":"
|
||||||
<< type_s16 << " to " << mesgsys->getSender() << LL_ENDL;
|
<< type_s16 << " to " << mesgsys->getSender() << LL_ENDL;
|
||||||
return;
|
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;
|
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)
|
if (xferp)
|
||||||
{
|
{
|
||||||
mSendList.push_front(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;
|
LLXferManager *gXferManager = NULL;
|
||||||
|
|
||||||
|
|
||||||
void start_xfer_manager(LLVFS *vfs)
|
void start_xfer_manager()
|
||||||
{
|
{
|
||||||
gXferManager = new LLXferManager(vfs);
|
gXferManager = new LLXferManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_xfer_manager()
|
void cleanup_xfer_manager()
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@
|
||||||
|
|
||||||
//Forward declaration to avoid circular dependencies
|
//Forward declaration to avoid circular dependencies
|
||||||
class LLXfer;
|
class LLXfer;
|
||||||
class LLVFS;
|
|
||||||
|
|
||||||
#include "llxfer.h"
|
#include "llxfer.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
|
@ -72,9 +71,6 @@ public:
|
||||||
|
|
||||||
class LLXferManager
|
class LLXferManager
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
LLVFS *mVFS;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
S32 mMaxOutgoingXfersPerCircuit;
|
S32 mMaxOutgoingXfersPerCircuit;
|
||||||
S32 mHardLimitOutgoingXfersPerCircuit; // At this limit, kill off the connection
|
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
|
std::multiset<std::string> mExpectedVFileRequests; // files that are authorized to be downloaded on top of
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LLXferManager(LLVFS *vfs);
|
LLXferManager();
|
||||||
virtual ~LLXferManager();
|
virtual ~LLXferManager();
|
||||||
|
|
||||||
virtual void init(LLVFS *vfs);
|
virtual void init();
|
||||||
virtual void cleanup();
|
virtual void cleanup();
|
||||||
|
|
||||||
void setUseAckThrottling(const BOOL use);
|
void setUseAckThrottling(const BOOL use);
|
||||||
|
|
@ -166,7 +162,7 @@ class LLXferManager
|
||||||
// vfile requesting
|
// vfile requesting
|
||||||
// .. to vfile
|
// .. to vfile
|
||||||
virtual void requestVFile(const LLUUID &local_id, const LLUUID& remote_id,
|
virtual void requestVFile(const LLUUID &local_id, const LLUUID& remote_id,
|
||||||
LLAssetType::EType type, LLVFS* vfs,
|
LLAssetType::EType type,
|
||||||
const LLHost& remote_host,
|
const LLHost& remote_host,
|
||||||
void (*callback)(void**,S32,LLExtStat), void** user_data,
|
void (*callback)(void**,S32,LLExtStat), void** user_data,
|
||||||
BOOL is_priority = FALSE);
|
BOOL is_priority = FALSE);
|
||||||
|
|
@ -213,7 +209,7 @@ class LLXferManager
|
||||||
extern LLXferManager* gXferManager;
|
extern LLXferManager* gXferManager;
|
||||||
|
|
||||||
// initialization and garbage collection
|
// initialization and garbage collection
|
||||||
void start_xfer_manager(LLVFS *vfs);
|
void start_xfer_manager();
|
||||||
void cleanup_xfer_manager();
|
void cleanup_xfer_manager();
|
||||||
|
|
||||||
// message system callbacks
|
// message system callbacks
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@
|
||||||
#include "apr_poll.h"
|
#include "apr_poll.h"
|
||||||
|
|
||||||
// linden library headers
|
// linden library headers
|
||||||
|
#include "llapp.h"
|
||||||
#include "indra_constants.h"
|
#include "indra_constants.h"
|
||||||
#include "lldir.h"
|
#include "lldir.h"
|
||||||
#include "llerror.h"
|
#include "llerror.h"
|
||||||
|
|
|
||||||
|
|
@ -774,6 +774,15 @@ void LLPluginClassMedia::loadURI(const std::string &uri)
|
||||||
sendMessage(message);
|
sendMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LLPluginClassMedia::executeJavaScript(const std::string &code)
|
||||||
|
{
|
||||||
|
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "execute_javascript");
|
||||||
|
|
||||||
|
message.setValue("code", code);
|
||||||
|
|
||||||
|
sendMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
const char* LLPluginClassMedia::priorityToString(EPriority priority)
|
const char* LLPluginClassMedia::priorityToString(EPriority priority)
|
||||||
{
|
{
|
||||||
const char* result = "UNKNOWN";
|
const char* result = "UNKNOWN";
|
||||||
|
|
@ -951,6 +960,19 @@ void LLPluginClassMedia::setJavascriptEnabled(const bool enabled)
|
||||||
sendMessage(message);
|
sendMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LLPluginClassMedia::setWebSecurityDisabled(const bool disabled)
|
||||||
|
{
|
||||||
|
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "web_security_disabled");
|
||||||
|
message.setValueBoolean("disabled", disabled);
|
||||||
|
sendMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLPluginClassMedia::setFileAccessFromFileUrlsEnabled(const bool enabled)
|
||||||
|
{
|
||||||
|
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "file_access_from_file_urls");
|
||||||
|
message.setValueBoolean("enabled", enabled);
|
||||||
|
sendMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
void LLPluginClassMedia::enableMediaPluginDebugging( bool enable )
|
void LLPluginClassMedia::enableMediaPluginDebugging( bool enable )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,8 @@ public:
|
||||||
|
|
||||||
void loadURI(const std::string &uri);
|
void loadURI(const std::string &uri);
|
||||||
|
|
||||||
|
void executeJavaScript(const std::string &code);
|
||||||
|
|
||||||
// "Loading" means uninitialized or any state prior to fully running (processing commands)
|
// "Loading" means uninitialized or any state prior to fully running (processing commands)
|
||||||
bool isPluginLoading(void) { return mPlugin?mPlugin->isLoading():false; };
|
bool isPluginLoading(void) { return mPlugin?mPlugin->isLoading():false; };
|
||||||
|
|
||||||
|
|
@ -213,6 +215,8 @@ public:
|
||||||
void setLanguageCode(const std::string &language_code);
|
void setLanguageCode(const std::string &language_code);
|
||||||
void setPluginsEnabled(const bool enabled);
|
void setPluginsEnabled(const bool enabled);
|
||||||
void setJavascriptEnabled(const bool enabled);
|
void setJavascriptEnabled(const bool enabled);
|
||||||
|
void setWebSecurityDisabled(const bool disabled);
|
||||||
|
void setFileAccessFromFileUrlsEnabled(const bool enabled);
|
||||||
void setTarget(const std::string &target);
|
void setTarget(const std::string &target);
|
||||||
|
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include "linden_common.h"
|
#include "linden_common.h"
|
||||||
|
|
||||||
|
#include "llapp.h"
|
||||||
#include "llpluginprocessparent.h"
|
#include "llpluginprocessparent.h"
|
||||||
#include "llpluginmessagepipe.h"
|
#include "llpluginmessagepipe.h"
|
||||||
#include "llpluginmessageclasses.h"
|
#include "llpluginmessageclasses.h"
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,9 @@ include(LLCommon)
|
||||||
include(LLImage)
|
include(LLImage)
|
||||||
include(LLMath)
|
include(LLMath)
|
||||||
include(LLRender)
|
include(LLRender)
|
||||||
include(LLVFS)
|
|
||||||
include(LLWindow)
|
include(LLWindow)
|
||||||
include(LLXML)
|
include(LLXML)
|
||||||
include(LLVFS)
|
include(LLFileSystem)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${FREETYPE_INCLUDE_DIRS}
|
${FREETYPE_INCLUDE_DIRS}
|
||||||
|
|
@ -20,10 +19,9 @@ include_directories(
|
||||||
${LLIMAGE_INCLUDE_DIRS}
|
${LLIMAGE_INCLUDE_DIRS}
|
||||||
${LLMATH_INCLUDE_DIRS}
|
${LLMATH_INCLUDE_DIRS}
|
||||||
${LLRENDER_INCLUDE_DIRS}
|
${LLRENDER_INCLUDE_DIRS}
|
||||||
${LLVFS_INCLUDE_DIRS}
|
${LLFILESYSTEM_INCLUDE_DIRS}
|
||||||
${LLWINDOW_INCLUDE_DIRS}
|
${LLWINDOW_INCLUDE_DIRS}
|
||||||
${LLXML_INCLUDE_DIRS}
|
${LLXML_INCLUDE_DIRS}
|
||||||
${LLVFS_INCLUDE_DIRS}
|
|
||||||
)
|
)
|
||||||
include_directories(SYSTEM
|
include_directories(SYSTEM
|
||||||
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
|
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
|
||||||
|
|
@ -104,9 +102,8 @@ if (BUILD_HEADLESS)
|
||||||
${LLIMAGE_LIBRARIES}
|
${LLIMAGE_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${LLRENDER_HEADLESS_LIBRARIES}
|
${LLRENDER_HEADLESS_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
|
||||||
${LLXML_LIBRARIES}
|
${LLXML_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLWINDOW_HEADLESS_LIBRARIES}
|
${LLWINDOW_HEADLESS_LIBRARIES}
|
||||||
${OPENGL_HEADLESS_LIBRARIES})
|
${OPENGL_HEADLESS_LIBRARIES})
|
||||||
|
|
||||||
|
|
@ -126,9 +123,8 @@ target_link_libraries(llrender
|
||||||
${LLCOMMON_LIBRARIES}
|
${LLCOMMON_LIBRARIES}
|
||||||
${LLIMAGE_LIBRARIES}
|
${LLIMAGE_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLXML_LIBRARIES}
|
${LLXML_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
|
||||||
${LLWINDOW_LIBRARIES}
|
${LLWINDOW_LIBRARIES}
|
||||||
${FREETYPE_LIBRARIES}
|
${FREETYPE_LIBRARIES}
|
||||||
${OPENGL_LIBRARIES})
|
${OPENGL_LIBRARIES})
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ include(LLCoreHttp)
|
||||||
include(LLRender)
|
include(LLRender)
|
||||||
include(LLWindow)
|
include(LLWindow)
|
||||||
include(LLCoreHttp)
|
include(LLCoreHttp)
|
||||||
include(LLVFS)
|
include(LLFileSystem)
|
||||||
include(LLXML)
|
include(LLXML)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
|
|
@ -25,7 +25,7 @@ include_directories(
|
||||||
${LLMESSAGE_INCLUDE_DIRS}
|
${LLMESSAGE_INCLUDE_DIRS}
|
||||||
${LLRENDER_INCLUDE_DIRS}
|
${LLRENDER_INCLUDE_DIRS}
|
||||||
${LLWINDOW_INCLUDE_DIRS}
|
${LLWINDOW_INCLUDE_DIRS}
|
||||||
${LLVFS_INCLUDE_DIRS}
|
${LLFILESYSTEM_INCLUDE_DIRS}
|
||||||
${LLXML_INCLUDE_DIRS}
|
${LLXML_INCLUDE_DIRS}
|
||||||
${LIBS_PREBUILD_DIR}/include/hunspell
|
${LIBS_PREBUILD_DIR}/include/hunspell
|
||||||
)
|
)
|
||||||
|
|
@ -285,7 +285,7 @@ target_link_libraries(llui
|
||||||
${LLINVENTORY_LIBRARIES}
|
${LLINVENTORY_LIBRARIES}
|
||||||
${LLMESSAGE_LIBRARIES}
|
${LLMESSAGE_LIBRARIES}
|
||||||
${LLCOREHTTP_LIBRARIES}
|
${LLCOREHTTP_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES} # ugh, just for LLDir
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLXUIXML_LIBRARIES}
|
${LLXUIXML_LIBRARIES}
|
||||||
${LLXML_LIBRARIES}
|
${LLXML_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@
|
||||||
#include "lldir.h"
|
#include "lldir.h"
|
||||||
#include "llsd.h"
|
#include "llsd.h"
|
||||||
#include "llfile.h"
|
#include "llfile.h"
|
||||||
#include "llvfile.h"
|
|
||||||
#include "lldate.h"
|
#include "lldate.h"
|
||||||
#include "llsdserialize.h"
|
#include "llsdserialize.h"
|
||||||
#include "llkeyboard.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(LLImage)
|
||||||
include(LLMath)
|
include(LLMath)
|
||||||
include(LLRender)
|
include(LLRender)
|
||||||
include(LLVFS)
|
include(LLFileSystem)
|
||||||
include(LLWindow)
|
include(LLWindow)
|
||||||
include(LLXML)
|
include(LLXML)
|
||||||
include(UI)
|
include(UI)
|
||||||
|
|
@ -26,7 +26,7 @@ include_directories(
|
||||||
${LLIMAGE_INCLUDE_DIRS}
|
${LLIMAGE_INCLUDE_DIRS}
|
||||||
${LLMATH_INCLUDE_DIRS}
|
${LLMATH_INCLUDE_DIRS}
|
||||||
${LLRENDER_INCLUDE_DIRS}
|
${LLRENDER_INCLUDE_DIRS}
|
||||||
${LLVFS_INCLUDE_DIRS}
|
${LLFILESYSTEM_INCLUDE_DIRS}
|
||||||
${LLWINDOW_INCLUDE_DIRS}
|
${LLWINDOW_INCLUDE_DIRS}
|
||||||
${LLXML_INCLUDE_DIRS}
|
${LLXML_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
@ -72,7 +72,7 @@ if (LINUX)
|
||||||
${LLIMAGE_LIBRARIES}
|
${LLIMAGE_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${LLRENDER_LIBRARIES}
|
${LLRENDER_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLWINDOW_LIBRARIES}
|
${LLWINDOW_LIBRARIES}
|
||||||
${LLXML_LIBRARIES}
|
${LLXML_LIBRARIES}
|
||||||
${UI_LIBRARIES} # for GTK
|
${UI_LIBRARIES} # for GTK
|
||||||
|
|
@ -95,7 +95,7 @@ if (LINUX)
|
||||||
${LLIMAGE_LIBRARIES}
|
${LLIMAGE_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${LLRENDER_HEADLESS_LIBRARIES}
|
${LLRENDER_HEADLESS_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLWINDOW_HEADLESS_LIBRARIES}
|
${LLWINDOW_HEADLESS_LIBRARIES}
|
||||||
${LLXML_LIBRARIES}
|
${LLXML_LIBRARIES}
|
||||||
fontconfig # For FCInit and other FC* functions.
|
fontconfig # For FCInit and other FC* functions.
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@ project(llxml)
|
||||||
include(00-Common)
|
include(00-Common)
|
||||||
include(LLCommon)
|
include(LLCommon)
|
||||||
include(LLMath)
|
include(LLMath)
|
||||||
include(LLVFS)
|
include(LLFileSystem)
|
||||||
include(LLXML)
|
include(LLXML)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${LLCOMMON_INCLUDE_DIRS}
|
${LLCOMMON_INCLUDE_DIRS}
|
||||||
${LLMATH_INCLUDE_DIRS}
|
${LLMATH_INCLUDE_DIRS}
|
||||||
${LLVFS_INCLUDE_DIRS}
|
${LLFILESYSTEM_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
include_directories(
|
include_directories(
|
||||||
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
|
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
|
||||||
|
|
@ -42,7 +42,7 @@ add_library (llxml ${llxml_SOURCE_FILES})
|
||||||
# Libraries on which this library depends, needed for Linux builds
|
# Libraries on which this library depends, needed for Linux builds
|
||||||
# Sort by high-level to low-level
|
# Sort by high-level to low-level
|
||||||
target_link_libraries( llxml
|
target_link_libraries( llxml
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${LLCOMMON_LIBRARIES}
|
${LLCOMMON_LIBRARIES}
|
||||||
${EXPAT_LIBRARIES}
|
${EXPAT_LIBRARIES}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ private:
|
||||||
void onTooltipCallback(std::string text);
|
void onTooltipCallback(std::string text);
|
||||||
void onLoadStartCallback();
|
void onLoadStartCallback();
|
||||||
void onRequestExitCallback();
|
void onRequestExitCallback();
|
||||||
void onLoadEndCallback(int httpStatusCode);
|
void onLoadEndCallback(int httpStatusCode, std::string url);
|
||||||
void onLoadError(int status, const std::string error_text);
|
void onLoadError(int status, const std::string error_text);
|
||||||
void onAddressChangeCallback(std::string url);
|
void onAddressChangeCallback(std::string url);
|
||||||
void onOpenPopupCallback(std::string url, std::string target);
|
void onOpenPopupCallback(std::string url, std::string target);
|
||||||
|
|
@ -89,6 +89,8 @@ private:
|
||||||
bool mDisableGPU;
|
bool mDisableGPU;
|
||||||
bool mDisableNetworkService;
|
bool mDisableNetworkService;
|
||||||
bool mUseMockKeyChain;
|
bool mUseMockKeyChain;
|
||||||
|
bool mDisableWebSecurity;
|
||||||
|
bool mFileAccessFromFileUrls;
|
||||||
std::string mUserAgentSubtring;
|
std::string mUserAgentSubtring;
|
||||||
std::string mAuthUsername;
|
std::string mAuthUsername;
|
||||||
std::string mAuthPassword;
|
std::string mAuthPassword;
|
||||||
|
|
@ -124,6 +126,8 @@ MediaPluginBase(host_send_func, host_user_data)
|
||||||
mDisableGPU = false;
|
mDisableGPU = false;
|
||||||
mDisableNetworkService = true;
|
mDisableNetworkService = true;
|
||||||
mUseMockKeyChain = true;
|
mUseMockKeyChain = true;
|
||||||
|
mDisableWebSecurity = false;
|
||||||
|
mFileAccessFromFileUrls = false;
|
||||||
mUserAgentSubtring = "";
|
mUserAgentSubtring = "";
|
||||||
mAuthUsername = "";
|
mAuthUsername = "";
|
||||||
mAuthPassword = "";
|
mAuthPassword = "";
|
||||||
|
|
@ -257,13 +261,14 @@ void MediaPluginCEF::onRequestExitCallback()
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
void MediaPluginCEF::onLoadEndCallback(int httpStatusCode)
|
void MediaPluginCEF::onLoadEndCallback(int httpStatusCode, std::string url)
|
||||||
{
|
{
|
||||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete");
|
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete");
|
||||||
//message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed?
|
//message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed?
|
||||||
message.setValueS32("result_code", httpStatusCode);
|
message.setValueS32("result_code", httpStatusCode);
|
||||||
message.setValueBoolean("history_back_available", mCEFLib->canGoBack());
|
message.setValueBoolean("history_back_available", mCEFLib->canGoBack());
|
||||||
message.setValueBoolean("history_forward_available", mCEFLib->canGoForward());
|
message.setValueBoolean("history_forward_available", mCEFLib->canGoForward());
|
||||||
|
message.setValue("uri", url);
|
||||||
sendMessage(message);
|
sendMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -352,14 +357,16 @@ const std::vector<std::string> MediaPluginCEF::onFileDialog(dullahan::EFileDialo
|
||||||
}
|
}
|
||||||
else if (dialog_type == dullahan::FD_SAVE_FILE)
|
else if (dialog_type == dullahan::FD_SAVE_FILE)
|
||||||
{
|
{
|
||||||
|
mPickedFiles.clear();
|
||||||
mAuthOK = false;
|
mAuthOK = false;
|
||||||
|
|
||||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download");
|
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download");
|
||||||
|
message.setValueBoolean("blocking_request", true);
|
||||||
message.setValue("filename", default_file);
|
message.setValue("filename", default_file);
|
||||||
|
|
||||||
sendMessage(message);
|
sendMessage(message);
|
||||||
|
|
||||||
return std::vector<std::string>();
|
return mPickedFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::vector<std::string>();
|
return std::vector<std::string>();
|
||||||
|
|
@ -520,7 +527,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
|
||||||
mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1));
|
mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1));
|
||||||
mCEFLib->setOnTooltipCallback(std::bind(&MediaPluginCEF::onTooltipCallback, this, std::placeholders::_1));
|
mCEFLib->setOnTooltipCallback(std::bind(&MediaPluginCEF::onTooltipCallback, this, std::placeholders::_1));
|
||||||
mCEFLib->setOnLoadStartCallback(std::bind(&MediaPluginCEF::onLoadStartCallback, this));
|
mCEFLib->setOnLoadStartCallback(std::bind(&MediaPluginCEF::onLoadStartCallback, this));
|
||||||
mCEFLib->setOnLoadEndCallback(std::bind(&MediaPluginCEF::onLoadEndCallback, this, std::placeholders::_1));
|
mCEFLib->setOnLoadEndCallback(std::bind(&MediaPluginCEF::onLoadEndCallback, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
mCEFLib->setOnLoadErrorCallback(std::bind(&MediaPluginCEF::onLoadError, this, std::placeholders::_1, std::placeholders::_2));
|
mCEFLib->setOnLoadErrorCallback(std::bind(&MediaPluginCEF::onLoadError, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
mCEFLib->setOnAddressChangeCallback(std::bind(&MediaPluginCEF::onAddressChangeCallback, this, std::placeholders::_1));
|
mCEFLib->setOnAddressChangeCallback(std::bind(&MediaPluginCEF::onAddressChangeCallback, this, std::placeholders::_1));
|
||||||
mCEFLib->setOnOpenPopupCallback(std::bind(&MediaPluginCEF::onOpenPopupCallback, this, std::placeholders::_1, std::placeholders::_2));
|
mCEFLib->setOnOpenPopupCallback(std::bind(&MediaPluginCEF::onOpenPopupCallback, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
|
|
@ -559,6 +566,19 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
|
||||||
settings.disable_network_service = mDisableNetworkService;
|
settings.disable_network_service = mDisableNetworkService;
|
||||||
settings.use_mock_keychain = mUseMockKeyChain;
|
settings.use_mock_keychain = mUseMockKeyChain;
|
||||||
#endif
|
#endif
|
||||||
|
// these were added to facilitate loading images directly into a local
|
||||||
|
// web page for the prototype 360 project in 2017 - something that is
|
||||||
|
// disallowed normally by the browser security model. Now the the source
|
||||||
|
// (cubemap) images are stores as JavaScript, we can avoid opening up
|
||||||
|
// this security hole (it was only set for the 360 floater but still
|
||||||
|
// a concern). Leaving them here, explicitly turn off vs removing
|
||||||
|
// entirely from this source file so that others are aware of them
|
||||||
|
// in the future.
|
||||||
|
settings.disable_web_security = false;
|
||||||
|
settings.file_access_from_file_urls = false;
|
||||||
|
|
||||||
|
settings.flash_enabled = mPluginsEnabled;
|
||||||
|
|
||||||
// This setting applies to all plugins, not just Flash
|
// This setting applies to all plugins, not just Flash
|
||||||
// Regarding, SL-15559 PDF files do not load in CEF v91,
|
// Regarding, SL-15559 PDF files do not load in CEF v91,
|
||||||
// it turns out that on Windows, PDF support is treated
|
// it turns out that on Windows, PDF support is treated
|
||||||
|
|
@ -685,6 +705,11 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
|
||||||
std::string uri = message_in.getValue("uri");
|
std::string uri = message_in.getValue("uri");
|
||||||
mCEFLib->navigate(uri);
|
mCEFLib->navigate(uri);
|
||||||
}
|
}
|
||||||
|
else if (message_name == "execute_javascript")
|
||||||
|
{
|
||||||
|
std::string code = message_in.getValue("code");
|
||||||
|
mCEFLib->executeJavaScript(code);
|
||||||
|
}
|
||||||
else if (message_name == "set_cookie")
|
else if (message_name == "set_cookie")
|
||||||
{
|
{
|
||||||
std::string uri = message_in.getValue("uri");
|
std::string uri = message_in.getValue("uri");
|
||||||
|
|
@ -880,6 +905,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
|
||||||
{
|
{
|
||||||
mDisableGPU = message_in.getValueBoolean("disable");
|
mDisableGPU = message_in.getValueBoolean("disable");
|
||||||
}
|
}
|
||||||
|
else if (message_name == "web_security_disabled")
|
||||||
|
{
|
||||||
|
mDisableWebSecurity = message_in.getValueBoolean("disabled");
|
||||||
|
}
|
||||||
|
else if (message_name == "file_access_from_file_urls")
|
||||||
|
{
|
||||||
|
mFileAccessFromFileUrls = message_in.getValueBoolean("enabled");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
|
else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,13 @@ include(bugsplat)
|
||||||
include(BuildPackagesInfo)
|
include(BuildPackagesInfo)
|
||||||
include(BuildVersion)
|
include(BuildVersion)
|
||||||
include(CMakeCopyIfDifferent)
|
include(CMakeCopyIfDifferent)
|
||||||
|
include(CubemapToEquirectangularJS)
|
||||||
include(DBusGlib)
|
include(DBusGlib)
|
||||||
include(DragDrop)
|
include(DragDrop)
|
||||||
include(EXPAT)
|
include(EXPAT)
|
||||||
include(FMODSTUDIO)
|
include(FMODSTUDIO)
|
||||||
include(Hunspell)
|
include(Hunspell)
|
||||||
|
include(JPEGEncoderBasic)
|
||||||
include(JsonCpp)
|
include(JsonCpp)
|
||||||
include(LLAppearance)
|
include(LLAppearance)
|
||||||
include(LLAudio)
|
include(LLAudio)
|
||||||
|
|
@ -37,7 +39,7 @@ include(LLPlugin)
|
||||||
include(LLPrimitive)
|
include(LLPrimitive)
|
||||||
include(LLRender)
|
include(LLRender)
|
||||||
include(LLUI)
|
include(LLUI)
|
||||||
include(LLVFS)
|
include(LLFileSystem)
|
||||||
include(LLWindow)
|
include(LLWindow)
|
||||||
include(LLXML)
|
include(LLXML)
|
||||||
include(NDOF)
|
include(NDOF)
|
||||||
|
|
@ -47,6 +49,7 @@ include(OpenGL)
|
||||||
include(OpenSSL)
|
include(OpenSSL)
|
||||||
include(PNG)
|
include(PNG)
|
||||||
include(TemplateCheck)
|
include(TemplateCheck)
|
||||||
|
include(ThreeJS)
|
||||||
include(Tracy)
|
include(Tracy)
|
||||||
include(UI)
|
include(UI)
|
||||||
include(UnixInstall)
|
include(UnixInstall)
|
||||||
|
|
@ -83,7 +86,7 @@ include_directories(
|
||||||
${LLPRIMITIVE_INCLUDE_DIRS}
|
${LLPRIMITIVE_INCLUDE_DIRS}
|
||||||
${LLRENDER_INCLUDE_DIRS}
|
${LLRENDER_INCLUDE_DIRS}
|
||||||
${LLUI_INCLUDE_DIRS}
|
${LLUI_INCLUDE_DIRS}
|
||||||
${LLVFS_INCLUDE_DIRS}
|
${LLFILESYSTEM_INCLUDE_DIRS}
|
||||||
${LLWINDOW_INCLUDE_DIRS}
|
${LLWINDOW_INCLUDE_DIRS}
|
||||||
${LLXML_INCLUDE_DIRS}
|
${LLXML_INCLUDE_DIRS}
|
||||||
${LLLOGIN_INCLUDE_DIRS}
|
${LLLOGIN_INCLUDE_DIRS}
|
||||||
|
|
@ -207,6 +210,7 @@ set(viewer_SOURCE_FILES
|
||||||
llfilteredwearablelist.cpp
|
llfilteredwearablelist.cpp
|
||||||
llfirstuse.cpp
|
llfirstuse.cpp
|
||||||
llflexibleobject.cpp
|
llflexibleobject.cpp
|
||||||
|
llfloater360capture.cpp
|
||||||
llfloaterabout.cpp
|
llfloaterabout.cpp
|
||||||
llfloaterbvhpreview.cpp
|
llfloaterbvhpreview.cpp
|
||||||
llfloateraddpaymentmethod.cpp
|
llfloateraddpaymentmethod.cpp
|
||||||
|
|
@ -842,6 +846,7 @@ set(viewer_HEADER_FILES
|
||||||
llfilteredwearablelist.h
|
llfilteredwearablelist.h
|
||||||
llfirstuse.h
|
llfirstuse.h
|
||||||
llflexibleobject.h
|
llflexibleobject.h
|
||||||
|
llfloater360capture.h
|
||||||
llfloaterabout.h
|
llfloaterabout.h
|
||||||
llfloaterbvhpreview.h
|
llfloaterbvhpreview.h
|
||||||
llfloateraddpaymentmethod.h
|
llfloateraddpaymentmethod.h
|
||||||
|
|
@ -2027,7 +2032,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
|
||||||
${LLRENDER_LIBRARIES}
|
${LLRENDER_LIBRARIES}
|
||||||
${FREETYPE_LIBRARIES}
|
${FREETYPE_LIBRARIES}
|
||||||
${LLUI_LIBRARIES}
|
${LLUI_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLWINDOW_LIBRARIES}
|
${LLWINDOW_LIBRARIES}
|
||||||
${LLXML_LIBRARIES}
|
${LLXML_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
|
|
@ -2450,7 +2455,7 @@ if (LL_TESTS)
|
||||||
set(test_libs
|
set(test_libs
|
||||||
${LLMESSAGE_LIBRARIES}
|
${LLMESSAGE_LIBRARIES}
|
||||||
${WINDOWS_LIBRARIES}
|
${WINDOWS_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${LLCOMMON_LIBRARIES}
|
${LLCOMMON_LIBRARIES}
|
||||||
${GOOGLEMOCK_LIBRARIES}
|
${GOOGLEMOCK_LIBRARIES}
|
||||||
|
|
@ -2465,7 +2470,7 @@ if (LL_TESTS)
|
||||||
|
|
||||||
set(test_libs
|
set(test_libs
|
||||||
${WINDOWS_LIBRARIES}
|
${WINDOWS_LIBRARIES}
|
||||||
${LLVFS_LIBRARIES}
|
${LLFILESYSTEM_LIBRARIES}
|
||||||
${LLMATH_LIBRARIES}
|
${LLMATH_LIBRARIES}
|
||||||
${LLCOMMON_LIBRARIES}
|
${LLCOMMON_LIBRARIES}
|
||||||
${LLMESSAGE_LIBRARIES}
|
${LLMESSAGE_LIBRARIES}
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
6.5.1
|
6.5.2
|
||||||
|
|
|
||||||
|
|
@ -276,4 +276,15 @@
|
||||||
is_running_function="Floater.IsOpen"
|
is_running_function="Floater.IsOpen"
|
||||||
is_running_parameters="my_environments"
|
is_running_parameters="my_environments"
|
||||||
/>
|
/>
|
||||||
|
<command name="360capture"
|
||||||
|
available_in_toybox="true"
|
||||||
|
is_flashing_allowed="true"
|
||||||
|
icon="Command_360_Capture_Icon"
|
||||||
|
label_ref="Command_360_Capture_Label"
|
||||||
|
tooltip_ref="Command_360_Capture_Tooltip"
|
||||||
|
execute_function="Floater.ToggleOrBringToFront"
|
||||||
|
execute_parameters="360capture"
|
||||||
|
is_running_function="Floater.IsOpen"
|
||||||
|
is_running_parameters="360capture"
|
||||||
|
/>
|
||||||
</commands>
|
</commands>
|
||||||
|
|
|
||||||
|
|
@ -1351,6 +1351,39 @@
|
||||||
<key>Value</key>
|
<key>Value</key>
|
||||||
<integer>23</integer>
|
<integer>23</integer>
|
||||||
</map>
|
</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>
|
<key>CacheLocation</key>
|
||||||
<map>
|
<map>
|
||||||
<key>Comment</key>
|
<key>Comment</key>
|
||||||
|
|
@ -2066,6 +2099,28 @@
|
||||||
<key>Value</key>
|
<key>Value</key>
|
||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
</map>
|
</map>
|
||||||
|
<key>BrowserFileAccessFromFileUrls</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Allow access to local files via file urls in the embedded browser</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>Boolean</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</map>
|
||||||
|
<key>BrowserPluginsEnabled</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Enable Web plugins in the built-in Web browser?</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>Boolean</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</map>
|
||||||
<key>ChatBarCustomWidth</key>
|
<key>ChatBarCustomWidth</key>
|
||||||
<map>
|
<map>
|
||||||
<key>Comment</key>
|
<key>Comment</key>
|
||||||
|
|
@ -2815,17 +2870,6 @@
|
||||||
<key>Value</key>
|
<key>Value</key>
|
||||||
<integer>-1</integer>
|
<integer>-1</integer>
|
||||||
</map>
|
</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>
|
<key>DebugStatModeTimeDialation</key>
|
||||||
<map>
|
<map>
|
||||||
<key>Comment</key>
|
<key>Comment</key>
|
||||||
|
|
@ -3618,17 +3662,6 @@
|
||||||
<key>Value</key>
|
<key>Value</key>
|
||||||
<integer>4</integer>
|
<integer>4</integer>
|
||||||
</map>
|
</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>
|
<key>DynamicCameraStrength</key>
|
||||||
<map>
|
<map>
|
||||||
<key>Comment</key>
|
<key>Comment</key>
|
||||||
|
|
@ -14134,7 +14167,7 @@
|
||||||
<key>Value</key>
|
<key>Value</key>
|
||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
</map>
|
</map>
|
||||||
<key>RenderDelayVBUpdate</key>
|
<key>RenderDelayVBUpdate</key>
|
||||||
<map>
|
<map>
|
||||||
<key>Comment</key>
|
<key>Comment</key>
|
||||||
<string>Delay vertex buffer updates until just before rendering</string>
|
<string>Delay vertex buffer updates until just before rendering</string>
|
||||||
|
|
@ -14277,28 +14310,6 @@
|
||||||
<key>Value</key>
|
<key>Value</key>
|
||||||
<string/>
|
<string/>
|
||||||
</map>
|
</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>
|
<key>VelocityInterpolate</key>
|
||||||
<map>
|
<map>
|
||||||
<key>Comment</key>
|
<key>Comment</key>
|
||||||
|
|
@ -16675,18 +16686,104 @@
|
||||||
<key>Value</key>
|
<key>Value</key>
|
||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
</map>
|
</map>
|
||||||
<key>UpdateAppWindowTitleBar</key>
|
<key>360CaptureUseInterestListCap</key>
|
||||||
<map>
|
<map>
|
||||||
<key>Comment</key>
|
<key>Comment</key>
|
||||||
<string>Updates the application window title bar with brief information about user/location</string>
|
<string>Flag if set, uses the new InterestList cap to ask the simulator for full content</string>
|
||||||
<key>Persist</key>
|
<key>Persist</key>
|
||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
<key>Type</key>
|
<key>Type</key>
|
||||||
<string>Boolean</string>
|
<string>Boolean</string>
|
||||||
<key>Value</key>
|
<key>Value</key>
|
||||||
<integer>0</integer>
|
<integer>1</integer>
|
||||||
|
</map>
|
||||||
|
<key>360CaptureJPEGEncodeQuality</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Quality value to use in the JPEG encoder (0..100)</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>U32</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>95</integer>
|
||||||
|
</map>
|
||||||
|
<key>360CaptureDebugSaveImage</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Flag if set, saves off each cube map as an image, as well as the JavaScript data URL, for debugging purposes</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>Boolean</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</map>
|
||||||
|
<key>360CaptureOutputImageWidth</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Width of the output 360 equirectangular image</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>U32</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>4096</integer>
|
||||||
|
</map>
|
||||||
|
<key>360CaptureHideAvatars</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Flag if set, removes all the avatars from the 360 snapshot</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>Boolean</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>0</integer>
|
||||||
</map>
|
</map>
|
||||||
|
<key>360CaptureCameraFOV</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Field of view of the WebGL camera that converts the cubemap to an equirectangular image</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>U32</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>75</integer>
|
||||||
|
</map>
|
||||||
|
<key>360CaptureNumRenderPasses</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Number of times to render the scene while taking a snapshot</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>U32</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>3</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>UpdateAppWindowTitleBar</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Updates the application window title bar with brief information about user/location</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>Boolean</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</map>
|
||||||
</map>
|
</map>
|
||||||
</llsd>
|
</llsd>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -2895,7 +2895,7 @@ bool LLAgent::requestGetCapability(const std::string &capName, httpCallback_t cb
|
||||||
{
|
{
|
||||||
std::string url;
|
std::string url;
|
||||||
|
|
||||||
url = getRegion()->getCapability(capName);
|
url = getRegionCapability(capName);
|
||||||
|
|
||||||
if (url.empty())
|
if (url.empty())
|
||||||
{
|
{
|
||||||
|
|
@ -4636,23 +4636,19 @@ void LLAgent::requestAgentUserInfoCoro(std::string capurl)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool im_via_email;
|
|
||||||
bool is_verified_email;
|
|
||||||
std::string email;
|
std::string email;
|
||||||
std::string dir_visibility;
|
std::string dir_visibility;
|
||||||
|
|
||||||
im_via_email = result["im_via_email"].asBoolean();
|
|
||||||
is_verified_email = result["is_verified"].asBoolean();
|
|
||||||
email = result["email"].asString();
|
email = result["email"].asString();
|
||||||
dir_visibility = result["directory_visibility"].asString();
|
dir_visibility = result["directory_visibility"].asString();
|
||||||
|
|
||||||
// TODO: This should probably be changed. I'm not entirely comfortable
|
// TODO: This should probably be changed. I'm not entirely comfortable
|
||||||
// having LLAgent interact directly with the UI in this way.
|
// having LLAgent interact directly with the UI in this way.
|
||||||
LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email, is_verified_email);
|
LLFloaterPreference::updateUserInfo(dir_visibility);
|
||||||
LLFloaterSnapshot::setAgentEmail(email);
|
LLFloaterSnapshot::setAgentEmail(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLAgent::sendAgentUpdateUserInfo(bool im_via_email, const std::string& directory_visibility)
|
void LLAgent::sendAgentUpdateUserInfo(const std::string& directory_visibility)
|
||||||
{
|
{
|
||||||
std::string cap;
|
std::string cap;
|
||||||
|
|
||||||
|
|
@ -4665,16 +4661,16 @@ void LLAgent::sendAgentUpdateUserInfo(bool im_via_email, const std::string& dire
|
||||||
if (!cap.empty())
|
if (!cap.empty())
|
||||||
{
|
{
|
||||||
LLCoros::instance().launch("updateAgentUserInfoCoro",
|
LLCoros::instance().launch("updateAgentUserInfoCoro",
|
||||||
boost::bind(&LLAgent::updateAgentUserInfoCoro, this, cap, im_via_email, directory_visibility));
|
boost::bind(&LLAgent::updateAgentUserInfoCoro, this, cap, directory_visibility));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sendAgentUpdateUserInfoMessage(im_via_email, directory_visibility);
|
sendAgentUpdateUserInfoMessage(directory_visibility);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LLAgent::updateAgentUserInfoCoro(std::string capurl, bool im_via_email, std::string directory_visibility)
|
void LLAgent::updateAgentUserInfoCoro(std::string capurl, std::string directory_visibility)
|
||||||
{
|
{
|
||||||
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
|
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
|
||||||
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
|
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
|
||||||
|
|
@ -4685,8 +4681,8 @@ void LLAgent::updateAgentUserInfoCoro(std::string capurl, bool im_via_email, std
|
||||||
|
|
||||||
httpOpts->setFollowRedirects(true);
|
httpOpts->setFollowRedirects(true);
|
||||||
LLSD body(LLSDMap
|
LLSD body(LLSDMap
|
||||||
("dir_visibility", LLSD::String(directory_visibility))
|
("dir_visibility", LLSD::String(directory_visibility)));
|
||||||
("im_via_email", LLSD::Boolean(im_via_email)));
|
|
||||||
|
|
||||||
LLSD result = httpAdapter->postAndSuspend(httpRequest, capurl, body, httpOpts, httpHeaders);
|
LLSD result = httpAdapter->postAndSuspend(httpRequest, capurl, body, httpOpts, httpHeaders);
|
||||||
|
|
||||||
|
|
@ -4714,14 +4710,13 @@ void LLAgent::sendAgentUserInfoRequestMessage()
|
||||||
sendReliableMessage();
|
sendReliableMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLAgent::sendAgentUpdateUserInfoMessage(bool im_via_email, const std::string& directory_visibility)
|
void LLAgent::sendAgentUpdateUserInfoMessage(const std::string& directory_visibility)
|
||||||
{
|
{
|
||||||
gMessageSystem->newMessageFast(_PREHASH_UpdateUserInfo);
|
gMessageSystem->newMessageFast(_PREHASH_UpdateUserInfo);
|
||||||
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
|
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
|
||||||
gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID());
|
gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID());
|
||||||
gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID());
|
gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID());
|
||||||
gMessageSystem->nextBlockFast(_PREHASH_UserData);
|
gMessageSystem->nextBlockFast(_PREHASH_UserData);
|
||||||
gMessageSystem->addBOOLFast(_PREHASH_IMViaEMail, im_via_email);
|
|
||||||
gMessageSystem->addString("DirectoryVisibility", directory_visibility);
|
gMessageSystem->addString("DirectoryVisibility", directory_visibility);
|
||||||
gAgent.sendReliableMessage();
|
gAgent.sendReliableMessage();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -928,14 +928,14 @@ public:
|
||||||
void sendAgentUserInfoRequest();
|
void sendAgentUserInfoRequest();
|
||||||
|
|
||||||
// IM to Email and Online visibility
|
// IM to Email and Online visibility
|
||||||
void sendAgentUpdateUserInfo(bool im_to_email, const std::string& directory_visibility);
|
void sendAgentUpdateUserInfo(const std::string& directory_visibility);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void requestAgentUserInfoCoro(std::string capurl);
|
void requestAgentUserInfoCoro(std::string capurl);
|
||||||
void updateAgentUserInfoCoro(std::string capurl, bool im_via_email, std::string directory_visibility);
|
void updateAgentUserInfoCoro(std::string capurl, std::string directory_visibility);
|
||||||
// DEPRECATED: may be removed when User Info cap propagates
|
// DEPRECATED: may be removed when User Info cap propagates
|
||||||
void sendAgentUserInfoRequestMessage();
|
void sendAgentUserInfoRequestMessage();
|
||||||
void sendAgentUpdateUserInfoMessage(bool im_via_email, const std::string& directory_visibility);
|
void sendAgentUpdateUserInfoMessage(const std::string& directory_visibility);
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Receive
|
// Receive
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@
|
||||||
#include "lllogininstance.h"
|
#include "lllogininstance.h"
|
||||||
#include "llprogressview.h"
|
#include "llprogressview.h"
|
||||||
#include "llvocache.h"
|
#include "llvocache.h"
|
||||||
|
#include "lldiskcache.h"
|
||||||
#include "llvopartgroup.h"
|
#include "llvopartgroup.h"
|
||||||
#include "llweb.h"
|
#include "llweb.h"
|
||||||
#include "llfloatertexturefetchdebugger.h"
|
#include "llfloatertexturefetchdebugger.h"
|
||||||
|
|
@ -117,8 +118,6 @@
|
||||||
#include "llprimitive.h"
|
#include "llprimitive.h"
|
||||||
#include "llurlaction.h"
|
#include "llurlaction.h"
|
||||||
#include "llurlentry.h"
|
#include "llurlentry.h"
|
||||||
#include "llvfile.h"
|
|
||||||
#include "llvfsthread.h"
|
|
||||||
#include "llvolumemgr.h"
|
#include "llvolumemgr.h"
|
||||||
#include "llxfermanager.h"
|
#include "llxfermanager.h"
|
||||||
#include "llphysicsextensions.h"
|
#include "llphysicsextensions.h"
|
||||||
|
|
@ -343,9 +342,6 @@ bool gUseWireframe = FALSE;
|
||||||
//use for remember deferred mode in wireframe switch
|
//use for remember deferred mode in wireframe switch
|
||||||
bool gInitialDeferredModeForWireframe = FALSE;
|
bool gInitialDeferredModeForWireframe = FALSE;
|
||||||
|
|
||||||
// VFS globals - see llappviewer.h
|
|
||||||
LLVFS* gStaticVFS = NULL;
|
|
||||||
|
|
||||||
LLMemoryInfo gSysMemory;
|
LLMemoryInfo gSysMemory;
|
||||||
U64Bytes gMemoryAllocated(0); // updated in display_stats() in llviewerdisplay.cpp
|
U64Bytes gMemoryAllocated(0); // updated in display_stats() in llviewerdisplay.cpp
|
||||||
|
|
||||||
|
|
@ -402,12 +398,6 @@ void init_default_trans_args()
|
||||||
default_trans_args.insert("create_account_url");
|
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>
|
struct SettingsFile : public LLInitParam::Block<SettingsFile>
|
||||||
{
|
{
|
||||||
Mandatory<std::string> name;
|
Mandatory<std::string> name;
|
||||||
|
|
@ -576,7 +566,6 @@ static void settings_to_globals()
|
||||||
|
|
||||||
static void settings_modify()
|
static void settings_modify()
|
||||||
{
|
{
|
||||||
LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderDeferred");
|
|
||||||
LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
|
LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
|
||||||
LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
|
LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
|
||||||
LLPipeline::sRenderDeferred = LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
|
LLPipeline::sRenderDeferred = LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
|
||||||
|
|
@ -635,6 +624,7 @@ LLAppViewer* LLAppViewer::sInstance = NULL;
|
||||||
LLTextureCache* LLAppViewer::sTextureCache = NULL;
|
LLTextureCache* LLAppViewer::sTextureCache = NULL;
|
||||||
LLImageDecodeThread* LLAppViewer::sImageDecodeThread = NULL;
|
LLImageDecodeThread* LLAppViewer::sImageDecodeThread = NULL;
|
||||||
LLTextureFetch* LLAppViewer::sTextureFetch = NULL;
|
LLTextureFetch* LLAppViewer::sTextureFetch = NULL;
|
||||||
|
LLPurgeDiskCacheThread* LLAppViewer::sPurgeDiskCacheThread = NULL;
|
||||||
|
|
||||||
std::string getRuntime()
|
std::string getRuntime()
|
||||||
{
|
{
|
||||||
|
|
@ -928,10 +918,6 @@ bool LLAppViewer::init()
|
||||||
|
|
||||||
// *Note: this is where gViewerStats used to be created.
|
// *Note: this is where gViewerStats used to be created.
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize the VFS, and gracefully handle initialization errors
|
|
||||||
//
|
|
||||||
|
|
||||||
if (!initCache())
|
if (!initCache())
|
||||||
{
|
{
|
||||||
LL_WARNS("InitInfo") << "Failed to init cache" << LL_ENDL;
|
LL_WARNS("InitInfo") << "Failed to init cache" << LL_ENDL;
|
||||||
|
|
@ -1069,26 +1055,26 @@ bool LLAppViewer::init()
|
||||||
|| mNumSessions % 20 == 0 //periodically remind user to update driver
|
|| mNumSessions % 20 == 0 //periodically remind user to update driver
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedIntelDriver");
|
LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedIntelDriver");
|
||||||
std::string gpu_name = ll_safe_string((const char *)glGetString(GL_RENDERER));
|
std::string gpu_name = ll_safe_string((const char *)glGetString(GL_RENDERER));
|
||||||
LL_INFOS("AppInit") << "Notifying user about obsolete intel driver for " << gpu_name << LL_ENDL;
|
LL_INFOS("AppInit") << "Notifying user about obsolete intel driver for " << gpu_name << LL_ENDL;
|
||||||
details.setArg("[VERSION]", driver);
|
details.setArg("[VERSION]", driver);
|
||||||
details.setArg("[GPUNAME]", gpu_name);
|
details.setArg("[GPUNAME]", gpu_name);
|
||||||
S32 button = OSMessageBox(details.getString(),
|
S32 button = OSMessageBox(details.getString(),
|
||||||
LLStringUtil::null,
|
LLStringUtil::null,
|
||||||
OSMB_YESNO);
|
OSMB_YESNO);
|
||||||
if (OSBTN_YES == button && gViewerWindow)
|
if (OSBTN_YES == button && gViewerWindow)
|
||||||
{
|
|
||||||
std::string url = LLWeb::escapeURL(LLTrans::getString("IntelDriverPage"));
|
|
||||||
if (gViewerWindow->getWindow())
|
|
||||||
{
|
{
|
||||||
gViewerWindow->getWindow()->spawnWebBrowser(url, false);
|
std::string url = LLWeb::escapeURL(LLTrans::getString("IntelDriverPage"));
|
||||||
|
if (gViewerWindow->getWindow())
|
||||||
|
{
|
||||||
|
gViewerWindow->getWindow()->spawnWebBrowser(url, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Obsolete? mExpectedGLVersion is always zero
|
// Obsolete? mExpectedGLVersion is always zero
|
||||||
|
|
@ -1339,7 +1325,6 @@ static LLTrace::BlockTimerStatHandle FTM_TEXTURE_CACHE("Texture Cache");
|
||||||
static LLTrace::BlockTimerStatHandle FTM_DECODE("Image Decode");
|
static LLTrace::BlockTimerStatHandle FTM_DECODE("Image Decode");
|
||||||
static LLTrace::BlockTimerStatHandle FTM_FETCH("Image Fetch");
|
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_LFS("LFS Thread");
|
||||||
static LLTrace::BlockTimerStatHandle FTM_PAUSE_THREADS("Pause Threads");
|
static LLTrace::BlockTimerStatHandle FTM_PAUSE_THREADS("Pause Threads");
|
||||||
static LLTrace::BlockTimerStatHandle FTM_IDLE("Idle");
|
static LLTrace::BlockTimerStatHandle FTM_IDLE("Idle");
|
||||||
|
|
@ -1610,10 +1595,6 @@ bool LLAppViewer::doFrame()
|
||||||
|
|
||||||
work_pending += updateTextureThreads(max_time);
|
work_pending += updateTextureThreads(max_time);
|
||||||
|
|
||||||
{
|
|
||||||
LL_RECORD_BLOCK_TIME(FTM_VFS);
|
|
||||||
io_pending += LLVFSThread::updateClass(1);
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
LL_RECORD_BLOCK_TIME(FTM_LFS);
|
LL_RECORD_BLOCK_TIME(FTM_LFS);
|
||||||
io_pending += LLLFSThread::updateClass(1);
|
io_pending += LLLFSThread::updateClass(1);
|
||||||
|
|
@ -1621,7 +1602,7 @@ bool LLAppViewer::doFrame()
|
||||||
|
|
||||||
if (io_pending > 1000)
|
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 ;
|
total_work_pending += work_pending ;
|
||||||
|
|
@ -1644,7 +1625,6 @@ bool LLAppViewer::doFrame()
|
||||||
if(!total_io_pending) //pause file threads if nothing to process.
|
if(!total_io_pending) //pause file threads if nothing to process.
|
||||||
{
|
{
|
||||||
LL_PROFILE_ZONE_NAMED( "df LLVFSThread" )
|
LL_PROFILE_ZONE_NAMED( "df LLVFSThread" )
|
||||||
LLVFSThread::sLocal->pause();
|
|
||||||
LLLFSThread::sLocal->pause();
|
LLLFSThread::sLocal->pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1712,12 +1692,11 @@ S32 LLAppViewer::updateTextureThreads(F32 max_time)
|
||||||
return work_pending;
|
return work_pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLAppViewer::flushVFSIO()
|
void LLAppViewer::flushLFSIO()
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
S32 pending = LLVFSThread::updateClass(0);
|
S32 pending = LLLFSThread::updateClass(0);
|
||||||
pending += LLLFSThread::updateClass(0);
|
|
||||||
if (!pending)
|
if (!pending)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
|
@ -1734,12 +1713,12 @@ bool LLAppViewer::cleanup()
|
||||||
// we're about to destroy below. Run them first.
|
// we're about to destroy below. Run them first.
|
||||||
mOnCleanup();
|
mOnCleanup();
|
||||||
|
|
||||||
LLAtmosphere::cleanupClass();
|
LLAtmosphere::cleanupClass();
|
||||||
|
|
||||||
//ditch LLVOAvatarSelf instance
|
//ditch LLVOAvatarSelf instance
|
||||||
gAgentAvatarp = NULL;
|
gAgentAvatarp = NULL;
|
||||||
|
|
||||||
LLNotifications::instance().clear();
|
LLNotifications::instance().clear();
|
||||||
|
|
||||||
// workaround for DEV-35406 crash on shutdown
|
// workaround for DEV-35406 crash on shutdown
|
||||||
LLEventPumps::instance().reset();
|
LLEventPumps::instance().reset();
|
||||||
|
|
@ -1776,14 +1755,14 @@ bool LLAppViewer::cleanup()
|
||||||
// to ensure shutdown order
|
// to ensure shutdown order
|
||||||
LLMortician::setZealous(TRUE);
|
LLMortician::setZealous(TRUE);
|
||||||
|
|
||||||
// Give any remaining SLPlugin instances a chance to exit cleanly.
|
// Give any remaining SLPlugin instances a chance to exit cleanly.
|
||||||
LLPluginProcessParent::shutdown();
|
LLPluginProcessParent::shutdown();
|
||||||
|
|
||||||
disconnectViewer();
|
disconnectViewer();
|
||||||
LLViewerCamera::deleteSingleton();
|
LLViewerCamera::deleteSingleton();
|
||||||
|
|
||||||
LL_INFOS() << "Viewer disconnected" << LL_ENDL;
|
LL_INFOS() << "Viewer disconnected" << LL_ENDL;
|
||||||
|
|
||||||
if (gKeyboard)
|
if (gKeyboard)
|
||||||
{
|
{
|
||||||
gKeyboard->resetKeys();
|
gKeyboard->resetKeys();
|
||||||
|
|
@ -1815,7 +1794,7 @@ bool LLAppViewer::cleanup()
|
||||||
|
|
||||||
LLKeyframeDataCache::clear();
|
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...
|
#if 0 // this seems to get us stuck in an infinite loop...
|
||||||
gTransferManager.cleanup();
|
gTransferManager.cleanup();
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1848,15 +1827,15 @@ bool LLAppViewer::cleanup()
|
||||||
|
|
||||||
if (gAudiop)
|
if (gAudiop)
|
||||||
{
|
{
|
||||||
// be sure to stop the internet stream cleanly BEFORE destroying the interface to stop it.
|
// be sure to stop the internet stream cleanly BEFORE destroying the interface to stop it.
|
||||||
gAudiop->stopInternetStream();
|
gAudiop->stopInternetStream();
|
||||||
// shut down the streaming audio sub-subsystem first, in case it relies on not outliving the general audio subsystem.
|
// shut down the streaming audio sub-subsystem first, in case it relies on not outliving the general audio subsystem.
|
||||||
LLStreamingAudioInterface *sai = gAudiop->getStreamingAudioImpl();
|
LLStreamingAudioInterface *sai = gAudiop->getStreamingAudioImpl();
|
||||||
delete sai;
|
delete sai;
|
||||||
gAudiop->setStreamingAudioImpl(NULL);
|
gAudiop->setStreamingAudioImpl(NULL);
|
||||||
|
|
||||||
// shut down the audio subsystem
|
// shut down the audio subsystem
|
||||||
gAudiop->shutdown();
|
gAudiop->shutdown();
|
||||||
|
|
||||||
delete gAudiop;
|
delete gAudiop;
|
||||||
gAudiop = NULL;
|
gAudiop = NULL;
|
||||||
|
|
@ -1882,8 +1861,8 @@ bool LLAppViewer::cleanup()
|
||||||
|
|
||||||
LL_INFOS() << "Cache files removed" << LL_ENDL;
|
LL_INFOS() << "Cache files removed" << LL_ENDL;
|
||||||
|
|
||||||
// Wait for any pending VFS IO
|
// Wait for any pending LFS IO
|
||||||
flushVFSIO();
|
flushLFSIO();
|
||||||
LL_INFOS() << "Shutting down Views" << LL_ENDL;
|
LL_INFOS() << "Shutting down Views" << LL_ENDL;
|
||||||
|
|
||||||
// Destroy the UI
|
// Destroy the UI
|
||||||
|
|
@ -1925,11 +1904,11 @@ bool LLAppViewer::cleanup()
|
||||||
delete gKeyboard;
|
delete gKeyboard;
|
||||||
gKeyboard = NULL;
|
gKeyboard = NULL;
|
||||||
|
|
||||||
if (LLViewerJoystick::instanceExists())
|
if (LLViewerJoystick::instanceExists())
|
||||||
{
|
{
|
||||||
// Turn off Space Navigator and similar devices
|
// Turn off Space Navigator and similar devices
|
||||||
LLViewerJoystick::getInstance()->terminate();
|
LLViewerJoystick::getInstance()->terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
LL_INFOS() << "Cleaning up Objects" << LL_ENDL;
|
LL_INFOS() << "Cleaning up Objects" << LL_ENDL;
|
||||||
|
|
||||||
|
|
@ -1967,25 +1946,16 @@ bool LLAppViewer::cleanup()
|
||||||
SUBSYSTEM_CLEANUP(LLWorldMapView);
|
SUBSYSTEM_CLEANUP(LLWorldMapView);
|
||||||
SUBSYSTEM_CLEANUP(LLFolderViewItem);
|
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;
|
LL_INFOS() << "Saving Data" << LL_ENDL;
|
||||||
|
|
||||||
// Store the time of our current logoff
|
// Store the time of our current logoff
|
||||||
gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
|
gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
|
||||||
|
|
||||||
if (LLEnvironment::instanceExists())
|
if (LLEnvironment::instanceExists())
|
||||||
{
|
{
|
||||||
//Store environment settings if necessary
|
//Store environment settings if necessary
|
||||||
LLEnvironment::getInstance()->saveToSettings();
|
LLEnvironment::getInstance()->saveToSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must do this after all panels have been deleted because panels that have persistent rects
|
// Must do this after all panels have been deleted because panels that have persistent rects
|
||||||
// save their rects on delete.
|
// save their rects on delete.
|
||||||
|
|
@ -2035,7 +2005,7 @@ bool LLAppViewer::cleanup()
|
||||||
LLConversationLog::instance().cache();
|
LLConversationLog::instance().cache();
|
||||||
}
|
}
|
||||||
|
|
||||||
clearSecHandler();
|
clearSecHandler();
|
||||||
|
|
||||||
if (mPurgeCacheOnExit)
|
if (mPurgeCacheOnExit)
|
||||||
{
|
{
|
||||||
|
|
@ -2064,7 +2034,6 @@ bool LLAppViewer::cleanup()
|
||||||
pending += LLAppViewer::getTextureCache()->update(1); // unpauses the worker thread
|
pending += LLAppViewer::getTextureCache()->update(1); // unpauses the worker thread
|
||||||
pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread
|
pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread
|
||||||
pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
|
pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
|
||||||
pending += LLVFSThread::updateClass(0);
|
|
||||||
pending += LLLFSThread::updateClass(0);
|
pending += LLLFSThread::updateClass(0);
|
||||||
F64 idle_time = idleTimer.getElapsedTimeF64();
|
F64 idle_time = idleTimer.getElapsedTimeF64();
|
||||||
if(!pending)
|
if(!pending)
|
||||||
|
|
@ -2078,13 +2047,13 @@ bool LLAppViewer::cleanup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mPurgeUserDataOnExit)
|
if (mPurgeUserDataOnExit)
|
||||||
{
|
{
|
||||||
// Ideally we should not save anything from this session since it is going to be purged now,
|
// Ideally we should not save anything from this session since it is going to be purged now,
|
||||||
// but this is a very 'rare' case (user deleting himself), not worth overcomplicating 'save&cleanup' code
|
// but this is a very 'rare' case (user deleting himself), not worth overcomplicating 'save&cleanup' code
|
||||||
std::string user_path = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter() + LLStartUp::getUserId();
|
std::string user_path = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter() + LLStartUp::getUserId();
|
||||||
gDirUtilp->deleteDirAndContents(user_path);
|
gDirUtilp->deleteDirAndContents(user_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete workers first
|
// Delete workers first
|
||||||
// shotdown all worker threads before deleting them in case of co-dependencies
|
// shotdown all worker threads before deleting them in case of co-dependencies
|
||||||
|
|
@ -2092,6 +2061,7 @@ bool LLAppViewer::cleanup()
|
||||||
sTextureFetch->shutdown();
|
sTextureFetch->shutdown();
|
||||||
sTextureCache->shutdown();
|
sTextureCache->shutdown();
|
||||||
sImageDecodeThread->shutdown();
|
sImageDecodeThread->shutdown();
|
||||||
|
sPurgeDiskCacheThread->shutdown();
|
||||||
|
|
||||||
sTextureFetch->shutDownTextureCacheThread() ;
|
sTextureFetch->shutDownTextureCacheThread() ;
|
||||||
sTextureFetch->shutDownImageDecodeThread() ;
|
sTextureFetch->shutDownImageDecodeThread() ;
|
||||||
|
|
@ -2107,13 +2077,15 @@ bool LLAppViewer::cleanup()
|
||||||
|
|
||||||
//MUST happen AFTER SUBSYSTEM_CLEANUP(LLCurl)
|
//MUST happen AFTER SUBSYSTEM_CLEANUP(LLCurl)
|
||||||
delete sTextureCache;
|
delete sTextureCache;
|
||||||
sTextureCache = NULL;
|
sTextureCache = NULL;
|
||||||
delete sTextureFetch;
|
delete sTextureFetch;
|
||||||
sTextureFetch = NULL;
|
sTextureFetch = NULL;
|
||||||
delete sImageDecodeThread;
|
delete sImageDecodeThread;
|
||||||
sImageDecodeThread = NULL;
|
sImageDecodeThread = NULL;
|
||||||
delete mFastTimerLogThread;
|
delete mFastTimerLogThread;
|
||||||
mFastTimerLogThread = NULL;
|
mFastTimerLogThread = NULL;
|
||||||
|
delete sPurgeDiskCacheThread;
|
||||||
|
sPurgeDiskCacheThread = NULL;
|
||||||
|
|
||||||
if (LLFastTimerView::sAnalyzePerformance)
|
if (LLFastTimerView::sAnalyzePerformance)
|
||||||
{
|
{
|
||||||
|
|
@ -2139,28 +2111,11 @@ bool LLAppViewer::cleanup()
|
||||||
gTextureList.shutdown(); // shutdown again in case a callback added something
|
gTextureList.shutdown(); // shutdown again in case a callback added something
|
||||||
LLUIImageList::getInstance()->cleanUp();
|
LLUIImageList::getInstance()->cleanUp();
|
||||||
|
|
||||||
// This should eventually be done in LLAppViewer
|
|
||||||
SUBSYSTEM_CLEANUP(LLImage);
|
SUBSYSTEM_CLEANUP(LLImage);
|
||||||
SUBSYSTEM_CLEANUP(LLVFSThread);
|
|
||||||
SUBSYSTEM_CLEANUP(LLLFSThread);
|
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;
|
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();
|
gSavedSettings.cleanup();
|
||||||
LLUIColorTable::instance().clear();
|
LLUIColorTable::instance().clear();
|
||||||
|
|
||||||
|
|
@ -2187,7 +2142,7 @@ bool LLAppViewer::cleanup()
|
||||||
// make sure nothing uses applyProxySettings by this point.
|
// make sure nothing uses applyProxySettings by this point.
|
||||||
LL_INFOS() << "Cleaning up LLProxy." << LL_ENDL;
|
LL_INFOS() << "Cleaning up LLProxy." << LL_ENDL;
|
||||||
SUBSYSTEM_CLEANUP(LLProxy);
|
SUBSYSTEM_CLEANUP(LLProxy);
|
||||||
LLCore::LLHttp::cleanup();
|
LLCore::LLHttp::cleanup();
|
||||||
|
|
||||||
ll_close_fail_log();
|
ll_close_fail_log();
|
||||||
|
|
||||||
|
|
@ -2208,7 +2163,7 @@ bool LLAppViewer::cleanup()
|
||||||
// deleteSingleton() methods.
|
// deleteSingleton() methods.
|
||||||
LLSingletonBase::deleteAll();
|
LLSingletonBase::deleteAll();
|
||||||
|
|
||||||
LL_INFOS() << "Goodbye!" << LL_ENDL;
|
LL_INFOS() << "Goodbye!" << LL_ENDL;
|
||||||
|
|
||||||
removeDumpDir();
|
removeDumpDir();
|
||||||
|
|
||||||
|
|
@ -2222,7 +2177,6 @@ bool LLAppViewer::initThreads()
|
||||||
|
|
||||||
LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
|
LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
|
||||||
|
|
||||||
LLVFSThread::initClass(enable_threads && false);
|
|
||||||
LLLFSThread::initClass(enable_threads && false);
|
LLLFSThread::initClass(enable_threads && false);
|
||||||
|
|
||||||
// Image decoding
|
// Image decoding
|
||||||
|
|
@ -2232,6 +2186,7 @@ bool LLAppViewer::initThreads()
|
||||||
sImageDecodeThread,
|
sImageDecodeThread,
|
||||||
enable_threads && true,
|
enable_threads && true,
|
||||||
app_metrics_qa_mode);
|
app_metrics_qa_mode);
|
||||||
|
LLAppViewer::sPurgeDiskCacheThread = new LLPurgeDiskCacheThread();
|
||||||
|
|
||||||
if (LLTrace::BlockTimer::sLog || LLTrace::BlockTimer::sMetricLog)
|
if (LLTrace::BlockTimer::sLog || LLTrace::BlockTimer::sMetricLog)
|
||||||
{
|
{
|
||||||
|
|
@ -2271,14 +2226,14 @@ void errorCallback(LLError::ELevel level, const std::string &error_string)
|
||||||
|
|
||||||
void LLAppViewer::initLoggingAndGetLastDuration()
|
void LLAppViewer::initLoggingAndGetLastDuration()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Set up logging defaults for the viewer
|
// Set up logging defaults for the viewer
|
||||||
//
|
//
|
||||||
LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "")
|
LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "")
|
||||||
,gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")
|
,gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")
|
||||||
);
|
);
|
||||||
LLError::addGenericRecorder(&errorCallback);
|
LLError::addGenericRecorder(&errorCallback);
|
||||||
//LLError::setTimeFunction(getRuntime);
|
//LLError::setTimeFunction(getRuntime);
|
||||||
|
|
||||||
|
|
||||||
if (mSecondInstance)
|
if (mSecondInstance)
|
||||||
|
|
@ -2291,66 +2246,66 @@ void LLAppViewer::initLoggingAndGetLastDuration()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Remove the last ".old" log file.
|
// Remove the last ".old" log file.
|
||||||
std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
|
std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
|
||||||
"SecondLife.old");
|
"SecondLife.old");
|
||||||
LLFile::remove(old_log_file);
|
LLFile::remove(old_log_file);
|
||||||
|
|
||||||
// Get name of the log file
|
// Get name of the log file
|
||||||
std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
|
std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
|
||||||
"SecondLife.log");
|
"SecondLife.log");
|
||||||
/*
|
/*
|
||||||
* Before touching any log files, compute the duration of the last run
|
* Before touching any log files, compute the duration of the last run
|
||||||
* by comparing the ctime of the previous start marker file with the ctime
|
* by comparing the ctime of the previous start marker file with the ctime
|
||||||
* of the last log file.
|
* of the last log file.
|
||||||
*/
|
*/
|
||||||
std::string start_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, START_MARKER_FILE_NAME);
|
std::string start_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, START_MARKER_FILE_NAME);
|
||||||
llstat start_marker_stat;
|
llstat start_marker_stat;
|
||||||
llstat log_file_stat;
|
llstat log_file_stat;
|
||||||
std::ostringstream duration_log_stream; // can't log yet, so save any message for when we can below
|
std::ostringstream duration_log_stream; // can't log yet, so save any message for when we can below
|
||||||
int start_stat_result = LLFile::stat(start_marker_file_name, &start_marker_stat);
|
int start_stat_result = LLFile::stat(start_marker_file_name, &start_marker_stat);
|
||||||
int log_stat_result = LLFile::stat(log_file, &log_file_stat);
|
int log_stat_result = LLFile::stat(log_file, &log_file_stat);
|
||||||
if (0 == start_stat_result && 0 == log_stat_result)
|
if (0 == start_stat_result && 0 == log_stat_result)
|
||||||
{
|
{
|
||||||
int elapsed_seconds = log_file_stat.st_ctime - start_marker_stat.st_ctime;
|
int elapsed_seconds = log_file_stat.st_ctime - start_marker_stat.st_ctime;
|
||||||
// only report a last run time if the last viewer was the same version
|
// only report a last run time if the last viewer was the same version
|
||||||
// because this stat will be counted against this version
|
// because this stat will be counted against this version
|
||||||
if (markerIsSameVersion(start_marker_file_name))
|
if (markerIsSameVersion(start_marker_file_name))
|
||||||
{
|
{
|
||||||
gLastExecDuration = elapsed_seconds;
|
gLastExecDuration = elapsed_seconds;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
duration_log_stream << "start marker from some other version; duration is not reported";
|
duration_log_stream << "start marker from some other version; duration is not reported";
|
||||||
gLastExecDuration = -1;
|
gLastExecDuration = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// at least one of the LLFile::stat calls failed, so we can't compute the run time
|
// at least one of the LLFile::stat calls failed, so we can't compute the run time
|
||||||
duration_log_stream << "duration stat failure; start: " << start_stat_result << " log: " << log_stat_result;
|
duration_log_stream << "duration stat failure; start: " << start_stat_result << " log: " << log_stat_result;
|
||||||
gLastExecDuration = -1; // unknown
|
gLastExecDuration = -1; // unknown
|
||||||
}
|
}
|
||||||
std::string duration_log_msg(duration_log_stream.str());
|
std::string duration_log_msg(duration_log_stream.str());
|
||||||
|
|
||||||
// Create a new start marker file for comparison with log file time for the next run
|
// Create a new start marker file for comparison with log file time for the next run
|
||||||
LLAPRFile start_marker_file;
|
LLAPRFile start_marker_file;
|
||||||
start_marker_file.open(start_marker_file_name, LL_APR_WB);
|
start_marker_file.open(start_marker_file_name, LL_APR_WB);
|
||||||
if (start_marker_file.getFileHandle())
|
if (start_marker_file.getFileHandle())
|
||||||
{
|
{
|
||||||
recordMarkerVersion(start_marker_file);
|
recordMarkerVersion(start_marker_file);
|
||||||
start_marker_file.close();
|
start_marker_file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rename current log file to ".old"
|
// Rename current log file to ".old"
|
||||||
LLFile::rename(log_file, old_log_file);
|
LLFile::rename(log_file, old_log_file);
|
||||||
|
|
||||||
// Set the log file to SecondLife.log
|
// Set the log file to SecondLife.log
|
||||||
LLError::logToFile(log_file);
|
LLError::logToFile(log_file);
|
||||||
if (!duration_log_msg.empty())
|
if (!duration_log_msg.empty())
|
||||||
{
|
{
|
||||||
LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL;
|
LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3266,10 +3221,6 @@ LLSD LLAppViewer::getViewerInfo() const
|
||||||
info["GPU_SHADERS"] = gSavedSettings.getBOOL("RenderDeferred") ? "Enabled" : "Disabled";
|
info["GPU_SHADERS"] = gSavedSettings.getBOOL("RenderDeferred") ? "Enabled" : "Disabled";
|
||||||
info["TEXTURE_MEMORY"] = gSavedSettings.getS32("TextureMemory");
|
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
|
#if LL_DARWIN
|
||||||
info["HIDPI"] = gHiDPISupport;
|
info["HIDPI"] = gHiDPISupport;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -3361,6 +3312,9 @@ LLSD LLAppViewer::getViewerInfo() const
|
||||||
info["SERVER_RELEASE_NOTES_URL"] = mServerReleaseNotesURL;
|
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;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4021,8 +3975,8 @@ void LLAppViewer::removeDumpDir()
|
||||||
//its locking table for us.
|
//its locking table for us.
|
||||||
if (gDirUtilp->dumpDirExists()) // Check if dump dir was created this run
|
if (gDirUtilp->dumpDirExists()) // Check if dump dir was created this run
|
||||||
{
|
{
|
||||||
std::string dump_dir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
|
std::string dump_dir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
|
||||||
gDirUtilp->deleteDirAndContents(dump_dir);
|
gDirUtilp->deleteDirAndContents(dump_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSecondInstance && !isError())
|
if (mSecondInstance && !isError())
|
||||||
|
|
@ -4042,7 +3996,7 @@ void LLAppViewer::forceQuit()
|
||||||
void LLAppViewer::fastQuit(S32 error_code)
|
void LLAppViewer::fastQuit(S32 error_code)
|
||||||
{
|
{
|
||||||
// finish pending transfers
|
// finish pending transfers
|
||||||
flushVFSIO();
|
flushLFSIO();
|
||||||
// let sim know we're logging out
|
// let sim know we're logging out
|
||||||
sendLogoutRequest();
|
sendLogoutRequest();
|
||||||
// flush network buffers by shutting down messaging system
|
// flush network buffers by shutting down messaging system
|
||||||
|
|
@ -4231,44 +4185,14 @@ void LLAppViewer::migrateCacheDirectory()
|
||||||
#endif // LL_WINDOWS || LL_DARWIN
|
#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
|
//static
|
||||||
U32 LLAppViewer::getTextureCacheVersion()
|
U32 LLAppViewer::getTextureCacheVersion()
|
||||||
{
|
{
|
||||||
//viewer texture cache version, change if the texture cache format changes.
|
// Viewer texture cache version, change if the texture cache format changes.
|
||||||
const U32 TEXTURE_CACHE_VERSION = 8;
|
// 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 ;
|
return TEXTURE_CACHE_VERSION ;
|
||||||
}
|
}
|
||||||
|
|
@ -4290,6 +4214,17 @@ bool LLAppViewer::initCache()
|
||||||
LLAppViewer::getTextureCache()->setReadOnly(read_only) ;
|
LLAppViewer::getTextureCache()->setReadOnly(read_only) ;
|
||||||
LLVOCache::initParamSingleton(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;
|
bool texture_cache_mismatch = false;
|
||||||
if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion())
|
if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion())
|
||||||
{
|
{
|
||||||
|
|
@ -4324,6 +4259,7 @@ bool LLAppViewer::initCache()
|
||||||
LL_INFOS("AppCache") << "Cache location changed, cache needs purging" << LL_ENDL;
|
LL_INFOS("AppCache") << "Cache location changed, cache needs purging" << LL_ENDL;
|
||||||
gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"));
|
gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"));
|
||||||
purgeCache(); // purge old cache
|
purgeCache(); // purge old cache
|
||||||
|
gDirUtilp->deleteDirAndContents(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name));
|
||||||
gSavedSettings.setString("CacheLocation", new_cache_location);
|
gSavedSettings.setString("CacheLocation", new_cache_location);
|
||||||
gSavedSettings.setString("CacheLocationTopFolder", gDirUtilp->getBaseFileName(new_cache_location));
|
gSavedSettings.setString("CacheLocationTopFolder", gDirUtilp->getBaseFileName(new_cache_location));
|
||||||
}
|
}
|
||||||
|
|
@ -4336,11 +4272,26 @@ bool LLAppViewer::initCache()
|
||||||
gSavedSettings.setString("CacheLocationTopFolder", "");
|
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)
|
||||||
{
|
{
|
||||||
|
if (mPurgeCache)
|
||||||
|
{
|
||||||
LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
|
LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
|
||||||
purgeCache();
|
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"));
|
LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache"));
|
||||||
|
|
||||||
|
|
@ -4349,172 +4300,18 @@ bool LLAppViewer::initCache()
|
||||||
const S32 MB = 1024 * 1024;
|
const S32 MB = 1024 * 1024;
|
||||||
const S64 MIN_CACHE_SIZE = 256 * MB;
|
const S64 MIN_CACHE_SIZE = 256 * MB;
|
||||||
const S64 MAX_CACHE_SIZE = 9984ll * 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;
|
S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB;
|
||||||
cache_size = llclamp(cache_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE);
|
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;
|
||||||
S64 texture_cache_size = cache_size - vfs_size;
|
|
||||||
|
|
||||||
S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
|
S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
|
||||||
texture_cache_size -= extra;
|
texture_cache_size -= extra;
|
||||||
|
|
||||||
|
|
||||||
LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion());
|
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)
|
void LLAppViewer::addOnIdleCallback(const boost::function<void()>& cb)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
/**
|
/**
|
||||||
|
* @mainpage
|
||||||
* @mainpage
|
* @mainpage
|
||||||
*
|
*
|
||||||
* This is the sources for the Second Life Viewer;
|
* This is the sources for the Second Life Viewer;
|
||||||
|
|
@ -59,6 +60,7 @@ class LLImageDecodeThread;
|
||||||
class LLTextureFetch;
|
class LLTextureFetch;
|
||||||
class LLWatchdogTimeout;
|
class LLWatchdogTimeout;
|
||||||
class LLViewerJoystick;
|
class LLViewerJoystick;
|
||||||
|
class LLPurgeDiskCacheThread;
|
||||||
class LLViewerRegion;
|
class LLViewerRegion;
|
||||||
|
|
||||||
extern LLTrace::BlockTimerStatHandle FTM_FRAME;
|
extern LLTrace::BlockTimerStatHandle FTM_FRAME;
|
||||||
|
|
@ -85,7 +87,7 @@ public:
|
||||||
virtual bool frame(); // Override for application body logic
|
virtual bool frame(); // Override for application body logic
|
||||||
|
|
||||||
// Application control
|
// 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 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 fastQuit(S32 error_code = 0); // Shuts down the viewer immediately after sending a logout message
|
||||||
void requestQuit(); // Request a quit. A kinder, gentler quit.
|
void requestQuit(); // Request a quit. A kinder, gentler quit.
|
||||||
|
|
@ -118,6 +120,7 @@ public:
|
||||||
static LLTextureCache* getTextureCache() { return sTextureCache; }
|
static LLTextureCache* getTextureCache() { return sTextureCache; }
|
||||||
static LLImageDecodeThread* getImageDecodeThread() { return sImageDecodeThread; }
|
static LLImageDecodeThread* getImageDecodeThread() { return sImageDecodeThread; }
|
||||||
static LLTextureFetch* getTextureFetch() { return sTextureFetch; }
|
static LLTextureFetch* getTextureFetch() { return sTextureFetch; }
|
||||||
|
static LLPurgeDiskCacheThread* getPurgeDiskCacheThread() { return sPurgeDiskCacheThread; }
|
||||||
|
|
||||||
static U32 getTextureCacheVersion() ;
|
static U32 getTextureCacheVersion() ;
|
||||||
static U32 getObjectCacheVersion() ;
|
static U32 getObjectCacheVersion() ;
|
||||||
|
|
@ -294,6 +297,7 @@ private:
|
||||||
static LLTextureCache* sTextureCache;
|
static LLTextureCache* sTextureCache;
|
||||||
static LLImageDecodeThread* sImageDecodeThread;
|
static LLImageDecodeThread* sImageDecodeThread;
|
||||||
static LLTextureFetch* sTextureFetch;
|
static LLTextureFetch* sTextureFetch;
|
||||||
|
static LLPurgeDiskCacheThread* sPurgeDiskCacheThread;
|
||||||
|
|
||||||
S32 mNumSessions;
|
S32 mNumSessions;
|
||||||
|
|
||||||
|
|
@ -389,12 +393,6 @@ extern BOOL gRestoreGL;
|
||||||
extern bool gUseWireframe;
|
extern bool gUseWireframe;
|
||||||
extern bool gInitialDeferredModeForWireframe;
|
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 LLMemoryInfo gSysMemory;
|
||||||
extern U64Bytes gMemoryAllocated;
|
extern U64Bytes gMemoryAllocated;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -509,7 +509,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
|
// Only defined in newer SDKs than we currently use
|
||||||
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||||
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 4
|
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 4
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue