diff options
| author | Jonathan "Geenz" Goodman <geenz@geenzo.com> | 2025-04-15 13:55:01 -0400 |
|---|---|---|
| committer | Jonathan "Geenz" Goodman <geenz@geenzo.com> | 2025-04-15 13:55:01 -0400 |
| commit | 52cca995ccc30ac5aa989588a71c0a7f4a9804ae (patch) | |
| tree | 69aecdda91f34883bf38ac86eefe8df61b1c4f22 /indra/llcommon | |
| parent | 97085ed30057ce950184f057340e0ecbcfc7614b (diff) | |
| parent | e43baa755d9b91c029e7b5166317e76468baf896 (diff) | |
Merge branch 'release/2025.04' into rye/forevermac
Diffstat (limited to 'indra/llcommon')
| -rw-r--r-- | indra/llcommon/indra_constants.h | 2 | ||||
| -rw-r--r-- | indra/llcommon/llsdutil.h | 55 | ||||
| -rw-r--r-- | indra/llcommon/lluuid.cpp | 15 | ||||
| -rw-r--r-- | indra/llcommon/lluuid.h | 2 | ||||
| -rw-r--r-- | indra/llcommon/workqueue.cpp | 83 |
5 files changed, 137 insertions, 20 deletions
diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index d2de88ff0a..c6bdab007f 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -355,5 +355,7 @@ const U8 CLICK_ACTION_DISABLED = 8; const U8 CLICK_ACTION_IGNORE = 9; // DO NOT CHANGE THE SEQUENCE OF THIS LIST!! +constexpr U32 BEACON_SHOW_MAP = 0x0001; +constexpr U32 BEACON_FOCUS_MAP = 0x0002; #endif diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h index 38bbe19ddd..c31030c5ea 100644 --- a/indra/llcommon/llsdutil.h +++ b/indra/llcommon/llsdutil.h @@ -553,6 +553,61 @@ LLSD shallow(LLSD value, LLSD filter=LLSD()) { return llsd_shallow(value, filter } // namespace llsd +/***************************************************************************** + * toArray(), toMap() + *****************************************************************************/ +namespace llsd +{ + +// For some T convertible to LLSD, given std::vector<T> myVec, +// toArray(myVec) returns an LLSD array whose entries correspond to the +// items in myVec. +// For some U convertible to LLSD, given function U xform(const T&), +// toArray(myVec, xform) returns an LLSD array whose every entry is +// xform(item) of the corresponding item in myVec. +// toArray() actually works with any container<C> usable with range +// 'for', not just std::vector. +// (Once we get C++20 we can use std::identity instead of this default lambda.) +template<typename C, typename FUNC> +LLSD toArray(const C& container, FUNC&& func = [](const auto& arg) { return arg; }) +{ + LLSD array; + for (const auto& item : container) + { + array.append(std::forward<FUNC>(func)(item)); + } + return array; +} + +// For some T convertible to LLSD, given std::map<std::string, T> myMap, +// toMap(myMap) returns an LLSD map whose entries correspond to the +// (key, value) pairs in myMap. +// For some U convertible to LLSD, given function +// std::pair<std::string, U> xform(const std::pair<std::string, T>&), +// toMap(myMap, xform) returns an LLSD map whose every entry is +// xform(pair) of the corresponding (key, value) pair in myMap. +// toMap() actually works with any container usable with range 'for', not +// just std::map. It need not even be an associative container, as long as +// you pass an xform function that returns std::pair<std::string, U>. +// (Once we get C++20 we can use std::identity instead of this default lambda.) +template<typename C, typename FUNC> +LLSD toMap(const C& container, FUNC&& func = [](const auto& arg) { return arg; }) +{ + LLSD map; + for (const auto& pair : container) + { + const auto& [key, value] = std::forward<FUNC>(func)(pair); + map[key] = value; + } + return map; +} + +} // namespace llsd + +/***************************************************************************** + * boost::hash<LLSD> + *****************************************************************************/ + // Specialization for generating a hash value from an LLSD block. namespace boost { diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index b9bd27aa17..4aae90626e 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -174,14 +174,6 @@ void LLUUID::toString(std::string& out) const (U8)(mData[15])); } -// *TODO: deprecate -void LLUUID::toString(char* out) const -{ - std::string buffer; - toString(buffer); - strcpy(out, buffer.c_str()); /* Flawfinder: ignore */ -} - void LLUUID::toCompressedString(std::string& out) const { char bytes[UUID_BYTES + 1]; @@ -190,13 +182,6 @@ void LLUUID::toCompressedString(std::string& out) const out.assign(bytes, UUID_BYTES); } -// *TODO: deprecate -void LLUUID::toCompressedString(char* out) const -{ - memcpy(out, mData, UUID_BYTES); /* Flawfinder: ignore */ - out[UUID_BYTES] = '\0'; -} - std::string LLUUID::getString() const { return asString(); diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index bd4edc7993..ca1cf03c4d 100644 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h @@ -103,9 +103,7 @@ public: friend LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLUUID &uuid); friend LL_COMMON_API std::istream& operator>>(std::istream& s, LLUUID &uuid); - void toString(char *out) const; // Does not allocate memory, needs 36 characters (including \0) void toString(std::string& out) const; - void toCompressedString(char *out) const; // Does not allocate memory, needs 17 characters (including \0) void toCompressedString(std::string& out) const; std::string asString() const; diff --git a/indra/llcommon/workqueue.cpp b/indra/llcommon/workqueue.cpp index 6066e74fb5..c8ece616b2 100644 --- a/indra/llcommon/workqueue.cpp +++ b/indra/llcommon/workqueue.cpp @@ -17,6 +17,7 @@ // std headers // external library headers // other Linden headers +#include "llapp.h" #include "llcoros.h" #include LLCOROS_MUTEX_HEADER #include "llerror.h" @@ -102,19 +103,95 @@ std::string LL::WorkQueueBase::makeName(const std::string& name) return STRINGIZE("WorkQueue" << num); } +namespace +{ +#if LL_WINDOWS + + static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific + + U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS* exception_infop) + { + if (LLApp::instance()->reportCrashToBugsplat((void*)exception_infop)) + { + // Handled + return EXCEPTION_CONTINUE_SEARCH; + } + else if (code == STATUS_MSC_EXCEPTION) + { + // C++ exception, go on + return EXCEPTION_CONTINUE_SEARCH; + } + else + { + // handle it, convert to std::exception + return EXCEPTION_EXECUTE_HANDLER; + } + + return EXCEPTION_CONTINUE_SEARCH; + } + + void cpphandle(const LL::WorkQueueBase::Work& work) + { + // SE and C++ can not coexists, thus two handlers + try + { + work(); + } + catch (const LLContinueError&) + { + // Any uncaught exception derived from LLContinueError will be caught + // here and logged. This coroutine will terminate but the rest of the + // viewer will carry on. + LOG_UNHANDLED_EXCEPTION(STRINGIZE("LLContinue in work queue")); + } + } + + void sehandle(const LL::WorkQueueBase::Work& work) + { + __try + { + // handle stop and continue exceptions first + cpphandle(work); + } + __except (exception_filter(GetExceptionCode(), GetExceptionInformation())) + { + // convert to C++ styled exception + char integer_string[512]; + sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode()); + throw std::exception(integer_string); + } + } +#endif // LL_WINDOWS +} // anonymous namespace + void LL::WorkQueueBase::callWork(const Work& work) { LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + +#ifdef LL_WINDOWS + // can not use __try directly, toplevel requires unwinding, thus use of a wrapper + sehandle(work); +#else // LL_WINDOWS try { work(); } - catch (...) + catch (LLContinueError&) { - // No matter what goes wrong with any individual work item, the worker - // thread must go on! Log our own instance name with the exception. LOG_UNHANDLED_EXCEPTION(getKey()); } + catch (...) + { + // Stash any other kind of uncaught exception to be rethrown by main thread. + LL_WARNS("LLCoros") << "Capturing and rethrowing uncaught exception in WorkQueueBase " + << getKey() << LL_ENDL; + + LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); + main_queue->post( + // Bind the current exception, rethrow it in main loop. + [exc = std::current_exception()]() { std::rethrow_exception(exc); }); + } +#endif // else LL_WINDOWS } void LL::WorkQueueBase::error(const std::string& msg) |
