summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorcallum_linden <callum@lindenlab.com>2017-12-11 10:09:44 -0800
committercallum_linden <callum@lindenlab.com>2017-12-11 10:09:44 -0800
commit5561673bf1c98c717f69e747a9e8b0d56129ef12 (patch)
treef021c5beca7aaad132c60d25881c7920a9944daf /indra/llcommon
parentfe29551d9a6685bdc40e87ae135f236aec1ea475 (diff)
parentc565c62745ec37484118888f8f45dbde34d42e46 (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.cpp45
-rw-r--r--indra/llcommon/llcoros.h3
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);