summaryrefslogtreecommitdiff
path: root/indra/llcommon/llcoros.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/llcoros.cpp')
-rw-r--r--indra/llcommon/llcoros.cpp50
1 files changed, 33 insertions, 17 deletions
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index ae0d6e694d..9e95d9c85f 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -140,7 +140,7 @@ LLCoros::LLCoros():
// Previously we used
// boost::context::guarded_stack_allocator::default_stacksize();
// empirically this is insufficient.
- mStackSize(512*1024),
+ mStackSize(1024*1024),
// mCurrent does NOT own the current CoroData instance -- it simply
// points to it. So initialize it with a no-op deleter.
mCurrent{ [](CoroData*){} }
@@ -172,7 +172,7 @@ void LLCoros::cleanupSingleton()
// don't use llcoro::suspend() because that module depends
// on this one
// This will yield current(main) thread and will let active
- // coroutines run once
+ // corutines run once
boost::this_fiber::yield();
}
printActiveCoroutines("after pumping");
@@ -331,12 +331,34 @@ U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS* exception_infop)
return EXCEPTION_CONTINUE_SEARCH;
}
-void sehandle(const LLCoros::callable_t& callable)
+void cpphandle(const LLCoros::callable_t& callable, const std::string& name)
{
- __try
+ // SE and C++ can not coexists, thus two handlers
+ try
{
callable();
}
+ catch (const LLCoros::Stop& exc)
+ {
+ LL_INFOS("LLCoros") << "coroutine " << name << " terminating because "
+ << exc.what() << LL_ENDL;
+ }
+ 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("coroutine " << name));
+ }
+}
+
+void sehandle(const LLCoros::callable_t& callable, const std::string& name)
+{
+ __try
+ {
+ // handle stop and continue exceptions first
+ cpphandle(callable, name);
+ }
__except (exception_filter(GetExceptionCode(), GetExceptionInformation()))
{
// convert to C++ styled exception
@@ -347,16 +369,7 @@ void sehandle(const LLCoros::callable_t& callable)
throw std::exception(integer_string);
}
}
-
-#else // ! LL_WINDOWS
-
-inline void sehandle(const LLCoros::callable_t& callable)
-{
- callable();
-}
-
-#endif // ! LL_WINDOWS
-
+#endif // LL_WINDOWS
} // anonymous namespace
// Top-level wrapper around caller's coroutine callable.
@@ -369,10 +382,14 @@ void LLCoros::toplevel(std::string name, callable_t callable)
// set it as current
mCurrent.reset(&corodata);
+#ifdef LL_WINDOWS
+ // can not use __try directly, toplevel requires unwinding, thus use of a wrapper
+ sehandle(callable, name);
+#else // LL_WINDOWS
// run the code the caller actually wants in the coroutine
try
{
- LL::seh::catcher(callable);
+ callable();
}
catch (const Stop& exc)
{
@@ -386,7 +403,6 @@ void LLCoros::toplevel(std::string name, callable_t callable)
// viewer will carry on.
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
}
-#ifndef LL_WINDOWS
catch (...)
{
// Stash any OTHER kind of uncaught exception in the rethrow() queue
@@ -395,7 +411,7 @@ void LLCoros::toplevel(std::string name, callable_t callable)
<< name << LL_ENDL;
LLCoros::instance().saveException(name, std::current_exception());
}
-#endif // ! LL_WINDOWS
+#endif // else LL_WINDOWS
}
//static