0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-05-18 10:53:48 +02:00

ircd::ctx: Manipulate uncaught exception count on context switch.

This commit is contained in:
Jason Volk 2019-03-22 18:50:57 -07:00
parent 86759ecc15
commit 712409218e
3 changed files with 41 additions and 3 deletions

View file

@ -718,6 +718,7 @@ RB_CHK_SYSHEADER(new, [NEW])
RB_CHK_SYSHEADER(regex, [REGEX])
RB_CHK_SYSHEADER(memory_resource, [MEMORY_RESOURCE])
RB_CHK_SYSHEADER(filesystem, [FILESYSTEM])
RB_CHK_SYSHEADER(cxxabi.h, [CXXABI_H])
dnl unix platform
RB_CHK_SYSHEADER(unistd.h, [UNISTD_H])

View file

@ -57,6 +57,7 @@ struct ircd::ctx::continuation
ctx *const self;
const predicate *const pred;
const interruptor *const intr;
const uint uncaught_exceptions;
operator const boost::asio::yield_context &() const noexcept;
operator boost::asio::yield_context &() noexcept;

View file

@ -762,11 +762,16 @@ noexcept
ircd::ctx::this_ctx::exception_handler::exception_handler()
noexcept
:std::exception_ptr{std::current_exception()}
:std::exception_ptr
{
std::current_exception()
}
{
assert(bool(*this));
//assert(!std::uncaught_exceptions());
#ifdef HAVE_CXXABI_H
__cxa_end_catch();
#endif
// We don't yet support more levels of exceptions; after ending this
// catch we can't still be in another one. This doesn't apply if we're
@ -949,6 +954,14 @@ ircd::ctx::continuation::noop_interruptor{[]
return;
}};
#ifdef HAVE_CXXABI_H
struct __cxxabiv1::__cxa_eh_globals
{
__cxa_exception *caughtExceptions;
unsigned int uncaughtExceptions;
};
#endif
//
// continuation
//
@ -969,6 +982,10 @@ try
{
&intr
}
,uncaught_exceptions
{
uint(std::uncaught_exceptions())
}
{
assert(self != nullptr);
assert(self->notes <= 1);
@ -986,7 +1003,6 @@ try
// cannot interleave _cxa_begin_catch() and __cxa_end_catch() by yielding
// the ircd::ctx in an exception handler.
assert(!std::current_exception());
//assert(!std::uncaught_exceptions());
// Point to this continuation instance (which is on the context's stack)
// from the context's instance. This allows its features to be accessed
@ -1000,6 +1016,15 @@ try
// its execution run and is now yielding.
mark(prof::event::YIELD);
#ifdef HAVE_CXXABI_H
using __cxxabiv1::__cxa_get_globals_fast;
assert(__cxa_get_globals_fast());
assert(__cxa_get_globals_fast()->uncaughtExceptions == uncaught_exceptions);
__cxa_get_globals_fast()->uncaughtExceptions = 0;
#else
assert(!uncaught_exceptions);
#endif
// Null the fundamental current context register as the last operation
// during execution before yielding. When a context resumes it will
// restore this register; otherwise it remains null for executions on
@ -1024,6 +1049,17 @@ noexcept
// upon resuming execution.
ircd::ctx::current = self;
#ifdef HAVE_CXXABI_H
using __cxxabiv1::__cxa_get_globals_fast;
assert(__cxa_get_globals_fast());
assert(__cxa_get_globals_fast()->uncaughtExceptions == 0);
__cxa_get_globals_fast()->uncaughtExceptions = uncaught_exceptions;
assert(uint(std::uncaught_exceptions()) == uncaught_exceptions);
#else
assert(std::uncaught_exceptions() == 0);
assert(uncaught_exceptions == 0);
#endif
// Tell the profiler this is the point where the context is now resuming.
// On some optimized builds this might lead nowhere.
mark(prof::event::CONTINUE);