diff options
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/CMakeLists.txt | 77 | ||||
-rw-r--r-- | indra/llcommon/apply.h | 115 | ||||
-rw-r--r-- | indra/llcommon/llapp.cpp | 43 | ||||
-rw-r--r-- | indra/llcommon/llerrorthread.cpp | 2 | ||||
-rw-r--r-- | indra/llcommon/llprocess.cpp | 8 | ||||
-rw-r--r-- | indra/llcommon/llsd.h | 12 | ||||
-rw-r--r-- | indra/llcommon/llsdjson.h | 2 | ||||
-rw-r--r-- | indra/llcommon/llstl.h | 81 | ||||
-rw-r--r-- | indra/llcommon/stringize.h | 2 | ||||
-rw-r--r-- | indra/llcommon/tests/llleap_test.cpp | 14 |
10 files changed, 188 insertions, 168 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 3371306f11..620b2c636c 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -15,19 +15,6 @@ include(ZLIBNG) include(URIPARSER) include(Tracy) -include_directories( - ${EXPAT_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${JSONCPP_INCLUDE_DIR} - ${ZLIBNG_INCLUDE_DIRS} - ${URIPARSER_INCLUDE_DIRS} - ${TRACY_INCLUDE_DIR} - ) - -# add_executable(lltreeiterators lltreeiterators.cpp) -# -# target_link_libraries(lltreeiterators -# ${LLCOMMON_LIBRARIES}) set(llcommon_SOURCE_FILES indra_constants.cpp @@ -272,53 +259,26 @@ if (DARWIN) list(APPEND llcommon_SOURCE_FILES llsys_objc.mm) endif (DARWIN) -set_source_files_properties(${llcommon_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - -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}) -if(LLCOMMON_LINK_SHARED) - add_library (llcommon SHARED ${llcommon_SOURCE_FILES}) - if(NOT ADDRESS_SIZE EQUAL 32) - if(WINDOWS) - ##add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) - endif(NOT ADDRESS_SIZE EQUAL 32) - if(WINDOWS) - # always generate llcommon.pdb, even for "Release" builds - set_target_properties(llcommon PROPERTIES LINK_FLAGS "/DEBUG") - endif(WINDOWS) - ll_stage_sharedlib(llcommon) -else(LLCOMMON_LINK_SHARED) - add_library (llcommon ${llcommon_SOURCE_FILES}) -endif(LLCOMMON_LINK_SHARED) +add_library (llcommon ${llcommon_SOURCE_FILES}) target_link_libraries( - llcommon - ${APRUTIL_LIBRARIES} - ${APR_LIBRARIES} - ${EXPAT_LIBRARIES} - ${ICU4C_LIBRARY} - ${JSONCPP_LIBRARIES} - ${ZLIBNG_LIBRARIES} - ${WINDOWS_LIBRARIES} - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_PROGRAM_OPTIONS_LIBRARY} - ${BOOST_REGEX_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} - ${GOOGLE_PERFTOOLS_LIBRARIES} - ${URIPARSER_LIBRARIES} - ${TRACY_LIBRARY} + llcommon + ${ICU4C_LIBRARY} + ll::apr + ll::expat + ll::jsoncpp + ll::zlib-ng + ll::boost + ll::uriparser + ll::oslibraries + ll::tracy ) +target_include_directories(llcommon INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(llcommon PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + add_dependencies(llcommon stage_third_party_libs) if (LL_TESTS) @@ -329,14 +289,7 @@ if (LL_TESTS) LL_ADD_PROJECT_UNIT_TESTS(llcommon "${llcommon_TEST_SOURCE_FILES}") #set(TEST_DEBUG on) - set(test_libs llcommon - ${LLCOMMON_LIBRARIES} - ${WINDOWS_LIBRARIES} - ${GOOGLEMOCK_LIBRARIES} - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_THREAD_LIBRARY} - ${BOOST_SYSTEM_LIBRARY}) + set(test_libs llcommon) LL_ADD_INTEGRATION_TEST(bitpack "" "${test_libs}") LL_ADD_INTEGRATION_TEST(classic_callback "" "${test_libs}") LL_ADD_INTEGRATION_TEST(commonmisc "" "${test_libs}") diff --git a/indra/llcommon/apply.h b/indra/llcommon/apply.h new file mode 100644 index 0000000000..7c58d63bc0 --- /dev/null +++ b/indra/llcommon/apply.h @@ -0,0 +1,115 @@ +/** + * @file apply.h + * @author Nat Goodspeed + * @date 2022-06-18 + * @brief C++14 version of std::apply() + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Copyright (c) 2022, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_APPLY_H) +#define LL_APPLY_H + +#include <boost/type_traits/function_traits.hpp> +#include <tuple> + +namespace LL +{ + +/** + * USAGE NOTE: + * https://stackoverflow.com/a/40523474/5533635 + * + * If you're trying to pass apply() a variadic function, the compiler + * complains that it can't deduce the callable type, presumably because it + * doesn't know which arity to reify to pass. + * + * But it works to wrap the variadic function in a generic lambda, e.g.: + * + * @CODE + * LL::apply( + * [](auto&&... args) + * { + * return variadic(std::forward<decltype(args)>(args)...); + * }, + * args); + * @ENDCODE + * + * Presumably this is because there's only one instance of the generic lambda + * @em type, with a variadic <tt>operator()()</tt>. + * + * It's pointless to provide a wrapper @em function that implicitly supplies + * the generic lambda. You couldn't pass your variadic function to our wrapper + * function, for the same original reason! + * + * Instead we provide a wrapper @em macro. Sorry, Dr. Stroustrup. + */ +#define VAPPLY(FUNC, ARGS) \ + LL::apply( \ + [](auto&&... args) \ + { \ + return (FUNC)(std::forward<decltype(args)>(args)...); \ + }, \ + (ARGS)) + +#if __cplusplus >= 201703L + +// C++17 implementation +using std::apply; + +#else // C++14 + +// Derived from https://stackoverflow.com/a/20441189 +// and https://en.cppreference.com/w/cpp/utility/apply +template <typename CALLABLE, typename TUPLE, std::size_t... I> +auto apply_impl(CALLABLE&& func, TUPLE&& args, std::index_sequence<I...>) +{ + // call func(unpacked args) + return std::forward<CALLABLE>(func)(std::move(std::get<I>(args))...); +} + +template <typename CALLABLE, typename... ARGS> +auto apply(CALLABLE&& func, const std::tuple<ARGS...>& args) +{ + // std::index_sequence_for is the magic sauce here, generating an argument + // pack of indexes for each entry in args. apply_impl() can then pass + // those to std::get() to unpack args into individual arguments. + return apply_impl(std::forward<CALLABLE>(func), + args, + std::index_sequence_for<ARGS...>{}); +} + +// per https://stackoverflow.com/a/57510428/5533635 +template <typename CALLABLE, typename T, size_t SIZE> +auto apply(CALLABLE&& func, const std::array<T, SIZE>& args) +{ + return apply(std::forward<CALLABLE>(func), std::tuple_cat(args)); +} + +// per https://stackoverflow.com/a/28411055/5533635 +template <typename CALLABLE, typename T, std::size_t... I> +auto apply_impl(CALLABLE&& func, const std::vector<T>& args, std::index_sequence<I...>) +{ + return apply_impl(std::forward<CALLABLE>(func), + std::make_tuple(std::forward<T>(args[I])...), + I...); +} + +// this goes beyond C++17 std::apply() +template <typename CALLABLE, typename T> +auto apply(CALLABLE&& func, const std::vector<T>& args) +{ + constexpr auto arity = boost::function_traits<CALLABLE>::arity; + assert(args.size() == arity); + return apply_impl(std::forward<CALLABLE>(func), + args, + std::make_index_sequence<arity>()); +} + +#endif // C++14 + +} // namespace LL + +#endif /* ! defined(LL_APPLY_H) */ diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index c658075a31..d839b19c99 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -68,10 +68,6 @@ void setup_signals(); void default_unix_signal_handler(int signum, siginfo_t *info, void *); #if LL_LINUX -#include "google_breakpad/minidump_descriptor.h" -static bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, - void* context, - bool succeeded); #else // Called by breakpad exception handler after the minidump has been generated. bool unix_post_minidump_callback(const char *dump_dir, @@ -856,47 +852,8 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *) } #if LL_LINUX -bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, void* context, bool succeeded) -{ - // Copy minidump file path into fixed buffer in the app instance to avoid - // heap allocations in a crash handler. - - // path format: <dump_dir>/<minidump_id>.dmp - - //HACK: *path points to the buffer in getMiniDumpFilename which has already allocated space - //to avoid doing allocation during crash. - char * path = LLApp::instance()->getMiniDumpFilename(); - int dir_path_len = strlen(path); - - // The path must not be truncated. - S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH - dir_path_len; - - llassert( (remaining - strlen(minidump_desc.path())) > 5); - - path += dir_path_len; - - if (dir_path_len > 0 && path[-1] != '/') - { - *path++ = '/'; - --remaining; - } - - strncpy(path, minidump_desc.path(), remaining); - - LL_INFOS("CRASHREPORT") << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << LL_ENDL; - LLApp::runErrorHandler(); - -#ifndef LL_RELEASE_FOR_DOWNLOAD - clear_signals(); - return false; -#else - return true; #endif -} -#endif - - bool unix_post_minidump_callback(const char *dump_dir, const char *minidump_id, void *context, bool succeeded) diff --git a/indra/llcommon/llerrorthread.cpp b/indra/llcommon/llerrorthread.cpp index f6bc68b5c1..4f8f0a88ad 100644 --- a/indra/llcommon/llerrorthread.cpp +++ b/indra/llcommon/llerrorthread.cpp @@ -108,11 +108,9 @@ void LLErrorThread::run() // application state as APP_STATUS_ERROR. LL_INFOS() << "thread_error - Waiting for an error" << LL_ENDL; - S32 counter = 0; while (! (LLApp::isError() || LLApp::isStopped())) { ms_sleep(10); - counter++; } if (LLApp::isError()) { diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp index 23936f0526..97a38ea992 100644 --- a/indra/llcommon/llprocess.cpp +++ b/indra/llcommon/llprocess.cpp @@ -272,6 +272,14 @@ public: boost::bind(&ReadPipeImpl::tick, this, _1)); } + ~ReadPipeImpl() + { + if (mConnection.connected()) + { + mConnection.disconnect(); + } + } + // Much of the implementation is simply connecting the abstract virtual // methods with implementation data concealed from the base class. virtual std::istream& get_istream() { return mStream; } diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h index 92a1fc58a5..cdb9a7ed8a 100644 --- a/indra/llcommon/llsd.h +++ b/indra/llcommon/llsd.h @@ -441,42 +441,42 @@ public: static std::string typeString(Type type); // Return human-readable type as a string }; -struct llsd_select_bool : public std::unary_function<LLSD, LLSD::Boolean> +struct llsd_select_bool { LLSD::Boolean operator()(const LLSD& sd) const { return sd.asBoolean(); } }; -struct llsd_select_integer : public std::unary_function<LLSD, LLSD::Integer> +struct llsd_select_integer { LLSD::Integer operator()(const LLSD& sd) const { return sd.asInteger(); } }; -struct llsd_select_real : public std::unary_function<LLSD, LLSD::Real> +struct llsd_select_real { LLSD::Real operator()(const LLSD& sd) const { return sd.asReal(); } }; -struct llsd_select_float : public std::unary_function<LLSD, F32> +struct llsd_select_float { F32 operator()(const LLSD& sd) const { return (F32)sd.asReal(); } }; -struct llsd_select_uuid : public std::unary_function<LLSD, LLSD::UUID> +struct llsd_select_uuid { LLSD::UUID operator()(const LLSD& sd) const { return sd.asUUID(); } }; -struct llsd_select_string : public std::unary_function<LLSD, LLSD::String> +struct llsd_select_string { LLSD::String operator()(const LLSD& sd) const { diff --git a/indra/llcommon/llsdjson.h b/indra/llcommon/llsdjson.h index 2be7112404..e56cf03b45 100644 --- a/indra/llcommon/llsdjson.h +++ b/indra/llcommon/llsdjson.h @@ -34,7 +34,7 @@ #include "stdtypes.h" #include "llsd.h" -#include "value.h" +#include "json/value.h" /// Convert a parsed JSON structure into LLSD maintaining member names and /// array indexes. diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index a90c2c7e08..25131291f9 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -142,7 +142,7 @@ struct DeletePairedPointerArray // llselect2nd<map_type::value_type>())); template<typename T> -struct DeletePointerFunctor : public std::unary_function<T*, bool> +struct DeletePointerFunctor { bool operator()(T* ptr) const { @@ -153,7 +153,7 @@ struct DeletePointerFunctor : public std::unary_function<T*, bool> // See notes about DeleteArray for why you should consider avoiding this. template<typename T> -struct DeleteArrayFunctor : public std::unary_function<T*, bool> +struct DeleteArrayFunctor { bool operator()(T* ptr) const { @@ -395,16 +395,17 @@ OutputIter ll_transform_n( // select... with the stl. Look up usage on the sgi website. template <class _Pair> -struct _LLSelect1st : public std::unary_function<_Pair, typename _Pair::first_type> { - const typename _Pair::first_type& operator()(const _Pair& __x) const { +struct _LLSelect1st +{ + const auto& operator()(const _Pair& __x) const { return __x.first; } }; template <class _Pair> -struct _LLSelect2nd : public std::unary_function<_Pair, typename _Pair::second_type> +struct _LLSelect2nd { - const typename _Pair::second_type& operator()(const _Pair& __x) const { + const auto& operator()(const _Pair& __x) const { return __x.second; } }; @@ -416,9 +417,7 @@ template <class _Pair> struct llselect2nd : public _LLSelect2nd<_Pair> {}; // compose... with the stl. Look up usage on the sgi website. template <class _Operation1, class _Operation2> -class ll_unary_compose : - public std::unary_function<typename _Operation2::argument_type, - typename _Operation1::result_type> +class ll_unary_compose { protected: _Operation1 __op1; @@ -426,8 +425,9 @@ protected: public: ll_unary_compose(const _Operation1& __x, const _Operation2& __y) : __op1(__x), __op2(__y) {} - typename _Operation1::result_type - operator()(const typename _Operation2::argument_type& __x) const { + template <typename _Op2Arg> + auto + operator()(const _Op2Arg& __x) const { return __op1(__op2(__x)); } }; @@ -441,8 +441,7 @@ llcompose1(const _Operation1& __op1, const _Operation2& __op2) template <class _Operation1, class _Operation2, class _Operation3> class ll_binary_compose - : public std::unary_function<typename _Operation2::argument_type, - typename _Operation1::result_type> { +{ protected: _Operation1 _M_op1; _Operation2 _M_op2; @@ -451,8 +450,9 @@ public: ll_binary_compose(const _Operation1& __x, const _Operation2& __y, const _Operation3& __z) : _M_op1(__x), _M_op2(__y), _M_op3(__z) { } - typename _Operation1::result_type - operator()(const typename _Operation2::argument_type& __x) const { + template<typename OP2ARG> + auto + operator()(const OP2ARG& __x) const { return _M_op1(_M_op2(__x), _M_op3(__x)); } }; @@ -468,54 +468,51 @@ llcompose2(const _Operation1& __op1, const _Operation2& __op2, // helpers to deal with the fact that MSDev does not package // bind... with the stl. Again, this is from sgi. -template <class _Operation> -class llbinder1st : - public std::unary_function<typename _Operation::second_argument_type, - typename _Operation::result_type> { +template <class _Operation, typename _Arg1> +class llbinder1st +{ protected: _Operation op; - typename _Operation::first_argument_type value; + _Arg1 value; public: - llbinder1st(const _Operation& __x, - const typename _Operation::first_argument_type& __y) + llbinder1st(const _Operation& __x, const _Arg1& __y) : op(__x), value(__y) {} - typename _Operation::result_type - operator()(const typename _Operation::second_argument_type& __x) const { - return op(value, __x); - } + template <typename _Arg2> + auto + operator()(const _Arg2& __x) const { + return op(value, __x); + } }; template <class _Operation, class _Tp> -inline llbinder1st<_Operation> +inline auto llbind1st(const _Operation& __oper, const _Tp& __x) { - typedef typename _Operation::first_argument_type _Arg1_type; - return llbinder1st<_Operation>(__oper, _Arg1_type(__x)); + return llbinder1st<_Operation, _Tp>(__oper, __x); } -template <class _Operation> +template <class _Operation, typename _Arg2> class llbinder2nd - : public std::unary_function<typename _Operation::first_argument_type, - typename _Operation::result_type> { +{ protected: _Operation op; - typename _Operation::second_argument_type value; + _Arg2 value; public: llbinder2nd(const _Operation& __x, - const typename _Operation::second_argument_type& __y) + const _Arg2& __y) : op(__x), value(__y) {} - typename _Operation::result_type - operator()(const typename _Operation::first_argument_type& __x) const { + template <typename _Arg1> + auto + operator()(const _Arg1& __x) const { return op(__x, value); } }; template <class _Operation, class _Tp> -inline llbinder2nd<_Operation> +inline auto llbind2nd(const _Operation& __oper, const _Tp& __x) { - typedef typename _Operation::second_argument_type _Arg2_type; - return llbinder2nd<_Operation>(__oper, _Arg2_type(__x)); + return llbinder2nd<_Operation, _Tp>(__oper, __x); } /** @@ -548,8 +545,7 @@ bool before(const std::type_info* lhs, const std::type_info* rhs) namespace std { template <> - struct less<const std::type_info*>: - public std::binary_function<const std::type_info*, const std::type_info*, bool> + struct less<const std::type_info*> { bool operator()(const std::type_info* lhs, const std::type_info* rhs) const { @@ -558,8 +554,7 @@ namespace std }; template <> - struct less<std::type_info*>: - public std::binary_function<std::type_info*, std::type_info*, bool> + struct less<std::type_info*> { bool operator()(std::type_info* lhs, std::type_info* rhs) const { diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h index 12df693910..c0b13135f9 100644 --- a/indra/llcommon/stringize.h +++ b/indra/llcommon/stringize.h @@ -30,7 +30,7 @@ #define LL_STRINGIZE_H #include <sstream> -#include <llstring.h> +#include "llstring.h" #include <boost/call_traits.hpp> /** diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp index 9754353ab0..7ee36a9ea6 100644 --- a/indra/llcommon/tests/llleap_test.cpp +++ b/indra/llcommon/tests/llleap_test.cpp @@ -15,10 +15,10 @@ #include "llleap.h" // STL headers // std headers +#include <functional> // external library headers #include <boost/assign/list_of.hpp> #include <boost/phoenix/core/argument.hpp> -#include <boost/foreach.hpp> // other Linden headers #include "../test/lltut.h" #include "../test/namedtempfile.h" @@ -29,7 +29,6 @@ #include "llstring.h" #include "stringize.h" #include "StringVec.h" -#include <functional> using boost::assign::list_of; @@ -110,11 +109,6 @@ namespace tut "import os\n" "import sys\n" "\n" - // Don't forget that this Python script is written to some - // temp directory somewhere! Its __file__ is useless in - // finding indra/lib/python. Use our __FILE__, with - // raw-string syntax to deal with Windows pathnames. - "mydir = os.path.dirname(r'" << __FILE__ << "')\n" "from llbase import llsd\n" "\n" "class ProtocolError(Exception):\n" @@ -241,9 +235,9 @@ namespace tut "import sys\n" "sys.stderr.write('''Hello from Python!\n" "note partial line''')\n"); + StringVec vcommand{ PYTHON, script.getName() }; CaptureLog log(LLError::LEVEL_INFO); - waitfor(LLLeap::create(get_test_name(), - sv(list_of(PYTHON)(script.getName())))); + waitfor(LLLeap::create(get_test_name(), vcommand)); log.messageWith("Hello from Python!"); log.messageWith("note partial line"); } @@ -531,7 +525,7 @@ namespace tut result.ensure(); } - struct TestLargeMessage: public std::binary_function<size_t, size_t, bool> + struct TestLargeMessage { TestLargeMessage(const std::string& PYTHON_, const std::string& reader_module_, const std::string& test_name_): |