diff options
| author | Nat Goodspeed <nat@lindenlab.com> | 2018-12-16 14:31:32 -0500 |
|---|---|---|
| committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-02-11 20:53:21 +0200 |
| commit | 6c3507d6d358485c2a8e2fc4d915847cbeda3ee3 (patch) | |
| tree | 447685b69a4098011c70069479cb11ebf47da525 /indra/llcommon/llcoros.cpp | |
| parent | 236593e997e931580d3bd3192b12e450c8054b07 (diff) | |
SL-10190: Introduce LLCoros::saveException() and rethrow().
This mechanism uses a queue of std::exception_ptrs to transport an (otherwise)
uncaught exception from a terminated coroutine to the thread's main fiber. The
main loop calls LLCoros::rethrow() just after giving some cycles to ready
coroutines that frame.
# Conflicts:
# indra/llcommon/llcoros.cpp
# indra/llcommon/llcoros.h
# indra/newview/llappviewer.cpp
Diffstat (limited to 'indra/llcommon/llcoros.cpp')
| -rw-r--r-- | indra/llcommon/llcoros.cpp | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 6a534951ff..a182d305e8 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -35,6 +35,7 @@ // STL headers // std headers #include <atomic> +#include <stdexcept> // external library headers #include <boost/bind.hpp> #include <boost/fiber/fiber.hpp> @@ -214,6 +215,22 @@ std::string LLCoros::logname() return data.mName.empty()? data.getKey() : data.mName; } +void LLCoros::saveException(const std::string& name, std::exception_ptr exc) +{ + mExceptionQueue.emplace(name, exc); +} + +void LLCoros::rethrow() +{ + if (! mExceptionQueue.empty()) + { + ExceptionData front = mExceptionQueue.front(); + mExceptionQueue.pop(); + LL_WARNS("LLCoros") << "Rethrowing exception from coroutine " << front.name << LL_ENDL; + std::rethrow_exception(front.exception); + } +} + void LLCoros::setStackSize(S32 stacksize) { LL_DEBUGS("LLCoros") << "Setting coroutine stack size to " << stacksize << LL_ENDL; @@ -330,9 +347,11 @@ void LLCoros::toplevel(std::string name, callable_t callable) } catch (...) { - // Any OTHER kind of uncaught exception will cause the viewer to - // crash, hopefully informatively. - CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name)); + // Stash any OTHER kind of uncaught exception in the rethrow() queue + // to be rethrown by the main fiber. + LL_WARNS("LLCoros") << "Capturing uncaught exception in coroutine " + << name << LL_ENDL; + LLCoros::instance().saveException(name, std::current_exception()); } } |
