diff options
| author | Rider Linden <rider@lindenlab.com> | 2017-11-30 11:42:49 -0800 | 
|---|---|---|
| committer | Rider Linden <rider@lindenlab.com> | 2017-11-30 11:42:49 -0800 | 
| commit | 1df10afa2a7802763330475e1a90547c3cff7c06 (patch) | |
| tree | 8a8cdb8c02f1e18e8cfacefc1efbc2ab43c6157e /indra/llcommon | |
| parent | d7dd10b88bc3fda88f6528ecc5936e4889f019f3 (diff) | |
| parent | e3a2c5e3217ae74a0277f2e6d4e1e708fe398a1c (diff) | |
Merge
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); | 
