diff options
author | callum_linden <callum@lindenlab.com> | 2017-12-11 10:09:44 -0800 |
---|---|---|
committer | callum_linden <callum@lindenlab.com> | 2017-12-11 10:09:44 -0800 |
commit | 5561673bf1c98c717f69e747a9e8b0d56129ef12 (patch) | |
tree | f021c5beca7aaad132c60d25881c7920a9944daf /indra/llcommon | |
parent | fe29551d9a6685bdc40e87ae135f236aec1ea475 (diff) | |
parent | c565c62745ec37484118888f8f45dbde34d42e46 (diff) |
Automated merge with tip of viewer64 *plus* update to CEF 3.3202.1686 / Dullahan 901
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/llcoros.cpp | 45 | ||||
-rw-r--r-- | indra/llcommon/llcoros.h | 3 |
2 files changed, 48 insertions, 0 deletions
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 1e1dfd2602..c5ba23f68c 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -40,6 +40,10 @@ #include "stringize.h" #include "llexception.h" +#if LL_WINDOWS +#include <excpt.h> +#endif + namespace { void no_op() {} } // anonymous namespace @@ -276,6 +280,43 @@ void LLCoros::setStackSize(S32 stacksize) mStackSize = stacksize; } +#if LL_WINDOWS + +static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific + +U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) +{ + if (code == STATUS_MSC_EXCEPTION) + { + // C++ exception, go on + return EXCEPTION_CONTINUE_SEARCH; + } + else + { + // handle it + return EXCEPTION_EXECUTE_HANDLER; + } +} + +void LLCoros::winlevel(const callable_t& callable) +{ + __try + { + callable(); + } + __except (exception_filter(GetExceptionCode(), GetExceptionInformation())) + { + // convert to C++ styled exception + // 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()); + throw std::exception(integer_string); + } +} + +#endif + // Top-level wrapper around caller's coroutine callable. This function accepts // the coroutine library's implicit coro::self& parameter and saves it, but // does not pass it down to the caller's callable. @@ -286,7 +327,11 @@ void LLCoros::toplevel(coro::self& self, CoroData* data, const callable_t& calla // run the code the caller actually wants in the coroutine try { +#if LL_WINDOWS + winlevel(callable); +#else callable(); +#endif } catch (const LLContinueError&) { diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index bbe2d22af4..884d6b159c 100644 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h @@ -182,6 +182,9 @@ private: bool cleanup(const LLSD&); struct CoroData; static void no_cleanup(CoroData*); +#if LL_WINDOWS + static void winlevel(const callable_t& callable); +#endif static void toplevel(coro::self& self, CoroData* data, const callable_t& callable); static CoroData& get_CoroData(const std::string& caller); |