summaryrefslogtreecommitdiff
path: root/indra/llcommon/always_return.h
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2024-05-28 13:22:05 -0400
committerNat Goodspeed <nat@lindenlab.com>2024-05-28 13:22:05 -0400
commit5ed8df22cd59680a685c4ada7daa5555bf59d4fe (patch)
treeaffa9679e891608f9689c780cdd00710e5ea2c95 /indra/llcommon/always_return.h
parent71d777ea126e7f02cb46c11bdb606094ca06f75c (diff)
Fix up llexception.h's cross-platform SEH wrapper.
Introduce AlwaysReturn<void> specialization, which always discards any result of calling the specified callable with specified args. Derive new Windows_SEH_exception from LLException, not std::runtime_error. Put the various SEH functions in LL::seh nested namespace, e.g. LL::seh::catcher() as the primary API. Break out more levels of Windows SEH handler to work around the restrictions on functions containing __try/__except. The triadic catcher() overload now does little save declare a std::string stacktrace before forwarding the call to catcher_inner(), passing a reference to stacktrace along with the trycode, filter and handler functions. catcher_inner() accepts the stacktrace and the three function template arguments. It contains the __try/__except logic. It calls a new filter_() wrapper template, which calls fill_stacktrace() before forwarding the call to the caller's filter function. fill_stacktrace(), in the .cpp file, contains the logic to populate the stacktrace string -- unless the Structured Exception is stack overflow, in which case it puts an explanatory string instead. catcher_inner()'s __except clause passes not only the code, but also the stacktrace string, to the caller's handler function. It wraps the caller's handler function in always_return<rtype>(), where rtype is the type returned by the trycode function. This allows a handler to return a value, while also supporting the void handler case, e.g. one that throws a C++ exception. (This is why we need AlwaysReturn<void>: some trycode() functions are themselves void.) For the dyadic catcher() overload, introduce common_filter() containing the logic to distinguish a C++ exception from any other kind of Structured Exception. The fact that the stacktrace is captured before the filter function is called should permit capturing a stacktrace for a C++ exception as well as for most other Structured Exceptions. As before, the monadic catcher() overload supplies the rethrow() handler, in the .cpp file. Change existing calls from seh_catcher() to LL::seh::catcher().
Diffstat (limited to 'indra/llcommon/always_return.h')
-rw-r--r--indra/llcommon/always_return.h16
1 files changed, 16 insertions, 0 deletions
diff --git a/indra/llcommon/always_return.h b/indra/llcommon/always_return.h
index a206471da5..b99eb49096 100644
--- a/indra/llcommon/always_return.h
+++ b/indra/llcommon/always_return.h
@@ -79,6 +79,22 @@ namespace LL
DESIRED mDefault;
};
+ // specialize for AlwaysReturn<void>
+ template <>
+ struct AlwaysReturn<void>
+ {
+ public:
+ AlwaysReturn() {}
+
+ // callable returns a type not convertible to DESIRED, return default
+ template <typename CALLABLE, typename... ARGS>
+ void operator()(CALLABLE&& callable, ARGS&&... args)
+ {
+ // discard whatever callable(args) returns
+ std::forward<CALLABLE>(callable)(std::forward<ARGS>(args)...);
+ }
+ };
+
/**
* always_return<T>(some_function, some_args...) calls
* some_function(some_args...). It is guaranteed to return a value of type