mirror of
https://github.com/matrix-construct/construct
synced 2024-11-25 08:12:37 +01:00
ircd::ctx: Manipulate uncaught exception count on context switch.
This commit is contained in:
parent
86759ecc15
commit
712409218e
3 changed files with 41 additions and 3 deletions
|
@ -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])
|
||||
|
|
|
@ -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;
|
||||
|
|
42
ircd/ctx.cc
42
ircd/ctx.cc
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue