Ansariel 2021-07-21 14:13:23 +02:00
commit 2253723705
656 changed files with 9953 additions and 2435 deletions

2
.gitignore vendored
View File

@ -8,6 +8,7 @@
*.rej
*.swp
*.tar.bz2
*.code-workspace
*~
# Specific paths and/or names
@ -108,3 +109,4 @@ my_autobuild.xml
compile_commands.json
# ignore tracy for now
indra/tracy
firestorm.code-workspace

0
BuildParams Executable file → Normal file
View File

View File

@ -994,11 +994,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>c96fbccf3db01230832d8795318ee627</string>
<string>ab6f79c425524500d638807a3aee0115</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>file:///opt/firestorm/fmodstudio-2.01.09-darwin-211252249.tar.bz2</string>
<string>file:///opt/firestorm/fmodstudio-2.02.01-darwin-211941804.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@ -1008,11 +1008,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>65d60415962cf65918c4fabe379ad43a</string>
<string>729a2844a0de06d454f8de47d3a9cb10</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>file:///opt/firestorm/fmodstudio-2.01.09-linux64-211101316.tar.bz2</string>
<string>file:///opt/firestorm/fmodstudio-2.02.01-linux64-211941750.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>
@ -1022,11 +1022,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>215de14980a03774795de8cde24f1ad5</string>
<string>d8139acbaf2961a466244f39989f2b5b</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>file:///c:/cygwin/opt/firestorm/fmodstudio-2.01.09-windows-211090925.tar.bz2</string>
<string>file:///c:/cygwin/opt/firestorm/fmodstudio-2.02.01-windows-211941202.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -1036,18 +1036,18 @@
<key>archive</key>
<map>
<key>hash</key>
<string>a55f9ae859a5a60285f0c6c764729194</string>
<string>4704da8c560610e7c5329cdc05c2fec3</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>file:///c:/cygwin/opt/firestorm/fmodstudio-2.01.09-windows64-211090927.tar.bz2</string>
<string>file:///c:/cygwin/opt/firestorm/fmodstudio-2.02.01-windows64-211941203.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>2.01.09</string>
<string>2.02.01</string>
</map>
<key>fontconfig</key>
<map>
@ -1932,9 +1932,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>8d0ad384de8fbbc9083cac20258fcb0c</string>
<string>3b8b0f54c851f136e2a92e1c6ba724a5</string>
<key>url</key>
<string>file:///opt/firestorm/kdu-8.1-darwin64-210931415.tar.bz2</string>
<string>file:///opt/firestorm/kdu-8.1-darwin64-211970151.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -2405,18 +2405,18 @@
<key>archive</key>
<map>
<key>hash</key>
<string>40a87f5d505a141b2ec79513a6197c35</string>
<string>0a6349b11c8e9d34f0c80b8081736e75</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76516/728250/llca-202102021657.555615-common-555615.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/79438/751815/llca-202104010215.557744-common-557744.tar.bz2</string>
</map>
<key>name</key>
<string>common</string>
</map>
</map>
<key>version</key>
<string>202102021657.555615</string>
<string>202104010215.557744</string>
</map>
<key>llphysicsextensions_source</key>
<map>
@ -2539,9 +2539,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>2aa4ec0d72bbe4b755730f1bf92b39e7</string>
<string>ba49274838d4c6bbd612db969b04e607</string>
<key>url</key>
<string>file:///opt/firestorm/llphysicsextensions_tpv-1.0.542327-darwin64-542327.tar.bz2</string>
<string>file:///opt/firestorm/llphysicsextensions_tpv-1.0.561414-darwin64-561414.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -2563,9 +2563,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>ad9aba5e2c43a37b6530a0d2de64df1c</string>
<string>30de712d424f179d89dd00c01ded7257</string>
<key>url</key>
<string>file:///c:/cygwin/opt/firestorm/llphysicsextensions_tpv-1.0.542327-windows-542327.tar.bz2</string>
<string>file:///c:/cygwin/opt/firestorm/llphysicsextensions_tpv-1.0.561414-windows-561414.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -2575,16 +2575,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>46689ff1442a8eccac3a7f3258308e1e</string>
<string>abac12c4a12441704fa8884f1ca043d8</string>
<key>url</key>
<string>file:///c:/cygwin/opt/firestorm/llphysicsextensions_tpv-1.0.542327-windows64-542327.tar.bz2</string>
<string>file:///c:/cygwin/opt/firestorm/llphysicsextensions_tpv-1.0.561414-windows64-561414.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
</map>
<key>version</key>
<string>1.0.542327</string>
<string>1.0.561414</string>
</map>
<key>mesa</key>
<map>

View File

@ -129,11 +129,6 @@ pre_build()
then # show that we're doing this, just not the contents
echo source "$bugsplat_sh"
source "$bugsplat_sh"
# important: we test this and use its value in [grand-]child processes
if [ -n "${BUGSPLAT_DB:-}" ]
then echo export BUGSPLAT_DB
export BUGSPLAT_DB
fi
fi
set -x
@ -426,6 +421,15 @@ then
fi
fi
# Some of the uploads takes a long time to finish in the codeticket backend,
# causing the next codeticket upload attempt to fail.
# Inserting this after each potentially large upload may prevent those errors.
# JJ is making changes to Codeticket that we hope will eliminate this failure, then this can be removed
wait_for_codeticket()
{
sleep $(( 60 * 6 ))
}
# check status and upload results to S3
if $succeeded
then
@ -442,6 +446,7 @@ then
# Upload base package.
python_cmd "$helpers/codeticket.py" addoutput Installer "$package" \
|| fatal "Upload of installer failed"
wait_for_codeticket
# Upload additional packages.
for package_id in $additional_packages
@ -451,6 +456,7 @@ then
then
python_cmd "$helpers/codeticket.py" addoutput "Installer $package_id" "$package" \
|| fatal "Upload of installer $package_id failed"
wait_for_codeticket
else
record_failure "Failed to find additional package for '$package_id'."
fi
@ -464,6 +470,7 @@ then
# Upload crash reporter file
python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$VIEWER_SYMBOL_FILE" \
|| fatal "Upload of symbolfile failed"
wait_for_codeticket
fi
# Upload the llphysicsextensions_tpv package, if one was produced
@ -471,6 +478,9 @@ then
if [ -r "$build_dir/llphysicsextensions_package" ]
then
llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package)
# This next upload is a frequent failure; see if giving the last one some time helps
# JJ is making changes to Codeticket that we hope will eliminate this failure soon
sleep 300
python_cmd "$helpers/codeticket.py" addoutput "Physics Extensions Package" "$llphysicsextensions_package" --private \
|| fatal "Upload of physics extensions package failed"
fi
@ -483,6 +493,7 @@ then
begin_section "Upload Extension $extension"
. $extension
[ $? -eq 0 ] || fatal "Upload of extension $extension failed"
wait_for_codeticket
end_section "Upload Extension $extension"
done
fi
@ -492,7 +503,6 @@ then
record_event "skipping upload of installer"
fi
else
record_event "skipping upload of installer due to failed build"
fi

View File

@ -228,6 +228,7 @@ Ansariel Hiller
SL-13364
SL-13858
SL-13697
SL-13395
SL-3136
Aralara Rajal
Arare Chantilly
@ -267,9 +268,10 @@ Benjamin Bigdipper
Beq Janus
BUG-227094
SL-10288
SL-11300
SL-13583
SL-14766
SL-11300
SL-14927
Beth Walcher
Bezilon Kasei
Biancaluce Robbiani

View File

@ -13,6 +13,7 @@ project(${ROOT_PROJECT_NAME})
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(Variables)
include(bugsplat)
include(BuildVersion)
set(LEGACY_STDIO_LIBS)
@ -108,7 +109,10 @@ endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
add_custom_target(viewer)
if (NOT USE_BUGSPLAT)
add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
endif (NOT USE_BUGSPLAT)
add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
add_subdirectory(${LIBS_OPEN_PREFIX}llui)
add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components)
@ -124,31 +128,18 @@ add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)
endif (ENABLE_MEDIA_PLUGINS)
if (LINUX)
add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
if (INSTALL_PROPRIETARY)
include(LLAppearanceUtility)
add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR})
endif (INSTALL_PROPRIETARY)
#<FS:TS> Huh? Where'd that target come from?
#add_dependencies(viewer linux-crash-logger-strip-target)
add_dependencies(viewer linux-crash-logger)
elseif (DARWIN)
add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
add_dependencies(viewer mac-crash-logger)
elseif (WINDOWS)
add_subdirectory(${VIEWER_PREFIX}win_crash_logger)
# cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
if (EXISTS ${VIEWER_DIR}win_setup)
add_subdirectory(${VIEWER_DIR}win_setup)
endif (EXISTS ${VIEWER_DIR}win_setup)
# add_dependencies(viewer windows-setup windows-crash-logger)
add_dependencies(viewer windows-crash-logger)
endif (LINUX)
add_subdirectory(${VIEWER_PREFIX}newview)
add_dependencies(viewer firestorm-bin)
add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL)
if (WINDOWS)
# cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
if (EXISTS ${VIEWER_DIR}win_setup)
add_subdirectory(${VIEWER_DIR}win_setup)
endif (EXISTS ${VIEWER_DIR}win_setup)
endif (WINDOWS)
# sets the 'startup project' for debugging from visual studio.
set_property(
@ -156,6 +147,33 @@ set_property(
PROPERTY VS_STARTUP_PROJECT firestorm-bin
)
if (USE_BUGSPLAT)
if (BUGSPLAT_DB)
message(STATUS "Building with BugSplat; database '${BUGSPLAT_DB}'")
else (BUGSPLAT_DB)
message(WARNING "Building with BugSplat, but no database name set (BUGSPLAT_DB)")
endif (BUGSPLAT_DB)
else (USE_BUGSPLAT)
message(STATUS "Not building with BugSplat")
if (LINUX)
add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
#<FS:TS> Huh? Where'd that target come from?
#add_dependencies(viewer linux-crash-logger-strip-target)
elseif (DARWIN)
add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
add_dependencies(viewer mac-crash-logger)
elseif (WINDOWS)
add_subdirectory(${VIEWER_PREFIX}win_crash_logger)
# add_dependencies(viewer windows-setup windows-crash-logger)
add_dependencies(viewer windows-crash-logger)
endif (LINUX)
endif (USE_BUGSPLAT)
add_subdirectory(${VIEWER_PREFIX}newview)
add_dependencies(viewer firestorm-bin)
add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL)
if (LL_TESTS)
# Define after the custom targets are created so
# individual apps can add themselves as dependencies

View File

@ -72,7 +72,7 @@ if(WINDOWS)
# Filenames are different for 32/64 bit BugSplat file and we don't
# have any control over them so need to branch.
if (BUGSPLAT_DB)
if (USE_BUGSPLAT)
if(ADDRESS_SIZE EQUAL 32)
set(release_files ${release_files} BugSplat.dll)
set(release_files ${release_files} BugSplatRc.dll)
@ -82,7 +82,7 @@ if(WINDOWS)
set(release_files ${release_files} BugSplatRc64.dll)
set(release_files ${release_files} BsSndRpt64.exe)
endif(ADDRESS_SIZE EQUAL 32)
endif (BUGSPLAT_DB)
endif (USE_BUGSPLAT)
set(release_files ${release_files} growl++.dll growl.dll )
if (FMODSTUDIO)

View File

@ -6,6 +6,7 @@ include(LLTestCommand)
#include(GoogleMock)
# </FS:ND>
include(bugsplat)
include(Tut)
#*****************************************************************************
@ -92,6 +93,12 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
IF(LL_TEST_VERBOSE)
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}")
ENDIF(LL_TEST_VERBOSE)
if (USE_BUGSPLAT)
SET_PROPERTY(SOURCE ${${name}_test_SOURCE_FILES}
APPEND PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
endif (USE_BUGSPLAT)
# Headers
GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES)
SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES})
@ -229,6 +236,11 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}")
endif(USESYSTEMLIBS)
if (USE_BUGSPLAT)
SET_PROPERTY(SOURCE ${source_files}
APPEND PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
endif (USE_BUGSPLAT)
# The following was copied to llcorehttp/CMakeLists.txt's texture_load target.
# Any changes made here should be replicated there.
if (WINDOWS)

View File

@ -34,7 +34,6 @@ set(LL_TESTS OFF CACHE BOOL "Build and run unit and integration tests (disable f
set(INCREMENTAL_LINK OFF CACHE BOOL "Use incremental linking on win32 builds (enable for faster links on some machines)")
set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism")
set(VIEWER_SYMBOL_FILE "" CACHE STRING "Name of tarball into which to place symbol files")
set(BUGSPLAT_DB "" CACHE STRING "BugSplat database name, if BugSplat crash reporting is desired")
if(LIBS_CLOSED_DIR)
file(TO_CMAKE_PATH "${LIBS_CLOSED_DIR}" LIBS_CLOSED_DIR)

View File

@ -1,27 +1,38 @@
# BugSplat is engaged by setting BUGSPLAT_DB to the target BugSplat database
# name.
if (BUGSPLAT_DB)
if (USESYSTEMLIBS)
message(STATUS "Looking for system BugSplat")
set(BUGSPLAT_FIND_QUIETLY ON)
set(BUGSPLAT_FIND_REQUIRED ON)
include(FindBUGSPLAT)
else (USESYSTEMLIBS)
message(STATUS "Engaging autobuild BugSplat")
include(Prebuilt)
use_prebuilt_binary(bugsplat)
if (WINDOWS)
set(BUGSPLAT_LIBRARIES
${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib
)
elseif (DARWIN)
find_library(BUGSPLAT_LIBRARIES BugsplatMac
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
message(FATAL_ERROR "Bugsplat for OSX not fully implemented, please adapt llappdelegate-objc.mm to honor options of sending user name and settings.xml.")
else (WINDOWS)
message(FATAL_ERROR "Bugsplat for Linux not implemented.")
if (INSTALL_PROPRIETARY)
# Note that viewer_manifest.py makes decision based on BUGSPLAT_DB and not USE_BUGSPLAT
if (BUGSPLAT_DB)
set(USE_BUGSPLAT ON CACHE BOOL "Use the BugSplat crash reporting system")
else (BUGSPLAT_DB)
set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system")
endif (BUGSPLAT_DB)
else (INSTALL_PROPRIETARY)
set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system")
endif (INSTALL_PROPRIETARY)
if (USE_BUGSPLAT)
if (NOT USESYSTEMLIBS)
include(Prebuilt)
use_prebuilt_binary(bugsplat)
if (WINDOWS)
set(BUGSPLAT_LIBRARIES
${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib
)
elseif (DARWIN)
find_library(BUGSPLAT_LIBRARIES BugsplatMac REQUIRED
NO_DEFAULT_PATH PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
message("Bugsplat for OSX not fully implemented, please adapt llappdelegate-objc.mm to honor options of sending user name and settings.xml.")
else (WINDOWS)
message(FATAL_ERROR "BugSplat is not supported; add -DUSE_BUGSPLAT=OFF")
endif (WINDOWS)
else (NOT USESYSTEMLIBS)
set(BUGSPLAT_FIND_QUIETLY ON)
set(BUGSPLAT_FIND_REQUIRED ON)
include(FindBUGSPLAT)
endif (NOT USESYSTEMLIBS)
set(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name")
endif (WINDOWS)
set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat)
endif (USESYSTEMLIBS)
endif (BUGSPLAT_DB)
set(BUGSPLAT_DEFINE "LL_BUGSPLAT")
endif (USE_BUGSPLAT)

View File

@ -0,0 +1,3 @@
This component is no longer used in Linden Lab builds.
Change requests to support continued use by open source
builds are welcome.

View File

@ -4,6 +4,7 @@ project(llcommon)
include(00-Common)
include(LLCommon)
include(bugsplat)
include(Linking)
include(Boost)
include(LLSharedLibs)
@ -291,10 +292,10 @@ list(APPEND llcommon_HEADER_FILES "tea.h" )
set_source_files_properties(${llcommon_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
if (BUGSPLAT_DB)
set_source_files_properties(llapp.cpp
PROPERTIES COMPILE_DEFINITIONS "LL_BUGSPLAT")
endif (BUGSPLAT_DB)
if (USE_BUGSPLAT)
set_source_files_properties(${llcommon_SOURCE_FILES}
PROPERTIES COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
endif (USE_BUGSPLAT)
list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})

View File

@ -531,7 +531,12 @@ void LLApp::setupErrorHandling(bool second_instance)
#endif // LL_LINUX
#endif // ! LL_WINDOWS
#ifdef LL_BUGSPLAT
// do not start our own error thread
#else // ! LL_BUGSPLAT
startErrorThread();
#endif
}
void LLApp::startErrorThread()
@ -811,7 +816,9 @@ void setup_signals()
act.sa_flags = SA_SIGINFO;
// Synchronous signals
# ifndef LL_BUGSPLAT
sigaction(SIGABRT, &act, NULL);
# endif
sigaction(SIGALRM, &act, NULL);
sigaction(SIGBUS, &act, NULL);
sigaction(SIGFPE, &act, NULL);
@ -848,7 +855,9 @@ void clear_signals()
act.sa_flags = SA_SIGINFO;
// Synchronous signals
# ifndef LL_BUGSPLAT
sigaction(SIGABRT, &act, NULL);
# endif
sigaction(SIGALRM, &act, NULL);
sigaction(SIGBUS, &act, NULL);
sigaction(SIGFPE, &act, NULL);
@ -901,6 +910,7 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
return;
case SIGABRT:
// Note that this handler is not set for SIGABRT when using Bugsplat
// Abort just results in termination of the app, no funky error handling.
if (LLApp::sLogInSignal)
{

View File

@ -259,6 +259,10 @@ public:
*/
LLRunner& getRunner() { return mRunner; }
#ifdef LL_WINDOWS
virtual void reportCrashToBugsplat(void* pExcepInfo /*EXCEPTION_POINTERS*/) { }
#endif
public:
typedef std::map<std::string, std::string> string_map;
string_map mOptionMap; // Contains all command-line options and arguments in a map

View File

@ -56,6 +56,10 @@
#include "stringize.h"
#include "llexception.h"
#if LL_WINDOWS
#include <excpt.h>
#endif
// static
LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller)
{
@ -248,29 +252,58 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
#if LL_WINDOWS
void LLCoros::winlevel(const callable_t& callable)
static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop, const std::string& name)
{
// C++ exceptions were logged in toplevelTryWrapper, but not SEH
// log SEH exceptions here, to make sure it gets into bugsplat's
// report and because __try won't allow std::string operations
if (code != STATUS_MSC_EXCEPTION)
{
LL_WARNS() << "SEH crash in " << name << ", code: " << code << LL_ENDL;
}
// Handle bugsplat here, since GetExceptionInformation() can only be
// called from within filter for __except(filter), not from __except's {}
// Bugsplat should get all exceptions, C++ and SEH
LLApp::instance()->reportCrashToBugsplat(exception_infop);
// Only convert non C++ exceptions.
if (code == STATUS_MSC_EXCEPTION)
{
// C++ exception, go on
return EXCEPTION_CONTINUE_SEARCH;
}
else
{
// handle it
return EXCEPTION_EXECUTE_HANDLER;
}
}
void LLCoros::winlevel(const std::string& name, const callable_t& callable)
{
__try
{
callable();
toplevelTryWrapper(name, callable);
}
__except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation()))
__except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name))
{
// convert to C++ styled exception
// convert to C++ styled exception for handlers other than bugsplat
// Note: it might be better to use _se_set_translator
// if you want exception to inherit full callstack
char integer_string[32];
sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
//
// in case of bugsplat this will get to exceptionTerminateHandler and
// looks like fiber will terminate application after that
char integer_string[512];
sprintf(integer_string, "SEH crash in %s, code: %lu\n", name.c_str(), GetExceptionCode());
throw std::exception(integer_string);
}
}
#endif
// Top-level wrapper around caller's coroutine callable.
// Normally we like to pass strings and such by const reference -- but in this
// case, we WANT to copy both the name and the callable to our local stack!
void LLCoros::toplevel(std::string name, callable_t callable)
void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable)
{
// keep the CoroData on this top-level function's stack frame
CoroData corodata(name);
@ -280,18 +313,12 @@ void LLCoros::toplevel(std::string name, callable_t callable)
// run the code the caller actually wants in the coroutine
try
{
// <FS:Ansariel> Disable for more meaningful callstacks
//#if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD
// winlevel(callable);
//#else
callable();
//#endif
// <FS:Ansariel> Disable for more meaningful callstacks
}
catch (const Stop& exc)
{
LL_INFOS("LLCoros") << "coroutine " << name << " terminating because "
<< exc.what() << LL_ENDL;
<< exc.what() << LL_ENDL;
}
catch (const LLContinueError&)
{
@ -304,10 +331,25 @@ void LLCoros::toplevel(std::string name, callable_t callable)
{
// Any OTHER kind of uncaught exception will cause the viewer to
// crash, hopefully informatively.
CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
// to not modify callstack
throw;
}
}
// Top-level wrapper around caller's coroutine callable.
// Normally we like to pass strings and such by const reference -- but in this
// case, we WANT to copy both the name and the callable to our local stack!
void LLCoros::toplevel(std::string name, callable_t callable)
{
#if LL_WINDOWS
// Can not use __try in functions that require unwinding, so use one more wrapper
winlevel(name, callable);
#else
toplevelTryWrapper(name, callable);
#endif
}
//static
void LLCoros::checkStop()
{

View File

@ -290,11 +290,12 @@ public:
private:
std::string generateDistinctName(const std::string& prefix) const;
#if LL_WINDOWS
void winlevel(const std::string& name, const callable_t& callable);
#endif
void toplevelTryWrapper(const std::string& name, const callable_t& callable);
void toplevel(std::string name, callable_t callable);
struct CoroData;
#if LL_WINDOWS
static void winlevel(const callable_t& callable);
#endif
static CoroData& get_CoroData(const std::string& caller);
S32 mStackSize;

View File

@ -488,8 +488,6 @@ namespace
protected:
Globals();
public:
std::ostringstream messageStream;
bool messageStreamInUse;
std::string mFatalMessage;
void addCallSite(LLError::CallSite&);
@ -499,12 +497,7 @@ namespace
CallSiteVector callSites;
};
Globals::Globals()
: messageStream(),
messageStreamInUse(false),
callSites()
{
}
Globals::Globals() {}
Globals* Globals::getInstance()
{
@ -595,7 +588,7 @@ namespace LLError
mFileLevelMap(),
mTagLevelMap(),
mUniqueLogMessages(),
mCrashFunction(NULL),
mCrashFunction([](const std::string&){}),
mTimeFunction(NULL),
mRecorders(),
mShouldLogCallCounter(0)
@ -780,7 +773,6 @@ namespace
LLError::setDefaultLevel(LLError::LEVEL_INFO);
LLError::setAlwaysFlush(true);
LLError::setEnabledLogTypesMask(0xFFFFFFFF);
LLError::setFatalFunction(LLError::crashAndLoop);
LLError::setTimeFunction(LLError::utcTime);
// log_to_stderr is only false in the unit and integration tests to keep builds quieter
@ -1419,57 +1411,7 @@ namespace LLError
}
std::ostringstream* Log::out()
{
LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);
if (lock.isLocked())
{
Globals* g = Globals::getInstance();
if (!g->messageStreamInUse)
{
g->messageStreamInUse = true;
return &g->messageStream;
}
}
return new std::ostringstream;
}
void Log::flush(std::ostringstream* out, char* message)
{
LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);
if (!lock.isLocked())
{
return;
}
if(strlen(out->str().c_str()) < 128)
{
strcpy(message, out->str().c_str());
}
else
{
strncpy(message, out->str().c_str(), 127);
message[127] = '\0' ;
}
Globals* g = Globals::getInstance();
if (out == &g->messageStream)
{
g->messageStream.clear();
g->messageStream.str("");
g->messageStreamInUse = false;
}
else
{
delete out;
}
return ;
}
void Log::flush(std::ostringstream* out, const CallSite& site)
void Log::flush(const std::ostringstream& out, const CallSite& site)
{
LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);
if (!lock.isLocked())
@ -1480,21 +1422,11 @@ namespace LLError
Globals* g = Globals::getInstance();
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
std::string message = out->str();
if (out == &g->messageStream)
{
g->messageStream.clear();
g->messageStream.str("");
g->messageStreamInUse = false;
}
else
{
delete out;
}
std::string message = out.str();
if (site.mPrintOnce)
{
std::ostringstream message_stream;
std::ostringstream message_stream;
std::map<std::string, unsigned int>::iterator messageIter = s->mUniqueLogMessages.find(message);
if (messageIter != s->mUniqueLogMessages.end())
@ -1515,8 +1447,8 @@ namespace LLError
message_stream << "ONCE: ";
s->mUniqueLogMessages[message] = 1;
}
message_stream << message;
message = message_stream.str();
message_stream << message;
message = message_stream.str();
}
writeToRecorders(site, message);
@ -1524,10 +1456,7 @@ namespace LLError
if (site.mLevel == LEVEL_ERROR)
{
g->mFatalMessage = message;
if (s->mCrashFunction)
{
s->mCrashFunction(message);
}
s->mCrashFunction(message);
}
}
}
@ -1591,29 +1520,6 @@ namespace LLError
return s->mShouldLogCallCounter;
}
#if LL_WINDOWS
// VC80 was optimizing the error away.
#pragma optimize("", off)
#endif
void crashAndLoop(const std::string& message)
{
// Now, we go kaboom!
int* make_me_crash = NULL;
*make_me_crash = 0;
while(true)
{
// Loop forever, in case the crash didn't work?
}
// this is an attempt to let Coverity and other semantic scanners know that this function won't be returning ever.
exit(EXIT_FAILURE);
}
#if LL_WINDOWS
#pragma optimize("", on)
#endif
std::string utcTime()
{
time_t now = time(NULL);
@ -1630,33 +1536,7 @@ namespace LLError
namespace LLError
{
char** LLCallStacks::sBuffer = NULL ;
S32 LLCallStacks::sIndex = 0 ;
//static
void LLCallStacks::allocateStackBuffer()
{
if(sBuffer == NULL)
{
sBuffer = new char*[512] ;
sBuffer[0] = new char[512 * 128] ;
for(S32 i = 1 ; i < 512 ; i++)
{
sBuffer[i] = sBuffer[i-1] + 128 ;
}
sIndex = 0 ;
}
}
void LLCallStacks::freeStackBuffer()
{
if(sBuffer != NULL)
{
delete [] sBuffer[0] ;
delete [] sBuffer ;
sBuffer = NULL ;
}
}
LLCallStacks::StringVector LLCallStacks::sBuffer ;
//static
void LLCallStacks::push(const char* function, const int line)
@ -1667,33 +1547,24 @@ namespace LLError
return;
}
if(sBuffer == NULL)
{
allocateStackBuffer();
}
if(sIndex > 511)
if(sBuffer.size() > 511)
{
clear() ;
}
strcpy(sBuffer[sIndex], function) ;
sprintf(sBuffer[sIndex] + strlen(function), " line: %d ", line) ;
sIndex++ ;
return ;
std::ostringstream out;
insert(out, function, line);
sBuffer.push_back(out.str());
}
//static
std::ostringstream* LLCallStacks::insert(const char* function, const int line)
void LLCallStacks::insert(std::ostream& out, const char* function, const int line)
{
std::ostringstream* _out = LLError::Log::out();
*_out << function << " line " << line << " " ;
return _out ;
out << function << " line " << line << " " ;
}
//static
void LLCallStacks::end(std::ostringstream* _out)
void LLCallStacks::end(const std::ostringstream& out)
{
LLMutexTrylock lock(getMutex<STACKS_MUTEX>(), 5);
if (!lock.isLocked())
@ -1701,17 +1572,12 @@ namespace LLError
return;
}
if(sBuffer == NULL)
{
allocateStackBuffer();
}
if(sIndex > 511)
if(sBuffer.size() > 511)
{
clear() ;
}
LLError::Log::flush(_out, sBuffer[sIndex++]) ;
sBuffer.push_back(out.str());
}
//static
@ -1723,33 +1589,30 @@ namespace LLError
return;
}
if(sIndex > 0)
if(! sBuffer.empty())
{
LL_INFOS() << " ************* PRINT OUT LL CALL STACKS ************* " << LL_ENDL;
while(sIndex > 0)
for (StringVector::const_reverse_iterator ri(sBuffer.rbegin()), re(sBuffer.rend());
ri != re; ++ri)
{
sIndex-- ;
LL_INFOS() << sBuffer[sIndex] << LL_ENDL;
LL_INFOS() << (*ri) << LL_ENDL;
}
LL_INFOS() << " *************** END OF LL CALL STACKS *************** " << LL_ENDL;
}
if(sBuffer != NULL)
{
freeStackBuffer();
}
cleanup();
}
//static
void LLCallStacks::clear()
{
sIndex = 0 ;
sBuffer.clear();
}
//static
void LLCallStacks::cleanup()
{
freeStackBuffer();
clear();
}
std::ostream& operator<<(std::ostream& out, const LLStacktrace&)

View File

@ -29,7 +29,9 @@
#define LL_LLERROR_H
#include <sstream>
#include <string>
#include <typeinfo>
#include <vector>
#include "stdtypes.h"
@ -204,9 +206,7 @@ namespace LLError
{
public:
static bool shouldLog(CallSite&);
static std::ostringstream* out();
static void flush(std::ostringstream* out, char* message);
static void flush(std::ostringstream*, const CallSite&);
static void flush(const std::ostringstream&, const CallSite&);
static std::string demangle(const char* mangled);
/// classname<TYPE>()
template <typename T>
@ -287,18 +287,15 @@ namespace LLError
class LL_COMMON_API LLCallStacks
{
private:
static char** sBuffer ;
static S32 sIndex ;
static void allocateStackBuffer();
static void freeStackBuffer();
typedef std::vector<std::string> StringVector;
static StringVector sBuffer ;
public:
static void push(const char* function, const int line) ;
static std::ostringstream* insert(const char* function, const int line) ;
static void insert(std::ostream& out, const char* function, const int line) ;
static void print() ;
static void clear() ;
static void end(std::ostringstream* _out) ;
static void end(const std::ostringstream& out) ;
static void cleanup();
};
@ -312,10 +309,11 @@ namespace LLError
//this is cheaper than llcallstacks if no need to output other variables to call stacks.
#define LL_PUSH_CALLSTACKS() LLError::LLCallStacks::push(__FUNCTION__, __LINE__)
#define llcallstacks \
{ \
std::ostringstream* _out = LLError::LLCallStacks::insert(__FUNCTION__, __LINE__) ; \
(*_out)
#define llcallstacks \
{ \
std::ostringstream _out; \
LLError::LLCallStacks::insert(_out, __FUNCTION__, __LINE__) ; \
_out
#define llcallstacksendl \
LLError::End(); \
@ -361,11 +359,11 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
static LLError::CallSite _site(lllog_site_args_(level, once, tags)); \
lllog_test_()
#define lllog_test_() \
if (LL_UNLIKELY(_site.shouldLog())) \
{ \
std::ostringstream* _out = LLError::Log::out(); \
(*_out)
#define lllog_test_() \
if (LL_UNLIKELY(_site.shouldLog())) \
{ \
std::ostringstream _out; \
_out
#define lllog_site_args_(level, once, tags) \
level, __FILE__, __LINE__, typeid(_LL_CLASS_TO_LOG), \
@ -384,15 +382,27 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
// LL_CONT << " for " << t << " seconds" << LL_ENDL;
//
//Such computation is done iff the message will be logged.
#define LL_CONT (*_out)
#define LL_CONT _out
#define LL_NEWLINE '\n'
#define LL_ENDL \
LLError::End(); \
LLError::Log::flush(_out, _site); \
} \
} while(0)
// Use this only in LL_ERRS or in a place that LL_ERRS may not be used
#define LLERROR_CRASH \
{ \
int* make_me_crash = NULL;\
*make_me_crash = 0; \
exit(*make_me_crash); \
}
#define LL_ENDL \
LLError::End(); \
LLError::Log::flush(_out, _site); \
if (_site.mLevel == LLError::LEVEL_ERROR) \
{ \
LLERROR_CRASH \
} \
} \
} while(0)
// NEW Macros for debugging, allow the passing of a string tag

View File

@ -94,14 +94,16 @@ namespace LLError
*/
typedef boost::function<void(const std::string&)> FatalFunction;
LL_COMMON_API void crashAndLoop(const std::string& message);
// Default fatal function: access null pointer and loops forever
LL_COMMON_API void setFatalFunction(const FatalFunction&);
// The fatal function will be called when an message of LEVEL_ERROR
// The fatal function will be called after an message of LEVEL_ERROR
// is logged. Note: supressing a LEVEL_ERROR message from being logged
// (by, for example, setting a class level to LEVEL_NONE), will keep
// the that message from causing the fatal funciton to be invoked.
// that message from causing the fatal function to be invoked.
// The passed FatalFunction will be the LAST log function called
// before LL_ERRS crashes its caller. A FatalFunction can throw an
// exception, or call exit(), to bypass the crash. It MUST disrupt the
// flow of control because no caller expects LL_ERRS to return.
LL_COMMON_API FatalFunction getFatalFunction();
// Retrieve the previously-set FatalFunction
@ -147,14 +149,14 @@ namespace LLError
virtual void recordMessage(LLError::ELevel, const std::string& message) = 0;
// use the level for better display, not for filtering
virtual bool enabled() { return true; }
virtual bool enabled() { return true; }
bool wantsTime();
bool wantsTags();
bool wantsLevel();
bool wantsLocation();
bool wantsFunctionName();
bool wantsMultiline();
bool wantsMultiline();
void showTime(bool show);
void showTags(bool show);
@ -165,15 +167,35 @@ namespace LLError
protected:
bool mWantsTime;
bool mWantsTags;
bool mWantsLevel;
bool mWantsLocation;
bool mWantsFunctionName;
bool mWantsMultiline;
bool mWantsTags;
bool mWantsLevel;
bool mWantsLocation;
bool mWantsFunctionName;
bool mWantsMultiline;
};
typedef boost::shared_ptr<Recorder> RecorderPtr;
/**
* Instantiate GenericRecorder with a callable(level, message) to get
* control on every log message without having to code an explicit
* Recorder subclass.
*/
template <typename CALLABLE>
class GenericRecorder: public Recorder
{
public:
GenericRecorder(const CALLABLE& callable):
mCallable(callable)
{}
void recordMessage(LLError::ELevel level, const std::string& message) override
{
mCallable(level, message);
}
private:
CALLABLE mCallable;
};
/**
* @NOTE: addRecorder() and removeRecorder() uses the boost::shared_ptr to allow for shared ownership
* while still ensuring that the allocated memory is eventually freed
@ -181,6 +203,19 @@ namespace LLError
LL_COMMON_API void addRecorder(RecorderPtr);
LL_COMMON_API void removeRecorder(RecorderPtr);
// each error message is passed to each recorder via recordMessage()
/**
* Call addGenericRecorder() with a callable(level, message) to get
* control on every log message without having to code an explicit
* Recorder subclass. Save the returned RecorderPtr if you later want to
* call removeRecorder().
*/
template <typename CALLABLE>
RecorderPtr addGenericRecorder(const CALLABLE& callable)
{
RecorderPtr ptr{ new GenericRecorder<CALLABLE>(callable) };
addRecorder(ptr);
return ptr;
}
LL_COMMON_API void logToFile(const std::string& filename);
LL_COMMON_API void logToStderr();

View File

@ -59,7 +59,6 @@ public:
// pump name -- so it should NOT need tweaking for uniqueness.
mReplyPump(LLUUID::generateNewID().asString()),
mExpect(0),
mPrevFatalFunction(LLError::getFatalFunction()),
// Instantiate a distinct LLLeapListener for this plugin. (Every
// plugin will want its own collection of managed listeners, etc.)
// Pass it a callback to our connect() method, so it can send events
@ -146,7 +145,9 @@ public:
.listen("LLLeap", boost::bind(&LLLeapImpl::rstderr, this, _1));
// For our lifespan, intercept any LL_ERRS so we can notify plugin
LLError::setFatalFunction(boost::bind(&LLLeapImpl::fatalFunction, this, _1));
mRecorder = LLError::addGenericRecorder(
[this](LLError::ELevel level, const std::string& message)
{ onError(level, message); });
// Send child a preliminary event reporting our own reply-pump name --
// which would otherwise be pretty tricky to guess!
@ -162,8 +163,7 @@ public:
virtual ~LLLeapImpl()
{
LL_DEBUGS("LLLeap") << "destroying LLLeap(\"" << mDesc << "\")" << LL_ENDL;
// Restore original FatalFunction
LLError::setFatalFunction(mPrevFatalFunction);
LLError::removeRecorder(mRecorder);
}
// Listener for failed launch attempt
@ -377,28 +377,28 @@ public:
return false;
}
void fatalFunction(const std::string& error)
void onError(LLError::ELevel level, const std::string& error)
{
// Notify plugin
LLSD event;
event["type"] = "error";
event["error"] = error;
mReplyPump.post(event);
// All the above really accomplished was to buffer the serialized
// event in our WritePipe. Have to pump mainloop a couple times to
// really write it out there... but time out in case we can't write.
LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN));
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
LLSD nop;
F64 until = (LLTimer::getElapsedSeconds() + 2).value();
while (childin.size() && LLTimer::getElapsedSeconds() < until)
if (level == LLError::LEVEL_ERROR)
{
mainloop.post(nop);
}
// Notify plugin
LLSD event;
event["type"] = "error";
event["error"] = error;
mReplyPump.post(event);
// forward the call to the previous FatalFunction
mPrevFatalFunction(error);
// All the above really accomplished was to buffer the serialized
// event in our WritePipe. Have to pump mainloop a couple times to
// really write it out there... but time out in case we can't write.
LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN));
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
LLSD nop;
F64 until = (LLTimer::getElapsedSeconds() + 2).value();
while (childin.size() && LLTimer::getElapsedSeconds() < until)
{
mainloop.post(nop);
}
}
}
private:
@ -421,7 +421,7 @@ private:
mStdinConnection, mStdoutConnection, mStdoutDataConnection, mStderrConnection;
boost::scoped_ptr<LLEventPump::Blocker> mBlocker;
LLProcess::ReadPipe::size_type mExpect;
LLError::FatalFunction mPrevFatalFunction;
LLError::RecorderPtr mRecorder;
boost::scoped_ptr<LLLeapListener> mListener;
};

View File

@ -38,11 +38,6 @@
#include <sstream>
#include <stdexcept>
namespace {
void log(LLError::ELevel level,
const char* p1, const char* p2, const char* p3, const char* p4);
} // anonymous namespace
// Our master list of all LLSingletons is itself an LLSingleton. We used to
// store it in a function-local static, but that could get destroyed before
// the last of the LLSingletons -- and ~LLSingletonBase() definitely wants to
@ -218,8 +213,8 @@ void LLSingletonBase::pop_initializing()
if (list.empty())
{
logerrs("Underflow in stack of currently-initializing LLSingletons at ",
classname(this).c_str(), "::getInstance()");
logerrs({"Underflow in stack of currently-initializing LLSingletons at ",
classname(this), "::getInstance()"});
}
// Now we know list.back() exists: capture it
@ -240,9 +235,9 @@ void LLSingletonBase::pop_initializing()
// Now validate the newly-popped LLSingleton.
if (back != this)
{
logerrs("Push/pop mismatch in stack of currently-initializing LLSingletons: ",
classname(this).c_str(), "::getInstance() trying to pop ",
classname(back).c_str());
logerrs({"Push/pop mismatch in stack of currently-initializing LLSingletons: ",
classname(this), "::getInstance() trying to pop ",
classname(back)});
}
// log AFTER popping so logging singletons don't cry circularity
@ -331,15 +326,15 @@ void LLSingletonBase::capture_dependency()
//
// Example: LLNotifications singleton initializes default channels.
// Channels register themselves with singleton once done.
logdebugs("LLSingleton circularity: ", out.str().c_str(),
classname(this).c_str(), "");
logdebugs({"LLSingleton circularity: ", out.str(),
classname(this)});
}
else
{
// Actual circularity with other singleton (or single singleton is used extensively).
// Dependency can be unclear.
logwarns("LLSingleton circularity: ", out.str().c_str(),
classname(this).c_str(), "");
logwarns({"LLSingleton circularity: ", out.str(),
classname(this)});
}
}
else
@ -352,8 +347,8 @@ void LLSingletonBase::capture_dependency()
if (current->mDepends.insert(this).second)
{
// only log the FIRST time we hit this dependency!
logdebugs(classname(current).c_str(),
" depends on ", classname(this).c_str());
logdebugs({classname(current),
" depends on ", classname(this)});
}
}
}
@ -401,7 +396,7 @@ LLSingletonBase::vec_t LLSingletonBase::dep_sort()
void LLSingletonBase::cleanup_()
{
logdebugs("calling ", classname(this).c_str(), "::cleanupSingleton()");
logdebugs({"calling ", classname(this), "::cleanupSingleton()"});
try
{
cleanupSingleton();
@ -427,23 +422,23 @@ void LLSingletonBase::deleteAll()
if (! sp->mDeleteSingleton)
{
// This Should Not Happen... but carry on.
logwarns(name.c_str(), "::mDeleteSingleton not initialized!");
logwarns({name, "::mDeleteSingleton not initialized!"});
}
else
{
// properly initialized: call it.
logdebugs("calling ", name.c_str(), "::deleteSingleton()");
logdebugs({"calling ", name, "::deleteSingleton()"});
// From this point on, DO NOT DEREFERENCE sp!
sp->mDeleteSingleton();
}
}
catch (const std::exception& e)
{
logwarns("Exception in ", name.c_str(), "::deleteSingleton(): ", e.what());
logwarns({"Exception in ", name, "::deleteSingleton(): ", e.what()});
}
catch (...)
{
logwarns("Unknown exception in ", name.c_str(), "::deleteSingleton()");
logwarns({"Unknown exception in ", name, "::deleteSingleton()"});
}
}
}
@ -451,49 +446,40 @@ void LLSingletonBase::deleteAll()
/*---------------------------- Logging helpers -----------------------------*/
namespace {
void log(LLError::ELevel level,
const char* p1, const char* p2, const char* p3, const char* p4)
std::ostream& operator<<(std::ostream& out, const LLSingletonBase::string_params& args)
{
LL_VLOGS(level, "LLSingleton") << p1 << p2 << p3 << p4 << LL_ENDL;
// However many args there are in args, stream each of them to 'out'.
for (auto arg : args)
{
out << arg;
}
return out;
}
} // anonymous namespace
//static
void LLSingletonBase::logwarns(const char* p1, const char* p2, const char* p3, const char* p4)
void LLSingletonBase::logwarns(const string_params& args)
{
log(LLError::LEVEL_WARN, p1, p2, p3, p4);
LL_WARNS("LLSingleton") << args << LL_ENDL;
}
//static
void LLSingletonBase::loginfos(const char* p1, const char* p2, const char* p3, const char* p4)
void LLSingletonBase::loginfos(const string_params& args)
{
log(LLError::LEVEL_INFO, p1, p2, p3, p4);
LL_INFOS("LLSingleton") << args << LL_ENDL;
}
//static
void LLSingletonBase::logdebugs(const char* p1, const char* p2, const char* p3, const char* p4)
void LLSingletonBase::logdebugs(const string_params& args)
{
log(LLError::LEVEL_DEBUG, p1, p2, p3, p4);
LL_DEBUGS("LLSingleton") << args << LL_ENDL;
}
//static
void LLSingletonBase::logerrs(const char* p1, const char* p2, const char* p3, const char* p4)
void LLSingletonBase::logerrs(const string_params& args)
{
log(LLError::LEVEL_ERROR, p1, p2, p3, p4);
// The other important side effect of LL_ERRS() is
// https://www.youtube.com/watch?v=OMG7paGJqhQ (emphasis on OMG)
std::ostringstream out;
out << p1 << p2 << p3 << p4;
auto crash = LLError::getFatalFunction();
if (crash)
{
crash(out.str());
}
else
{
LLError::crashAndLoop(out.str());
}
LL_ERRS("LLSingleton") << args << LL_ENDL;
}
std::string LLSingletonBase::demangle(const char* mangled)

View File

@ -27,9 +27,10 @@
#include <boost/noncopyable.hpp>
#include <boost/unordered_set.hpp>
#include <initializer_list>
#include <list>
#include <vector>
#include <typeinfo>
#include <vector>
#include "mutex.h"
#include "lockstatic.h"
#include "llthread.h" // on_main_thread()
@ -111,14 +112,13 @@ protected:
void capture_dependency();
// delegate logging calls to llsingleton.cpp
static void logerrs(const char* p1, const char* p2="",
const char* p3="", const char* p4="");
static void logwarns(const char* p1, const char* p2="",
const char* p3="", const char* p4="");
static void loginfos(const char* p1, const char* p2="",
const char* p3="", const char* p4="");
static void logdebugs(const char* p1, const char* p2="",
const char* p3="", const char* p4="");
public:
typedef std::initializer_list<const std::string> string_params;
protected:
static void logerrs (const string_params&);
static void logwarns (const string_params&);
static void loginfos (const string_params&);
static void logdebugs(const string_params&);
static std::string demangle(const char* mangled);
// these classname() declarations restate template functions declared in
// llerror.h because we avoid #including that here
@ -368,8 +368,8 @@ private:
// init stack to its previous size BEFORE logging so log-machinery
// LLSingletons don't record a dependency on DERIVED_TYPE!
LLSingleton_manage_master<DERIVED_TYPE>().reset_initializing(prev_size);
logwarns("Error constructing ", classname<DERIVED_TYPE>().c_str(),
": ", err.what());
logwarns({"Error constructing ", classname<DERIVED_TYPE>(),
": ", err.what()});
// There isn't a separate EInitState value meaning "we attempted
// to construct this LLSingleton subclass but could not," so use
// DELETED. That seems slightly more appropriate than UNINITIALIZED.
@ -397,8 +397,8 @@ private:
// BEFORE logging, so log-machinery LLSingletons don't record a
// dependency on DERIVED_TYPE!
pop_initializing(lk->mInstance);
logwarns("Error in ", classname<DERIVED_TYPE>().c_str(),
"::initSingleton(): ", err.what());
logwarns({"Error in ", classname<DERIVED_TYPE>(),
"::initSingleton(): ", err.what()});
// Get rid of the instance entirely. This call depends on our
// recursive_mutex. We could have a deleteSingleton(LockStatic&)
// overload and pass lk, but we don't strictly need it.
@ -547,9 +547,9 @@ public:
case CONSTRUCTING:
// here if DERIVED_TYPE's constructor (directly or indirectly)
// calls DERIVED_TYPE::getInstance()
logerrs("Tried to access singleton ",
classname<DERIVED_TYPE>().c_str(),
" from singleton constructor!");
logerrs({"Tried to access singleton ",
classname<DERIVED_TYPE>(),
" from singleton constructor!"});
return nullptr;
case INITIALIZING:
@ -564,9 +564,9 @@ public:
case DELETED:
// called after deleteSingleton()
logwarns("Trying to access deleted singleton ",
classname<DERIVED_TYPE>().c_str(),
" -- creating new instance");
logwarns({"Trying to access deleted singleton ",
classname<DERIVED_TYPE>(),
" -- creating new instance"});
// fall through
case UNINITIALIZED:
case QUEUED:
@ -593,8 +593,8 @@ public:
} // unlock 'lk'
// Per the comment block above, dispatch to the main thread.
loginfos(classname<DERIVED_TYPE>().c_str(),
"::getInstance() dispatching to main thread");
loginfos({classname<DERIVED_TYPE>(),
"::getInstance() dispatching to main thread"});
auto instance = LLMainThreadTask::dispatch(
[](){
// VERY IMPORTANT to call getInstance() on the main thread,
@ -604,16 +604,16 @@ public:
// the main thread processes them, only the FIRST such request
// actually constructs the instance -- every subsequent one
// simply returns the existing instance.
loginfos(classname<DERIVED_TYPE>().c_str(),
"::getInstance() on main thread");
loginfos({classname<DERIVED_TYPE>(),
"::getInstance() on main thread"});
return getInstance();
});
// record the dependency chain tracked on THIS thread, not the main
// thread (consider a getInstance() overload with a tag param that
// suppresses dep tracking when dispatched to the main thread)
capture_dependency(instance);
loginfos(classname<DERIVED_TYPE>().c_str(),
"::getInstance() returning on requesting thread");
loginfos({classname<DERIVED_TYPE>(),
"::getInstance() returning on requesting thread"});
return instance;
}
@ -682,16 +682,16 @@ private:
// For organizational purposes this function shouldn't be called twice
if (lk->mInitState != super::UNINITIALIZED)
{
super::logerrs("Tried to initialize singleton ",
super::template classname<DERIVED_TYPE>().c_str(),
" twice!");
super::logerrs({"Tried to initialize singleton ",
super::template classname<DERIVED_TYPE>(),
" twice!"});
return nullptr;
}
else if (on_main_thread())
{
// on the main thread, simply construct instance while holding lock
super::logdebugs(super::template classname<DERIVED_TYPE>().c_str(),
"::initParamSingleton()");
super::logdebugs({super::template classname<DERIVED_TYPE>(),
"::initParamSingleton()"});
super::constructSingleton(lk, std::forward<Args>(args)...);
return lk->mInstance;
}
@ -703,8 +703,8 @@ private:
lk->mInitState = super::QUEUED;
// very important to unlock here so main thread can actually process
lk.unlock();
super::loginfos(super::template classname<DERIVED_TYPE>().c_str(),
"::initParamSingleton() dispatching to main thread");
super::loginfos({super::template classname<DERIVED_TYPE>(),
"::initParamSingleton() dispatching to main thread"});
// Normally it would be the height of folly to reference-bind
// 'args' into a lambda to be executed on some other thread! By
// the time that thread executed the lambda, the references would
@ -715,12 +715,12 @@ private:
// references.
auto instance = LLMainThreadTask::dispatch(
[&](){
super::loginfos(super::template classname<DERIVED_TYPE>().c_str(),
"::initParamSingleton() on main thread");
super::loginfos({super::template classname<DERIVED_TYPE>(),
"::initParamSingleton() on main thread"});
return initParamSingleton_(std::forward<Args>(args)...);
});
super::loginfos(super::template classname<DERIVED_TYPE>().c_str(),
"::initParamSingleton() returning on requesting thread");
super::loginfos({super::template classname<DERIVED_TYPE>(),
"::initParamSingleton() returning on requesting thread"});
return instance;
}
}
@ -748,14 +748,14 @@ public:
{
case super::UNINITIALIZED:
case super::QUEUED:
super::logerrs("Uninitialized param singleton ",
super::template classname<DERIVED_TYPE>().c_str());
super::logerrs({"Uninitialized param singleton ",
super::template classname<DERIVED_TYPE>()});
break;
case super::CONSTRUCTING:
super::logerrs("Tried to access param singleton ",
super::template classname<DERIVED_TYPE>().c_str(),
" from singleton constructor!");
super::logerrs({"Tried to access param singleton ",
super::template classname<DERIVED_TYPE>(),
" from singleton constructor!"});
break;
case super::INITIALIZING:
@ -767,8 +767,8 @@ public:
return lk->mInstance;
case super::DELETED:
super::logerrs("Trying to access deleted param singleton ",
super::template classname<DERIVED_TYPE>().c_str());
super::logerrs({"Trying to access deleted param singleton ",
super::template classname<DERIVED_TYPE>()});
break;
}

View File

@ -358,8 +358,9 @@ void LLThread::setQuitting()
{
mStatus = QUITTING;
}
// It's only safe to remove mRunCondition if all locked threads were notified
mRunCondition->broadcast();
mDataLock->unlock();
wake();
}
// static

View File

@ -280,7 +280,7 @@ std::string LLURI::escapePathAndData(const std::string &str)
std::string fragment;
size_t fragment_pos = str.find('#');
if (fragment_pos != std::string::npos)
if ((fragment_pos != std::string::npos) && (fragment_pos > delim_pos))
{
query = str.substr(path_size, fragment_pos - path_size);
fragment = str.substr(fragment_pos);

View File

@ -26,6 +26,7 @@
*/
#include <vector>
#include <stdexcept>
#include "linden_common.h"
@ -69,21 +70,41 @@ namespace
namespace
{
static bool fatalWasCalled;
void fatalCall(const std::string&) { fatalWasCalled = true; }
static bool fatalWasCalled = false;
struct FatalWasCalled: public std::runtime_error
{
FatalWasCalled(const std::string& what): std::runtime_error(what) {}
};
void fatalCall(const std::string& msg) { throw FatalWasCalled(msg); }
}
// Because we use LLError::setFatalFunction(fatalCall), any LL_ERRS call we
// issue will throw FatalWasCalled. But we want the test program to continue.
// So instead of writing:
// LL_ERRS("tag") << "some message" << LL_ENDL;
// write:
// CATCH(LL_ERRS("tag"), "some message");
#define CATCH(logcall, expr) \
try \
{ \
logcall << expr << LL_ENDL; \
} \
catch (const FatalWasCalled&) \
{ \
fatalWasCalled = true; \
}
namespace tut
{
class TestRecorder : public LLError::Recorder
{
public:
TestRecorder()
{
showTime(false);
}
{
showTime(false);
}
virtual ~TestRecorder()
{}
{}
virtual void recordMessage(LLError::ELevel level,
const std::string& message)
@ -252,7 +273,7 @@ namespace
LL_DEBUGS("WriteTag","AnotherTag") << "one" << LL_ENDL;
LL_INFOS("WriteTag") << "two" << LL_ENDL;
LL_WARNS("WriteTag") << "three" << LL_ENDL;
LL_ERRS("WriteTag") << "four" << LL_ENDL;
CATCH(LL_ERRS("WriteTag"), "four");
}
};
@ -380,7 +401,7 @@ namespace
std::string errorReturningLocation()
{
LL_ERRS() << "die" << LL_ENDL; int this_line = __LINE__;
int this_line = __LINE__; CATCH(LL_ERRS(), "die");
return locationString(this_line);
}
}
@ -701,7 +722,7 @@ public:
static void doDebug() { LL_DEBUGS() << "add dice" << LL_ENDL; }
static void doInfo() { LL_INFOS() << "any idea" << LL_ENDL; }
static void doWarn() { LL_WARNS() << "aim west" << LL_ENDL; }
static void doError() { LL_ERRS() << "ate eels" << LL_ENDL; }
static void doError() { CATCH(LL_ERRS(), "ate eels"); }
static void doAll() { doDebug(); doInfo(); doWarn(); doError(); }
};
@ -712,7 +733,7 @@ public:
static void doDebug() { LL_DEBUGS() << "bed down" << LL_ENDL; }
static void doInfo() { LL_INFOS() << "buy iron" << LL_ENDL; }
static void doWarn() { LL_WARNS() << "bad word" << LL_ENDL; }
static void doError() { LL_ERRS() << "big easy" << LL_ENDL; }
static void doError() { CATCH(LL_ERRS(), "big easy"); }
static void doAll() { doDebug(); doInfo(); doWarn(); doError(); }
};
@ -874,13 +895,10 @@ namespace tut
namespace
{
std::string writeTagWithSpaceReturningLocation()
{
LL_DEBUGS("Write Tag") << "not allowed" << LL_ENDL; int this_line = __LINE__;
std::ostringstream location;
location << LLError::abbreviateFile(__FILE__).c_str() << "(" << this_line << ")";
return location.str();
}
{
int this_line = __LINE__; CATCH(LL_DEBUGS("Write Tag"), "not allowed");
return locationString(this_line);
}
};
namespace tut
@ -894,9 +912,9 @@ namespace tut
std::string location = writeTagWithSpaceReturningLocation();
std::string expected = "Space is not allowed in a log tag at " + location;
ensure_message_field_equals(0, LEVEL_FIELD, "ERROR");
ensure_message_field_equals(0, MSG_FIELD, expected);
ensure("fatal callback called", fatalWasCalled);
ensure_message_field_equals(0, LEVEL_FIELD, "ERROR");
ensure_message_field_equals(0, MSG_FIELD, expected);
ensure("fatal callback called", fatalWasCalled);
}
}

View File

@ -44,10 +44,6 @@
#include <list>
#include <string>
// statically reference the function in test.cpp... it's short, we could
// replicate, but better to reuse
extern void wouldHaveCrashed(const std::string& message);
struct WrapLLErrs
{
WrapLLErrs():
@ -59,7 +55,8 @@ struct WrapLLErrs
mPriorFatal(LLError::getFatalFunction())
{
// Make LL_ERRS call our own operator() method
LLError::setFatalFunction(boost::bind(&WrapLLErrs::operator(), this, _1));
LLError::setFatalFunction(
[this](const std::string& message){ (*this)(message); });
}
~WrapLLErrs()
@ -199,11 +196,13 @@ public:
// with that output. If it turns out that saveAndResetSettings() has
// some bad effect, give up and just let the DEBUG level log messages
// display.
: boost::noncopyable(),
: boost::noncopyable(),
mFatalFunction(LLError::getFatalFunction()),
mOldSettings(LLError::saveAndResetSettings()),
mRecorder(new CaptureLogRecorder())
mRecorder(new CaptureLogRecorder())
{
LLError::setFatalFunction(wouldHaveCrashed);
// reinstate the FatalFunction we just reset
LLError::setFatalFunction(mFatalFunction);
LLError::setDefaultLevel(level);
LLError::addRecorder(mRecorder);
}
@ -219,17 +218,18 @@ public:
/// for the sought string.
std::string messageWith(const std::string& search, bool required=true)
{
return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->messageWith(search, required);
return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->messageWith(search, required);
}
std::ostream& streamto(std::ostream& out) const
{
return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->streamto(out);
return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->streamto(out);
}
private:
LLError::FatalFunction mFatalFunction;
LLError::SettingsStoragePtr mOldSettings;
LLError::RecorderPtr mRecorder;
LLError::RecorderPtr mRecorder;
};
#endif /* ! defined(LL_WRAPLLERRS_H) */

View File

@ -17,6 +17,7 @@ include(LLAddBuildTest)
include(LLMessage)
include(LLCommon)
include(Tut)
include(bugsplat)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})

View File

@ -56,7 +56,6 @@ void HttpReplyQueue::addOp(const HttpReplyQueue::opPtr_t &op)
mQueue.push_back(op);
}
mQueueCV.notify_all();
}

View File

@ -98,7 +98,6 @@ protected:
OpContainer mQueue;
LLCoreInt::HttpMutex mQueueMutex;
LLCoreInt::HttpConditionVariable mQueueCV;
}; // end class HttpReplyQueue

View File

@ -142,13 +142,19 @@ void HttpRequestQueue::wakeAll()
}
void HttpRequestQueue::stopQueue()
bool HttpRequestQueue::stopQueue()
{
{
HttpScopedLock lock(mQueueMutex);
mQueueStopped = true;
wakeAll();
if (!mQueueStopped)
{
mQueueStopped = true;
wakeAll();
return true;
}
wakeAll();
return false;
}
}

View File

@ -124,7 +124,7 @@ public:
/// them on their way.
///
/// Threading: callable by any thread.
void stopQueue();
bool stopQueue();
protected:
static HttpRequestQueue * sInstance;

View File

@ -87,7 +87,11 @@ HttpService::~HttpService()
// is a bit tricky.
if (mRequestQueue)
{
mRequestQueue->stopQueue();
if (mRequestQueue->stopQueue())
{
// Give mRequestQueue a chance to finish
ms_sleep(10);
}
}
if (mThread)

View File

@ -32,6 +32,7 @@
namespace LLCore
{
bool HttpOptions::sDefaultVerifyPeer = false;
HttpOptions::HttpOptions() :
mWantHeaders(false),
@ -43,7 +44,7 @@ HttpOptions::HttpOptions() :
mMaxRetryBackoff(HTTP_RETRY_BACKOFF_MAX_DEFAULT),
mUseRetryAfter(HTTP_USE_RETRY_AFTER_DEFAULT),
mFollowRedirects(true),
mVerifyPeer(false),
mVerifyPeer(sDefaultVerifyPeer),
mVerifyHost(false),
mDNSCacheTimeout(-1L),
mNoBody(false),
@ -123,7 +124,15 @@ void HttpOptions::setHeadersOnly(bool nobody)
{
mNoBody = nobody;
if (mNoBody)
{
setWantHeaders(true);
setSSLVerifyPeer(false);
}
}
void HttpOptions::setDefaultSSLVerifyPeer(bool verify)
{
sDefaultVerifyPeer = verify;
}
// <FS:Ansariel> GetIfModified request

View File

@ -143,7 +143,7 @@ public:
/// Instructs the LLCore::HTTPRequest to verify that the exchanged security
/// certificate is authentic.
/// Default: false
/// Default: sDefaultVerifyPeer
void setSSLVerifyPeer(bool verify);
bool getSSLVerifyPeer() const
{
@ -178,6 +178,13 @@ public:
return mNoBody;
}
/// Sets default behavior for verifying that the name in the
/// security certificate matches the name of the host contacted.
/// Defaults false if not set, but should be set according to
/// viewer's initialization options and command argunments, see
/// NoVerifySSLCert
static void setDefaultSSLVerifyPeer(bool verify);
// <FS:Ansariel> GetIfModified request
void setLastModified(long last_modified);
long getLastModified() const
@ -200,6 +207,9 @@ protected:
bool mVerifyHost;
int mDNSCacheTimeout;
bool mNoBody;
static bool sDefaultVerifyPeer;
long mLastModified; // <FS:Ansariel> GetIfModified request
}; // end class HttpOptions

View File

@ -0,0 +1,3 @@
This component is no longer used in Linden Lab builds.
Change requests to support continued use by open source
builds are welcome.

View File

@ -520,6 +520,7 @@ bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
httpOpts->setTimeout(timeout);
httpOpts->setSSLVerifyPeer(false);
for(int i = 0; i < retries; ++i)
{

View File

@ -62,6 +62,11 @@ LLDiskCache::LLDiskCache(const std::string cache_dir,
LLFile::mkdir(dirname);
}
// </FS:Ansariel>
// <FS:Beq> add static assets into the new cache after clear.
// Only missing entries are copied on init, skiplist is setup
// For everything we populate FS specific assets to allow future updates
prepopulateCacheWithStatic();
// </FS:Beq>
}
void LLDiskCache::purge()
@ -117,6 +122,11 @@ void LLDiskCache::purge()
LL_INFOS() << "Purging cache to a maximum of " << mMaxSizeBytes << " bytes" << LL_ENDL;
// <FS:Beq> Extra accounting to track the retention of static assets
int keep{0};
int del{0};
int skip{0};
// </FS:Beq>
uintmax_t file_size_total = 0;
for (file_info_t& entry : file_info)
{
@ -126,17 +136,34 @@ void LLDiskCache::purge()
if (file_size_total > mMaxSizeBytes)
{
action = "DELETE:";
// <FS:Ansariel> Do not crash if we cannot delete the file for some reason
//boost::filesystem::remove(entry.second.second);
boost::filesystem::remove(entry.second.second, ec);
if (ec.failed())
// <FS:Beq> Make sure static assets are not eliminated
auto uuid_as_string = gDirUtilp->getBaseFileName(entry.second.second,true);
uuid_as_string = uuid_as_string.substr(mCacheFilenamePrefix.size() + 1, 36);// skip "sl_cache_" and trailing "_N"
// LL_INFOS() << "checking UUID=" <<uuid_as_string<< LL_ENDL;
if (std::find(mSkipList.begin(), mSkipList.end(), uuid_as_string) != mSkipList.end())
{
LL_WARNS() << "Failed to delete cache file " << entry.second.second << ": " << ec.message() << LL_ENDL;
// this is one of our protected items so no purging
action = "STATIC:";
skip++;
updateFileAccessTime(entry.second.second); // force these to the front of the list next time so that purge size works
}
else
{
del++; // Extra accounting to track the retention of static assets
// </FS:Beq>
// <FS:Ansariel> Do not crash if we cannot delete the file for some reason
//boost::filesystem::remove(entry.second.second);
boost::filesystem::remove(entry.second.second, ec);
if (ec.failed())
{
LL_WARNS() << "Failed to delete cache file " << entry.second.second << ": " << ec.message() << LL_ENDL;
}
}
// </FS:Ansariel>
}
else
{
keep++; // <FS:Beq/> Extra accounting to track the retention of static assets
action = " KEEP:";
}
@ -160,6 +187,7 @@ void LLDiskCache::purge()
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;
LL_INFOS() << "Deleted: " << del << " Skipped: " << skip << " Kept: " << keep << LL_ENDL; // <FS:Beq/> Extra accounting to track the retention of static assets
}
}
@ -321,8 +349,57 @@ const std::string LLDiskCache::getCacheInfo()
return cache_info.str();
}
// <FS:Beq> Copy static items into cache and add to the skip list that prevents their purging
// Note that there is no de-duplication nor other validation of the list.
void LLDiskCache::prepopulateCacheWithStatic()
{
mSkipList.clear();
std::vector<std::string> from_folders;
from_folders.emplace_back(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "fs_static_assets"));
#ifdef OPENSIM
from_folders.emplace_back(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "static_assets"));
#endif
for (const auto& from_folder : from_folders)
{
if (gDirUtilp->fileExists(from_folder))
{
auto assets_to_copy = gDirUtilp->getFilesInDir(from_folder);
for (auto from_asset_file : assets_to_copy)
{
from_asset_file = from_folder + gDirUtilp->getDirDelimiter() + from_asset_file;
// we store static assets as UUID.asset_type the asset_type is not used in the current simple cache format
auto uuid_as_string{ gDirUtilp->getBaseFileName(from_asset_file, true) };
auto to_asset_file = metaDataToFilepath(uuid_as_string, LLAssetType::AT_UNKNOWN, std::string());
if (!gDirUtilp->fileExists(to_asset_file))
{
if (mEnableCacheDebugInfo)
{
LL_INFOS("LLDiskCache") << "Copying static asset " << from_asset_file << " to cache from " << from_folder << LL_ENDL;
}
if (!LLFile::copy(from_asset_file, to_asset_file))
{
LL_WARNS("LLDiskCache") << "Failed to copy " << from_asset_file << " to " << to_asset_file << LL_ENDL;
}
}
if (std::find(mSkipList.begin(), mSkipList.end(), uuid_as_string) == mSkipList.end())
{
if (mEnableCacheDebugInfo)
{
LL_INFOS("LLDiskCache") << "Adding " << uuid_as_string << " to skip list" << LL_ENDL;
}
mSkipList.emplace_back(uuid_as_string);
}
}
}
}
}
// </FS:Beq>
void LLDiskCache::clearCache()
{
LL_INFOS() << "clearing cache " << mCacheDir << LL_ENDL;
/**
* See notes on performance in dirFileSize(..) - there may be
* a quicker way to do this by operating on the parent dir vs
@ -337,26 +414,50 @@ void LLDiskCache::clearCache()
#endif
if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
{
LL_INFOS() << "is a directory: " << mCacheDir << LL_ENDL;
// <FS:Ansariel> Optimize asset simple disk cache
//for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
for (auto& entry : boost::make_iterator_range(boost::filesystem::recursive_directory_iterator(cache_path, ec), {}))
// <FS:TS> FIRE-31070: Crash on clearing cache on macOS and Linux
// On Unix-like operating systems, the recursive_directory_iterator gets very unhappy if you
// delete a file out from under it in a for loop. This restructuring to a while loop and
// manually incrementing the iterator avoids the problem. Note that the iterator must be
// incremented *before* deleting the file.
boost::filesystem::recursive_directory_iterator entry(cache_path, ec);
boost::filesystem::recursive_directory_iterator cache_end;
while (entry != cache_end)
{
if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
const boost::filesystem::path& remove_entry = entry->path();
if (boost::filesystem::is_regular_file(remove_entry, ec) && !ec.failed())
{
if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
if (remove_entry.string().find(mCacheFilenamePrefix) != std::string::npos)
{
// <FS:Ansariel> Do not crash if we cannot delete the file for some reason
//boost::filesystem::remove(entry);
boost::filesystem::remove(entry, ec);
const boost::filesystem::path remove_path = remove_entry;
++entry;
boost::filesystem::remove(remove_path, ec);
if (ec.failed())
{
LL_WARNS() << "Failed to delete cache file " << entry << ": " << ec.message() << LL_ENDL;
LL_WARNS() << "Failed to delete cache file " << remove_path.string() << ": " << ec.message() << LL_ENDL;
}
// </FS:Ansariel>
}
else
{
++entry;
}
}
else
{
++entry;
}
// </FS:TS> FIRE-31070
}
// <FS:Beq> add static assets into the new cache after clear
LL_INFOS() << "prepopulating new cache " << LL_ENDL;
prepopulateCacheWithStatic();
}
LL_INFOS() << "Cleared cache " << mCacheDir << LL_ENDL;
}
uintmax_t LLDiskCache::dirFileSize(const std::string dir)

View File

@ -131,6 +131,11 @@ class LLDiskCache :
*/
void purge();
// <FS:Beq>
// copy from distribution into cache to replace static content
void prepopulateCacheWithStatic();
// </FS:Beq>
/**
* Clear the cache by removing all the files in the specified cache
* directory individually. Only the files that contain a prefix defined
@ -191,6 +196,8 @@ class LLDiskCache :
* various parts of the code
*/
bool mEnableCacheDebugInfo;
std::vector<std::string> mSkipList; // <FS:Beq/> Vector of "static" untouchable assets that should never be purged
};
// <FS:Ansariel> Regular disk cache cleanup

View File

@ -81,10 +81,7 @@ bool LLFileSystem::getExists(const LLUUID& file_id, const LLAssetType::EType fil
}
// static
// <FS:Ansariel> Fix log spam
//bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType file_type)
bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType file_type, int suppress_error /*= 0*/)
// </FS:Ansariel>
{
FSZoneC(tracy::Color::Gold); // <FS:Beq> measure cache performance
std::string id_str;
@ -92,10 +89,7 @@ bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType fi
const std::string extra_info = "";
const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id_str, file_type, extra_info);
// <FS:Ansariel> Fix log spam
//LLFile::remove(filename.c_str());
LLFile::remove(filename.c_str(), suppress_error);
// </FS:Ansariel>
return true;
}
@ -115,10 +109,7 @@ bool LLFileSystem::renameFile(const LLUUID& old_file_id, const LLAssetType::ETyp
const std::string new_filename = LLDiskCache::getInstance()->metaDataToFilepath(new_id_str, new_file_type, extra_info);
// Rename needs the new file to not exist.
// <FS:Ansariel> Fix log spam
//LLFileSystem::removeFile(new_file_id, new_file_type);
LLFileSystem::removeFile(new_file_id, new_file_type, ENOENT);
// </FS:Ansariel>
if (LLFile::rename(old_filename, new_filename) != 0)
{

View File

@ -54,10 +54,7 @@ class LLFileSystem
BOOL remove();
static bool getExists(const LLUUID& file_id, const LLAssetType::EType file_type);
// <FS:Ansariel> Fix log spam
//static bool removeFile(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);
// </FS:Ansariel>
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);

View File

@ -11,6 +11,7 @@ include(LLKDU)
include(LLImageJ2COJ)
include(ZLIB)
include(LLAddBuildTest)
include(bugsplat)
include(Tut)
include_directories(

View File

@ -103,60 +103,104 @@ LLVector3 LLLandmark::getRegionPos() const
// static
LLLandmark* LLLandmark::constructFromString(const char *buffer)
LLLandmark* LLLandmark::constructFromString(const char *buffer, const S32 buffer_size)
{
const char* cur = buffer;
S32 chars_read = 0;
S32 chars_read_total = 0;
S32 count = 0;
U32 version = 0;
bool bad_block = false;
LLLandmark* result = NULL;
// read version
count = sscanf( cur, "Landmark version %u\n%n", &version, &chars_read );
if(count != 1)
{
goto error;
}
count = sscanf( buffer, "Landmark version %u\n%n", &version, &chars_read );
chars_read_total += chars_read;
if(version == 1)
{
LLVector3d pos;
cur += chars_read;
// read position
count = sscanf( cur, "position %lf %lf %lf\n%n", pos.mdV+VX, pos.mdV+VY, pos.mdV+VZ, &chars_read );
if( count != 3 )
{
goto error;
}
cur += chars_read;
// LL_INFOS() << "Landmark read: " << pos << LL_ENDL;
return new LLLandmark(pos);
}
else if(version == 2)
{
// *NOTE: Changing the buffer size will require changing the
// scanf call below.
char region_id_str[MAX_STRING]; /* Flawfinder: ignore */
LLVector3 pos;
cur += chars_read;
count = sscanf( /* Flawfinder: ignore */
cur,
"region_id %254s\n%n",
region_id_str, &chars_read);
if(count != 1) goto error;
cur += chars_read;
count = sscanf(cur, "local_pos %f %f %f\n%n", pos.mV+VX, pos.mV+VY, pos.mV+VZ, &chars_read);
if(count != 3) goto error;
cur += chars_read;
LLLandmark* lm = new LLLandmark;
lm->mRegionID.set(region_id_str);
lm->mRegionPos = pos;
return lm;
}
if (count != 1
|| chars_read_total >= buffer_size)
{
bad_block = true;
}
error:
LL_INFOS() << "Bad Landmark Asset: bad _DATA_ block." << LL_ENDL;
return NULL;
if (!bad_block)
{
switch (version)
{
case 1:
{
LLVector3d pos;
// read position
count = sscanf(buffer + chars_read_total, "position %lf %lf %lf\n%n", pos.mdV + VX, pos.mdV + VY, pos.mdV + VZ, &chars_read);
if (count != 3)
{
bad_block = true;
}
else
{
LL_DEBUGS("Landmark") << "Landmark read: " << pos << LL_ENDL;
result = new LLLandmark(pos);
}
break;
}
case 2:
{
// *NOTE: Changing the buffer size will require changing the
// scanf call below.
char region_id_str[MAX_STRING];
LLVector3 pos;
LLUUID region_id;
count = sscanf( buffer + chars_read_total,
"region_id %254s\n%n",
region_id_str,
&chars_read);
chars_read_total += chars_read;
if (count != 1
|| chars_read_total >= buffer_size
|| !LLUUID::validate(region_id_str))
{
bad_block = true;
}
if (!bad_block)
{
region_id.set(region_id_str);
if (region_id.isNull())
{
bad_block = true;
}
}
if (!bad_block)
{
count = sscanf(buffer + chars_read_total, "local_pos %f %f %f\n%n", pos.mV + VX, pos.mV + VY, pos.mV + VZ, &chars_read);
if (count != 3)
{
bad_block = true;
}
else
{
result = new LLLandmark;
result->mRegionID = region_id;
result->mRegionPos = pos;
}
}
break;
}
default:
{
LL_INFOS("Landmark") << "Encountered Unknown landmark version " << version << LL_ENDL;
break;
}
}
}
if (bad_block)
{
LL_INFOS("Landmark") << "Bad Landmark Asset: bad _DATA_ block." << LL_ENDL;
}
return result;
}
@ -176,7 +220,7 @@ void LLLandmark::requestRegionHandle(
if(region_id.isNull())
{
// don't bother with checking - it's 0.
LL_DEBUGS() << "requestRegionHandle: null" << LL_ENDL;
LL_DEBUGS("Landmark") << "requestRegionHandle: null" << LL_ENDL;
if(callback)
{
const U64 U64_ZERO = 0;
@ -187,7 +231,7 @@ void LLLandmark::requestRegionHandle(
{
if(region_id == mLocalRegion.first)
{
LL_DEBUGS() << "requestRegionHandle: local" << LL_ENDL;
LL_DEBUGS("Landmark") << "requestRegionHandle: local" << LL_ENDL;
if(callback)
{
callback(region_id, mLocalRegion.second);
@ -198,13 +242,13 @@ void LLLandmark::requestRegionHandle(
region_map_t::iterator it = mRegions.find(region_id);
if(it == mRegions.end())
{
LL_DEBUGS() << "requestRegionHandle: upstream" << LL_ENDL;
LL_DEBUGS("Landmark") << "requestRegionHandle: upstream" << LL_ENDL;
if(callback)
{
region_callback_map_t::value_type vt(region_id, callback);
sRegionCallbackMap.insert(vt);
}
LL_DEBUGS() << "Landmark requesting information about: "
LL_DEBUGS("Landmark") << "Landmark requesting information about: "
<< region_id << LL_ENDL;
msg->newMessage("RegionHandleRequest");
msg->nextBlock("RequestBlock");
@ -214,7 +258,7 @@ void LLLandmark::requestRegionHandle(
else if(callback)
{
// we have the answer locally - just call the callack.
LL_DEBUGS() << "requestRegionHandle: ready" << LL_ENDL;
LL_DEBUGS("Landmark") << "requestRegionHandle: ready" << LL_ENDL;
callback(region_id, (*it).second.mRegionHandle);
}
}

View File

@ -60,7 +60,7 @@ public:
// constructs a new LLLandmark from a string
// return NULL if there's an error
static LLLandmark* constructFromString(const char *buffer);
static LLLandmark* constructFromString(const char *buffer, const S32 buffer_size);
// register callbacks that this class handles
static void registerCallbacks(LLMessageSystem* msg);

View File

@ -4,6 +4,7 @@ project(llmath)
include(00-Common)
include(LLCommon)
include(bugsplat)
include(Boost)
include_directories(

View File

@ -138,13 +138,24 @@ LLCoprocedureManager::~LLCoprocedureManager()
close();
}
LLCoprocedureManager::poolPtr_t LLCoprocedureManager::initializePool(const std::string &poolName)
void LLCoprocedureManager::initializePool(const std::string &poolName)
{
poolMap_t::iterator it = mPoolMap.find(poolName);
if (it != mPoolMap.end())
{
// Pools are not supposed to be initialized twice
// Todo: ideally restrict init to STATE_FIRST
LL_WARNS("CoProcMgr") << "Pool is already present " << poolName << LL_ENDL;
return;
}
// Attempt to look up a pool size in the configuration. If found use that
std::string keyName = "PoolSize" + poolName;
int size = 0;
LL_ERRS_IF(poolName.empty(), "CoprocedureManager") << "Poolname must not be empty" << LL_ENDL;
LL_INFOS("CoprocedureManager") << "Initializing pool " << poolName << LL_ENDL;
if (mPropertyQueryFn)
{
@ -171,8 +182,6 @@ LLCoprocedureManager::poolPtr_t LLCoprocedureManager::initializePool(const std::
bool inserted = mPoolMap.emplace(poolName, pool).second;
LL_ERRS_IF(!inserted, "CoprocedureManager") << "Unable to add pool named \"" << poolName << "\" to map. FATAL!" << LL_ENDL;
return pool;
}
//-------------------------------------------------------------------------
@ -182,22 +191,28 @@ LLUUID LLCoprocedureManager::enqueueCoprocedure(const std::string &pool, const s
// not exist, create it.
poolMap_t::iterator it = mPoolMap.find(pool);
poolPtr_t targetPool = (it != mPoolMap.end()) ? it->second : initializePool(pool);
if (it == mPoolMap.end())
{
// initializing pools in enqueueCoprocedure is not thread safe,
// at the moment pools need to be initialized manually
LL_ERRS() << "Uninitialized pool " << pool << LL_ENDL;
}
poolPtr_t targetPool = it->second;
return targetPool->enqueueCoprocedure(name, proc);
}
void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpdate_t updatefn)
{
// functions to discover and store the pool sizes
// Might be a better idea to make an initializePool(name, size) to init everything externally
mPropertyQueryFn = queryfn;
mPropertyDefineFn = updatefn;
// workaround until we get mutex into initializePool
initializePool("AssetStorage");
initializePool("Upload");
initializePool("AIS");
initializePool("ExpCache"); // <FS:Ansariel> FIRE-30731: ExpCache coroutine pool crash
initializePool("AIS"); // it might be better to have some kind of on-demand initialization for AIS
// "ExpCache" pool gets initialized in LLExperienceCache
// asset storage pool gets initialized in LLViewerAssetStorage
}
//-------------------------------------------------------------------------

View File

@ -79,6 +79,8 @@ public:
void close();
void close(const std::string &pool);
void initializePool(const std::string &poolName);
private:
@ -87,8 +89,6 @@ private:
poolMap_t mPoolMap;
poolPtr_t initializePool(const std::string &poolName);
SettingQuery_t mPropertyQueryFn;
SettingUpdate_t mPropertyDefineFn;

View File

@ -114,6 +114,8 @@ void LLExperienceCache::initSingleton()
cache_stream >> (*this);
}
LLCoprocedureManager::instance().initializePool("ExpCache");
LLCoros::instance().launch("LLExperienceCache::idleCoro",
boost::bind(&LLExperienceCache::idleCoro, this));

View File

@ -91,6 +91,7 @@ namespace tut
{
Sync sync;
int foo = 0;
LLCoprocedureManager::instance().initializePool("PoolName");
LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName",
[&foo, &sync] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) {
sync.bump();

View File

@ -50,6 +50,7 @@ U32 LLRender::sUIVerts = 0;
U32 LLTexUnit::sWhiteTexture = 0;
bool LLRender::sGLCoreProfile = false;
bool LLRender::sNsightDebugSupport = false;
LLVector2 LLRender::sUIGLScaleFactor = LLVector2(1.f, 1.f);
static const U32 LL_NUM_TEXTURE_LAYERS = 32;
static const U32 LL_NUM_LIGHT_UNITS = 8;

View File

@ -480,6 +480,7 @@ public:
static U32 sUIVerts;
static bool sGLCoreProfile;
static bool sNsightDebugSupport;
static LLVector2 sUIGLScaleFactor;
private:
friend class LLLightState;

View File

@ -106,11 +106,10 @@ void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixe
top += LLFontGL::sCurOrigin.mY;
gGL.loadUIIdentity();
LLRender2D *r2d_inst = LLRender2D::getInstance();
gl_rect_2d(llfloor((F32)left * r2d_inst->mGLScaleFactor.mV[VX]) - pixel_offset,
llfloor((F32)top * r2d_inst->mGLScaleFactor.mV[VY]) + pixel_offset,
llfloor((F32)right * r2d_inst->mGLScaleFactor.mV[VX]) + pixel_offset,
llfloor((F32)bottom * r2d_inst->mGLScaleFactor.mV[VY]) - pixel_offset,
gl_rect_2d(llfloor((F32)left * LLRender::sUIGLScaleFactor.mV[VX]) - pixel_offset,
llfloor((F32)top * LLRender::sUIGLScaleFactor.mV[VY]) + pixel_offset,
llfloor((F32)right * LLRender::sUIGLScaleFactor.mV[VX]) + pixel_offset,
llfloor((F32)bottom * LLRender::sUIGLScaleFactor.mV[VY]) - pixel_offset,
filled);
gGL.popUIMatrix();
}
@ -2017,7 +2016,6 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv
LLRender2D::LLRender2D(LLImageProviderInterface* image_provider)
{
mGLScaleFactor = LLVector2(1.f, 1.f);
mImageProvider = image_provider;
if(mImageProvider)
{
@ -2034,7 +2032,7 @@ LLRender2D::~LLRender2D()
}
}
// static
void LLRender2D::translate(F32 x, F32 y, F32 z)
{
gGL.translateUI(x,y,z);
@ -2043,12 +2041,14 @@ void LLRender2D::translate(F32 x, F32 y, F32 z)
LLFontGL::sCurDepth += z;
}
// static
void LLRender2D::pushMatrix()
{
gGL.pushUIMatrix();
LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));
}
// static
void LLRender2D::popMatrix()
{
gGL.popUIMatrix();
@ -2057,6 +2057,7 @@ void LLRender2D::popMatrix()
LLFontGL::sOriginStack.pop_back();
}
// static
void LLRender2D::loadIdentity()
{
gGL.loadUIIdentity();
@ -2065,17 +2066,13 @@ void LLRender2D::loadIdentity()
LLFontGL::sCurDepth = 0.f;
}
void LLRender2D::setScaleFactor(const LLVector2 &scale_factor)
{
mGLScaleFactor = scale_factor;
}
// static
void LLRender2D::setLineWidth(F32 width)
{
// <FS> Line width OGL core profile fix by Rye Mutt
//gGL.flush();
//glLineWidth(width * lerp(mGLScaleFactor.mV[VX], mGLScaleFactor.mV[VY], 0.5f));
gGL.setLineWidth(width * lerp(mGLScaleFactor.mV[VX], mGLScaleFactor.mV[VY], 0.5f));
//glLineWidth(width * lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f));
gGL.setLineWidth(width * lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f));
}
LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority)

View File

@ -128,19 +128,16 @@ class LLRender2D : public LLParamSingleton<LLRender2D>
LOG_CLASS(LLRender2D);
~LLRender2D();
public:
void pushMatrix();
void popMatrix();
void loadIdentity();
void translate(F32 x, F32 y, F32 z = 0.0f);
static void pushMatrix();
static void popMatrix();
static void loadIdentity();
static void translate(F32 x, F32 y, F32 z = 0.0f);
void setLineWidth(F32 width);
void setScaleFactor(const LLVector2& scale_factor);
static void setLineWidth(F32 width);
LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
LLVector2 mGLScaleFactor;
protected:
// since LLRender2D has no control of image provider's lifecycle
// we need a way to tell LLRender2D that provider died and

View File

@ -1006,7 +1006,7 @@ void LLAccordionCtrlTab::drawChild(const LLRect& root_rect,LLView* child)
LLRect screen_rect;
localRectToScreen(child->getRect(),&screen_rect);
if ( root_rect.overlaps(screen_rect) && LLUI::getInstance()->mDirtyRect.overlaps(screen_rect))
if ( root_rect.overlaps(screen_rect) && sDirtyRect.overlaps(screen_rect))
{
gGL.matrixMode(LLRender::MM_MODELVIEW);
LLUI::pushMatrix();

View File

@ -219,7 +219,9 @@ void LLConsole::draw()
// <FS> Different draw options
//LLUIImagePtr imagep = LLUI::getUIImage("transparent");
//F32 console_opacity = llclamp(LLUI::getInstance()->mSettingGroups["config"]->getF32("ConsoleBackgroundOpacity"), 0.f, 1.f);
//static LLCachedControl<F32> console_bg_opacity(*LLUI::getInstance()->mSettingGroups["config"], "ConsoleBackgroundOpacity", 0.7f);
//F32 console_opacity = llclamp(console_bg_opacity(), 0.f, 1.f);
//LLColor4 color = LLUIColorTable::instance().getColor("ConsoleBackground");
//color.mV[VALPHA] *= console_opacity;

View File

@ -416,13 +416,15 @@ void LLFloater::layoutDragHandle()
// static
void LLFloater::updateActiveFloaterTransparency()
{
sActiveControlTransparency = LLUI::getInstance()->mSettingGroups["config"]->getF32("ActiveFloaterTransparency");
static LLCachedControl<F32> active_transparency(*LLUI::getInstance()->mSettingGroups["config"], "ActiveFloaterTransparency", 1.f);
sActiveControlTransparency = active_transparency;
}
// static
void LLFloater::updateInactiveFloaterTransparency()
{
sInactiveControlTransparency = LLUI::getInstance()->mSettingGroups["config"]->getF32("InactiveFloaterTransparency");
static LLCachedControl<F32> inactive_transparency(*LLUI::getInstance()->mSettingGroups["config"], "InactiveFloaterTransparency", 0.95f);
sInactiveControlTransparency = inactive_transparency;
}
void LLFloater::addResizeCtrls()

View File

@ -348,9 +348,9 @@ static LLTrace::BlockTimerStatHandle FTM_FILTER("Filter Folder View");
void LLFolderView::filter( LLFolderViewFilter& filter )
{
LL_RECORD_BLOCK_TIME(FTM_FILTER);
static LLCachedControl<S32> filter_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
static LLCachedControl<S32> filter_hidden(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameUnvisible", 1);
filter.resetTime(llclamp(mParentPanel.get()->getVisible() ? filter_visible() : filter_hidden(), 1, 100));
static LLCachedControl<S32> time_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
static LLCachedControl<S32> time_invisible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameUnvisible", 1);
filter.resetTime(llclamp((mParentPanel.get()->getVisible() ? time_visible() : time_invisible()), 1, 100));
// Note: we filter the model, not the view
getViewModelItem()->filter(filter);
@ -687,11 +687,8 @@ void LLFolderView::draw()
closeAutoOpenedFolders();
}
// <FS:Ansariel> Performance improvement
//if (mSearchTimer.getElapsedTimeF32() > LLUI::getInstance()->mSettingGroups["config"]->getF32("TypeAheadTimeout") || !mSearchString.size())
static LLCachedControl<F32> typeAheadTimeout(*LLUI::getInstance()->mSettingGroups["config"], "TypeAheadTimeout");
if (mSearchTimer.getElapsedTimeF32() > typeAheadTimeout || !mSearchString.size())
// </FS:Ansariel>
static LLCachedControl<F32> type_ahead_timeout(*LLUI::getInstance()->mSettingGroups["config"], "TypeAheadTimeout", 1.5f);
if (mSearchTimer.getElapsedTimeF32() > type_ahead_timeout || !mSearchString.size())
{
mSearchString.clear();
}

View File

@ -1052,9 +1052,10 @@ void LLFolderViewItem::draw()
//
if (filter_string_length > 0)
{
F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mViewModelItem->getFilterStringOffset());
S32 filter_offset = mViewModelItem->getFilterStringOffset();
F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, filter_offset + filter_string_length) - font->getWidthF32(combined_string, filter_offset, filter_string_length);
F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
font->renderUTF8( combined_string, mViewModelItem->getFilterStringOffset(), match_string_left, yy,
font->renderUTF8( combined_string, filter_offset, match_string_left, yy,
sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
filter_string_length, S32_MAX, &right_x, FALSE );
}
@ -1724,7 +1725,7 @@ void LLFolderViewFolder::destroyView()
// extractItem() removes the specified item from the folder, but
// doesn't delete it.
void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
void LLFolderViewFolder::extractItem( LLFolderViewItem* item, bool deparent_model )
{
if (item->isSelected())
getRoot()->clearSelection();
@ -1747,7 +1748,11 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
mItems.erase(it);
}
//item has been removed, need to update filter
getViewModelItem()->removeChild(item->getViewModelItem());
if (deparent_model)
{
// in some cases model does not belong to parent view, is shared between views
getViewModelItem()->removeChild(item->getViewModelItem());
}
//because an item is going away regardless of filter status, force rearrange
requestArrange();
removeChild(item);

View File

@ -413,7 +413,7 @@ public:
// extractItem() removes the specified item from the folder, but
// doesn't delete it.
virtual void extractItem( LLFolderViewItem* item );
virtual void extractItem( LLFolderViewItem* item, bool deparent_model = true);
// This function is called by a child that needs to be resorted.
void resort(LLFolderViewItem* item);

View File

@ -48,9 +48,9 @@ std::string LLFolderViewModelCommon::getStatusText()
void LLFolderViewModelCommon::filter()
{
static LLCachedControl<S32> filter_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
getFilter().resetTime(llclamp(filter_visible(), 1, 100));
mFolderView->getViewModelItem()->filter(getFilter());
static LLCachedControl<S32> max_time(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
getFilter().resetTime(llclamp(max_time(), 1, 100));
mFolderView->getViewModelItem()->filter(getFilter());
}
bool LLFolderViewModelItemCommon::hasFilterStringMatch()

View File

@ -3378,7 +3378,11 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y, S3
CURSOR_WIDTH + MOUSE_CURSOR_PADDING * 2,
CURSOR_HEIGHT + MOUSE_CURSOR_PADDING * 2);
menu->translateIntoRectWithExclusion( menu_region_rect, mouse_rect );
if (menu->getRect().mTop > menu_region_rect.mTop)
// <FS:Ansariel> FIRE-31065: Make sure menu is shown on the screen properly
//if (menu->getRect().mTop > menu_region_rect.mTop)
if (menu->getRect().mTop > menu_region_rect.mTop ||
menu->getRect().mBottom < menu_region_rect.mBottom)
// </FS:Ansariel>
{
// not enough space: align with top, ignore exclusion
menu->translateIntoRect( menu_region_rect );

View File

@ -136,6 +136,7 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
}
}
mRoundedSquareImgp = LLUI::getUIImage("Rounded_Square");
if (p.thumb_image.isProvided())
{
mThumbImagep = LLUI::getUIImage(p.thumb_image());
@ -666,8 +667,6 @@ void LLMultiSlider::draw()
F32 opacity = getEnabled() ? 1.f : 0.3f;
// Track
LLUIImagePtr thumb_imagep = LLUI::getUIImage("Rounded_Square");
static LLUICachedControl<S32> multi_track_height_width ("UIMultiTrackHeight", 0);
S32 height_offset = 0;
S32 width_offset = 0;
@ -685,7 +684,7 @@ void LLMultiSlider::draw()
if(mDrawTrack)
{
track_rect.stretch(-1);
thumb_imagep->draw(track_rect, mTrackColor.get() % opacity);
mRoundedSquareImgp->draw(track_rect, mTrackColor.get() % opacity);
}
// if we're supposed to use a drawn triangle
@ -704,7 +703,7 @@ void LLMultiSlider::draw()
mTriangleColor.get() % opacity, TRUE);
}
}
else if (!thumb_imagep && !mThumbImagep)
else if (!mRoundedSquareImgp && !mThumbImagep)
{
// draw all the thumbs
curSldrIt = mThumbRects.end();
@ -757,7 +756,7 @@ void LLMultiSlider::draw()
}
else
{
thumb_imagep->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f);
mRoundedSquareImgp->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f);
}
}
@ -772,7 +771,7 @@ void LLMultiSlider::draw()
}
else
{
thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
mRoundedSquareImgp->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
}
}
}
@ -784,7 +783,7 @@ void LLMultiSlider::draw()
}
else
{
thumb_imagep->drawBorder(mThumbRects[mHoverSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
mRoundedSquareImgp->drawBorder(mThumbRects[mHoverSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
}
}
@ -822,11 +821,11 @@ void LLMultiSlider::draw()
}
else if (capture == this)
{
thumb_imagep->drawSolid(mIt->second, curThumbColor);
mRoundedSquareImgp->drawSolid(mIt->second, curThumbColor);
}
else
{
thumb_imagep->drawSolid(mIt->second, curThumbColor % opacity);
mRoundedSquareImgp->drawSolid(mIt->second, curThumbColor % opacity);
}
}
@ -846,11 +845,11 @@ void LLMultiSlider::draw()
}
else if (capture == this)
{
thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get());
mRoundedSquareImgp->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get());
}
else
{
thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get() % opacity);
mRoundedSquareImgp->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get() % opacity);
}
}
if(hoverSldrIt != mThumbRects.end())
@ -861,7 +860,7 @@ void LLMultiSlider::draw()
}
else
{
thumb_imagep->drawSolid(hoverSldrIt->second, mThumbCenterSelectedColor.get());
mRoundedSquareImgp->drawSolid(hoverSldrIt->second, mThumbCenterSelectedColor.get());
}
}
}

View File

@ -150,6 +150,7 @@ protected:
LLUIColor mDisabledThumbColor;
LLUIColor mTriangleColor;
LLUIImagePtr mThumbImagep; //blimps on the slider, for now no 'disabled' support
LLUIImagePtr mRoundedSquareImgp; //blimps on the slider, for now no 'disabled' support
const EOrientation mOrientation;

View File

@ -27,9 +27,8 @@
// Many classes just store a single LLNotificationPtr
// and llnotifications.h is very large, so define this ligher header.
#include <boost/shared_ptr.hpp>
class LLNotification;
typedef boost::shared_ptr<LLNotification> LLNotificationPtr;
typedef std::shared_ptr<LLNotification> LLNotificationPtr;
#endif

View File

@ -85,7 +85,6 @@
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/type_traits.hpp>
#include <boost/signals2.hpp>
#include <boost/range.hpp>
@ -307,7 +306,7 @@ typedef boost::shared_ptr<LLNotificationVisibilityRule> LLNotificationVisibility
*/
class LLNotification :
boost::noncopyable,
public boost::enable_shared_from_this<LLNotification>
public std::enable_shared_from_this<LLNotification>
{
LOG_CLASS(LLNotification);
friend class LLNotifications;
@ -763,7 +762,10 @@ public:
: mFilter(filter),
mItems()
{}
virtual ~LLNotificationChannelBase() {}
virtual ~LLNotificationChannelBase()
{
mItems.clear();
}
// you can also connect to a Channel, so you can be notified of
// changes to this channel
LLBoundListener connectChanged(const LLEventListener& slot)
@ -893,6 +895,7 @@ class LLNotifications :
{
LLSINGLETON(LLNotifications);
LOG_CLASS(LLNotifications);
virtual ~LLNotifications() {}
public:
@ -1093,7 +1096,11 @@ public:
LLPersistentNotificationChannel()
: LLNotificationChannel("Persistent", "Visible", &notificationFilter)
{}
virtual ~LLPersistentNotificationChannel() {}
virtual ~LLPersistentNotificationChannel()
{
mHistory.clear();
}
typedef std::vector<LLNotificationPtr> history_list_t;
history_list_t::iterator beginHistory() { sortHistory(); return mHistory.begin(); }

View File

@ -2193,6 +2193,13 @@ void LLTextEditor::showContextMenu(S32 x, S32 y, bool set_cursor_pos)
mContextMenu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>("menu_text_editor.xml",
LLMenuGL::sMenuContainer,
LLMenuHolderGL::child_registry_t::instance());
// <FS:Beq> FIRE-31081 defend against null this prt exception in setItemVisible found in BugSplat
if(!mContextMenu)
{
LL_WARNS() << "Failed to create context menu 'menu_text_editor'" << LL_ENDL;
return;
}
// </FS:Beq>
}
// Route menu to this class

View File

@ -1337,7 +1337,7 @@ BOOL LLToolBarButton::handleHover(S32 x, S32 y, MASK mask)
BOOL handled = FALSE;
S32 mouse_distance_squared = (x - mMouseDownX) * (x - mMouseDownX) + (y - mMouseDownY) * (y - mMouseDownY);
S32 drag_threshold = LLUI::getInstance()->mSettingGroups["config"]->getS32("DragAndDropDistanceThreshold");
static LLCachedControl<S32> drag_threshold(*LLUI::getInstance()->mSettingGroups["config"], "DragAndDropDistanceThreshold", 3);
if (mouse_distance_squared > drag_threshold * drag_threshold
&& hasMouseCapture() &&
mStartDragItemCallback && mHandleDragItemCallback)

View File

@ -358,8 +358,8 @@ void LLToolTip::draw()
if (mFadeTimer.getStarted())
{
F32 tool_tip_fade_time = LLUI::getInstance()->mSettingGroups["config"]->getF32("ToolTipFadeTime");
alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, tool_tip_fade_time, 1.f, 0.f);
static LLCachedControl<F32> tool_tip_fade_time(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipFadeTime", 0.2f);
alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, tool_tip_fade_time(), 1.f, 0.f);
if (alpha == 0.f)
{
// finished fading out, so hide ourselves

View File

@ -178,7 +178,6 @@ mAudioCallback(audio_callback),
mDeferredAudioCallback(deferred_audio_callback),
mWindow(NULL), // set later in startup
mRootView(NULL),
mDirty(FALSE),
mHelpImpl(NULL)
{
LLRender2D::initParamSingleton(image_provider);
@ -230,19 +229,6 @@ void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& rem
mClearPopupsFunc = clear_popups;
}
void LLUI::dirtyRect(LLRect rect)
{
if (!mDirty)
{
mDirtyRect = rect;
mDirty = TRUE;
}
else
{
mDirtyRect.unionWith(rect);
}
}
void LLUI::setMousePositionScreen(S32 x, S32 y)
{
#if defined(LL_DARWIN)
@ -577,6 +563,18 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path)
return context;
}
//static
LLVector2& LLUI::getScaleFactor()
{
return LLRender::sUIGLScaleFactor;
}
//static
void LLUI::setScaleFactor(const LLVector2& scale_factor)
{
LLRender::sUIGLScaleFactor = scale_factor;
}
// LLLocalClipRect and LLScreenClipRect moved to lllocalcliprect.h/cpp

View File

@ -250,10 +250,6 @@ public:
void setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t&, const clear_popups_t& );
LLRect mDirtyRect;
BOOL mDirty;
void dirtyRect(LLRect rect);
// Return the ISO639 language name ("en", "ko", etc.) for the viewer UI.
// http://www.loc.gov/standards/iso639-2/php/code_list.php
// <FS:Ansariel> FIRE-16709: Bypass FSEnabledLanguages for llGetAgentLanguage
@ -321,14 +317,14 @@ public:
void positionViewNearMouse(LLView* view, S32 spawn_x = S32_MAX, S32 spawn_y = S32_MAX);
// LLRender2D wrappers
static void pushMatrix() { LLRender2D::getInstance()->pushMatrix(); }
static void popMatrix() { LLRender2D::getInstance()->popMatrix(); }
static void loadIdentity() { LLRender2D::getInstance()->loadIdentity(); }
static void translate(F32 x, F32 y, F32 z = 0.0f) { LLRender2D::getInstance()->translate(x, y, z); }
static void pushMatrix() { LLRender2D::pushMatrix(); }
static void popMatrix() { LLRender2D::popMatrix(); }
static void loadIdentity() { LLRender2D::loadIdentity(); }
static void translate(F32 x, F32 y, F32 z = 0.0f) { LLRender2D::translate(x, y, z); }
static LLVector2& getScaleFactor() { return LLRender2D::getInstance()->mGLScaleFactor; }
static void setScaleFactor(const LLVector2& scale_factor) { LLRender2D::getInstance()->setScaleFactor(scale_factor); }
static void setLineWidth(F32 width) { LLRender2D::getInstance()->setLineWidth(width); }
static LLVector2& getScaleFactor();
static void setScaleFactor(const LLVector2& scale_factor);
static void setLineWidth(F32 width) { LLRender2D::setLineWidth(width); }
static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0)
{ return LLRender2D::getInstance()->getUIImageByID(image_id, priority); }
static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0)

View File

@ -179,7 +179,7 @@ void LLUrlEntryBase::callObservers(const std::string &id,
bool LLUrlEntryBase::isLinkDisabled() const
{
// this allows us to have a global setting to turn off text hyperlink highlighting/action
bool globally_disabled = LLUI::getInstance()->mSettingGroups["config"]->getBOOL("DisableTextHyperlinkActions");
static LLCachedControl<bool> globally_disabled(*LLUI::getInstance()->mSettingGroups["config"], "DisableTextHyperlinkActions", false);
return globally_disabled;
}
@ -529,7 +529,9 @@ LLUrlEntrySecondlifeURL::LLUrlEntrySecondlifeURL()
"|"
"(https://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(:\\d{1,5})?)"
"|"
"(https://([-\\w\\.]*\\.)?secondlifegrid\\.net(:\\d{1,5})?))"
"(https://([-\\w\\.]*\\.)?secondlifegrid\\.net(:\\d{1,5})?)"
"|"
"(https?://([-\\w\\.]*\\.)?secondlife\\.io(:\\d{1,5})?))"
"\\/\\S*",
boost::regex::perl|boost::regex::icase);
@ -1275,7 +1277,7 @@ std::string LLUrlEntryPlace::getLocation(const std::string &url) const
//
LLUrlEntryRegion::LLUrlEntryRegion()
{
mPattern = boost::regex("secondlife:///app/region/[^/\\s]+(/\\d+)?(/\\d+)?(/\\d+)?/?",
mPattern = boost::regex("secondlife:///app/region/[A-Za-z0-9()_%]+(/\\d+)?(/\\d+)?(/\\d+)?/?",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_slurl.xml";
mTooltip = LLTrans::getString("TooltipSLURL");

View File

@ -65,6 +65,8 @@ static const S32 LINE_HEIGHT = 15;
S32 LLView::sDepth = 0;
bool LLView::sDebugRects = false;
bool LLView::sIsRectDirty = false;
LLRect LLView::sDirtyRect;
bool LLView::sDebugRectsShowNames = true;
bool LLView::sDebugKeys = false;
bool LLView::sDebugMouseHandling = false;
@ -941,14 +943,16 @@ BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask)
std::string tooltip = getToolTip();
if (!tooltip.empty())
{
static LLCachedControl<F32> tooltip_fast_delay(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipFastDelay", 0.1f);
static LLCachedControl<F32> tooltip_delay(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipDelay", 0.7f);
static LLCachedControl<bool> allow_ui_tooltips(*LLUI::getInstance()->mSettingGroups["config"], "BasicUITooltips", true);
// allow "scrubbing" over ui by showing next tooltip immediately
// if previous one was still visible
F32 timeout = LLToolTipMgr::instance().toolTipVisible()
? LLUI::getInstance()->mSettingGroups["config"]->getF32( "ToolTipFastDelay" )
: LLUI::getInstance()->mSettingGroups["config"]->getF32( "ToolTipDelay" );
? tooltip_fast_delay
: tooltip_delay;
// Even if we don't show tooltips, consume the event, nothing below should show tooltip
bool allow_ui_tooltips = LLUI::getInstance()->mSettingGroups["config"]->getBOOL("BasicUITooltips");
if (allow_ui_tooltips)
{
LLToolTipMgr::instance().show(LLToolTip::Params()
@ -1245,7 +1249,7 @@ void LLView::drawChildren()
if (viewp->getVisible() && viewp->getRect().isValid())
{
LLRect screen_rect = viewp->calcScreenRect();
if ( rootp->getLocalRect().overlaps(screen_rect) && LLUI::getInstance()->mDirtyRect.overlaps(screen_rect))
if ( rootp->getLocalRect().overlaps(screen_rect) && sDirtyRect.overlaps(screen_rect))
{
LLUI::pushMatrix();
{
@ -1287,7 +1291,15 @@ void LLView::dirtyRect()
parent = parent->getParent();
}
LLUI::getInstance()->dirtyRect(cur->calcScreenRect());
if (!sIsRectDirty)
{
sDirtyRect = cur->calcScreenRect();
sIsRectDirty = true;
}
else
{
sDirtyRect.unionWith(cur->calcScreenRect());
}
}
//Draw a box for debugging.

View File

@ -671,6 +671,9 @@ public:
// Draw debug rectangles around widgets to help with alignment and spacing
static bool sDebugRects;
static bool sIsRectDirty;
static LLRect sDirtyRect;
// Draw widget names and sizes when drawing debug rectangles, turning this
// off is useful to make the rectangles themselves easier to see.
static bool sDebugRectsShowNames;

View File

@ -739,11 +739,6 @@ namespace tut
"XXX secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30 XXX",
"secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30");
// DEV-35459: SLURLs and teleport Links not parsed properly
testRegex("Region with quote", url,
"XXX secondlife:///app/region/A'ksha%20Oasis/41/166/701 XXX",
"secondlife:///app/region/A%27ksha%20Oasis/41/166/701");
// Rendering tests.
testLabel("Render /app/region/Ahern/50/50/50/", url,
"secondlife:///app/region/Ahern/50/50/50/",

View File

@ -0,0 +1,3 @@
This component is no longer used in Linden Lab builds.
Change requests to support continued use by open source
builds are welcome.

View File

@ -8,9 +8,7 @@ include(00-Common)
include(Linking)
include(Boost)
if (BUGSPLAT_DB)
include(bugsplat)
endif (BUGSPLAT_DB)
include(bugsplat)
include(BuildPackagesInfo)
include(BuildVersion)
include(CMakeCopyIfDifferent)
@ -110,18 +108,18 @@ include_directories(
${CMAKE_CURRENT_BINARY_DIR}
)
if (BUGSPLAT_DB)
include_directories(
${BUGSPLAT_INCLUDE_DIR}
)
endif (BUGSPLAT_DB)
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
${LLXML_SYSTEM_INCLUDE_DIRS}
${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
)
if (USE_BUGSPLAT)
include_directories(AFTER
${BUGSPLAT_INCLUDE_DIR}
)
endif (USE_BUGSPLAT)
set(viewer_SOURCE_FILES
# <Add FS includes below this line>
alfloaterregiontracker.cpp
@ -1744,11 +1742,11 @@ if (DARWIN)
${COREAUDIO_LIBRARY}
)
if (BUGSPLAT_DB)
if (USE_BUGSPLAT)
list(APPEND viewer_LIBRARIES
${BUGSPLAT_LIBRARIES}
)
endif (BUGSPLAT_DB)
endif (USE_BUGSPLAT)
# Add resource files to the project.
set(viewer_RESOURCE_FILES
@ -2196,10 +2194,10 @@ if (SDL_FOUND)
)
endif (SDL_FOUND)
if (BUGSPLAT_DB)
if (USE_BUGSPLAT)
set_property(TARGET ${VIEWER_BINARY_NAME}
PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT")
endif (BUGSPLAT_DB)
PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
endif (USE_BUGSPLAT)
# add package files
file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
@ -2285,9 +2283,12 @@ if (WINDOWS)
media_plugin_cef
media_plugin_libvlc
#media_plugin_example # <FS:Ansariel> Don't package example plugin
windows-crash-logger
)
if (NOT USE_BUGSPLAT)
LIST(APPEND COPY_INPUT_DEPENDENCIES windows-crash-logger)
endif (NOT USE_BUGSPLAT)
# <FS:Ansariel> Only copy OpenJPEG dll if needed
if (NOT USE_KDU)
list(APPEND COPY_INPUT_DEPENDENCIES
@ -2361,10 +2362,11 @@ if (WINDOWS)
add_dependencies(${VIEWER_BINARY_NAME} copy_win_scripts)
endif (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts)
add_dependencies(${VIEWER_BINARY_NAME}
SLPlugin
windows-crash-logger
)
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin)
if (NOT USE_BUGSPLAT)
add_dependencies(${VIEWER_BINARY_NAME} windows-crash-logger)
endif (NOT USE_BUGSPLAT)
# sets the 'working directory' for debugging from visual studio.
# Condition for version can be moved to requirements once build agents will be updated (see TOOL-3865)
@ -2527,11 +2529,11 @@ target_link_libraries(${VIEWER_BINARY_NAME}
target_link_libraries(${VIEWER_BINARY_NAME} ${DISCORD_LIBRARY} )
if (BUGSPLAT_DB)
if (USE_BUGSPLAT)
target_link_libraries(${VIEWER_BINARY_NAME}
${BUGSPLAT_LIBRARIES}
)
endif (BUGSPLAT_DB)
endif (USE_BUGSPLAT)
if (WINDOWS)
target_link_libraries(${VIEWER_BINARY_NAME}
@ -2553,7 +2555,6 @@ if (LINUX)
if (NOT ENABLE_MEDIA_PLUGINS)
set(COPY_INPUT_DEPENDENCIES
${VIEWER_BINARY_NAME}
linux-crash-logger
SLPlugin
media_plugin_cef
#media_plugin_gstreamer010
@ -2571,6 +2572,10 @@ else (NOT ENABLE_MEDIA_PLUGINS)
)
endif (NOT ENABLE_MEDIA_PLUGINS)
if (NOT USE_BUGSPLAT)
LIST(APPEND COPY_INPUT_DEPENDENCIES linux-crash-logger)
endif (NOT USE_BUGSPLAT)
add_custom_command(
OUTPUT ${product}.tar.bz2
COMMAND ${PYTHON_EXECUTABLE}
@ -2719,8 +2724,11 @@ if (DARWIN)
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
)
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef mac-crash-logger)
add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger)
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef)
if (NOT USE_BUGSPLAT)
add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger)
endif (NOT USE_BUGSPLAT)
if (ENABLE_SIGNING)
set(SIGNING_SETTING "--signature=${SIGNING_IDENTITY}")
@ -2764,7 +2772,7 @@ endif (INSTALL)
# Note that the conventional VIEWER_SYMBOL_FILE is set by ../../build.sh
if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIEWER_SYMBOL_FILE)
if (NOT BUGSPLAT_DB)
if (NOT USE_BUGSPLAT)
# Breakpad symbol-file generation
set(SYMBOL_SEARCH_DIRS "")
if (WINDOWS)
@ -2781,7 +2789,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
## set(VIEWER_EXE_GLOBS "'${product}' SLPlugin mac-crash-logger")
## set(VIEWER_EXE_GLOBS "'${product}' SLPlugin")
set(VIEWER_EXE_GLOBS "'${product}' mac-crash-logger")
set(VIEWER_LIB_GLOB "*.dylib")
endif (DARWIN)
@ -2820,7 +2828,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
add_dependencies(generate_symbols "${VIEWER_COPY_MANIFEST}")
endif (WINDOWS OR LINUX)
else (NOT BUGSPLAT_DB)
else (NOT USE_BUGSPLAT)
# BugSplat symbol-file generation
if (WINDOWS)
# Just pack up a tarball containing only the .pdb file for the
@ -2904,9 +2912,9 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
if (LINUX)
# TBD
endif (LINUX)
endif (NOT BUGSPLAT_DB)
endif (NOT USE_BUGSPLAT)
# for both BUGSPLAT_DB and Breakpad
# for both Bugsplat and Breakpad
add_dependencies(llpackage generate_symbols)
endif ()
@ -3048,6 +3056,10 @@ if (LL_TESTS)
${BOOST_CONTEXT_LIBRARY}
)
LL_ADD_INTEGRATION_TEST(cppfeatures
""
"${test_libs}"
)
LL_ADD_INTEGRATION_TEST(llsechandler_basic
llsechandler_basic.cpp
"${test_libs}"

View File

@ -1 +1 @@
6.4.21
6.4.22

View File

@ -17965,19 +17965,6 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>1</integer>
</map>
<!-- SL-12594 removes fixed function rendering
<key>VertexShaderEnable</key>
<map>
<key>Comment</key>
<string>Enable/disable all GLSL shaders (debug)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
-->
<key>VivoxAutoPostCrashDumps</key>
<map>
<key>Comment</key>
@ -18114,8 +18101,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>VivoxVadSensitivity</key>
<map>
<key>Comment</key>
<string>
A dimensionless value between 0 and 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds to decreasing the sensitivity of the VAD and 0 is turned off altogether</string>
<string>A dimensionless value between 0 and 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds to decreasing the sensitivity of the VAD and 0 is turned off altogether</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>

View File

@ -0,0 +1,28 @@
LLWearable version 22
RASL SOCKS BROWN
permissions 0
{
base_mask 7fffffff
owner_mask 7fffffff
group_mask 00000000
everyone_mask 00000000
next_owner_mask 00082000
creator_id 79908808-d272-49a8-864a-d133a10931e9
owner_id 79908808-d272-49a8-864a-d133a10931e9
last_owner_id 79908808-d272-49a8-864a-d133a10931e9
group_id 00000000-0000-0000-0000-000000000000
}
sale_info 0
{
sale_type not
sale_price 10
}
type 7
parameters 4
617 1
818 1
819 1
820 1
textures 1
12 301a3097-2858-7614-829d-c5859741246f

View File

@ -0,0 +1,34 @@
LLWearable version 22
RASL F SHOP SHOES FOOTSHAPER
permissions 0
{
base_mask 7fffffff
owner_mask 7fffffff
group_mask 00000000
everyone_mask 00000000
next_owner_mask 00082000
creator_id df110c10-72e6-40d6-8916-14b4b0366b18
owner_id df110c10-72e6-40d6-8916-14b4b0366b18
last_owner_id df110c10-72e6-40d6-8916-14b4b0366b18
group_id 00000000-0000-0000-0000-000000000000
}
sale_info 0
{
sale_type not
sale_price 10
}
type 6
parameters 10
198 1
503 .17
508 -1
513 0
514 .37
616 .1
654 .08
812 1
813 1
817 1
textures 1
7 3ab7e2fa-9572-ef36-1a30-d855dbea4f92

View File

@ -0,0 +1,29 @@
LLWearable version 22
RASL F LEARN LEGGINGS
permissions 0
{
base_mask 7fffffff
owner_mask 7fffffff
group_mask 00000000
everyone_mask 00000000
next_owner_mask 00082000
creator_id 79908808-d272-49a8-864a-d133a10931e9
owner_id 79908808-d272-49a8-864a-d133a10931e9
last_owner_id 79908808-d272-49a8-864a-d133a10931e9
group_id 00000000-0000-0000-0000-000000000000
}
sale_info 0
{
sale_type not
sale_price 10
}
type 11
parameters 5
619 1
624 1
824 1
825 1
826 1
textures 1
17 6f5d29ce-548f-fdd0-b8e1-1f90a123b76e

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