mirror of
https://github.com/matrix-construct/construct
synced 2024-11-17 23:40:57 +01:00
121 lines
2.5 KiB
C++
121 lines
2.5 KiB
C++
|
// Matrix Construct
|
||
|
//
|
||
|
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||
|
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net>
|
||
|
//
|
||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||
|
// purpose with or without fee is hereby granted, provided that the above
|
||
|
// copyright notice and this permission notice is present in all copies. The
|
||
|
// full license for this software is available in the LICENSE file.
|
||
|
|
||
|
#include <RB_INC_CXXABI_H
|
||
|
#include <ircd/asio.h>
|
||
|
#include "ctx.h"
|
||
|
|
||
|
#ifdef HAVE_CXXABI_H
|
||
|
struct __cxxabiv1::__cxa_eh_globals
|
||
|
{
|
||
|
__cxa_exception *caughtExceptions;
|
||
|
unsigned int uncaughtExceptions;
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
//
|
||
|
// exception_handler
|
||
|
//
|
||
|
|
||
|
ircd::ctx::exception_handler::exception_handler()
|
||
|
noexcept
|
||
|
:std::exception_ptr
|
||
|
{
|
||
|
// capture a shared reference of the current exception before the catch
|
||
|
// block closes around it.
|
||
|
std::current_exception()
|
||
|
}
|
||
|
{
|
||
|
assert(bool(*this));
|
||
|
|
||
|
// close the catch block.
|
||
|
end_catch();
|
||
|
|
||
|
// 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
|
||
|
// not on any ctx currently.
|
||
|
assert(!current || !std::uncaught_exceptions());
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// util
|
||
|
//
|
||
|
|
||
|
#ifdef HAVE_CXXABI_H
|
||
|
void
|
||
|
ircd::ctx::exception_handler::end_catch()
|
||
|
noexcept
|
||
|
{
|
||
|
if(likely(current))
|
||
|
__cxxabiv1::__cxa_end_catch();
|
||
|
}
|
||
|
#else
|
||
|
#warning "CXXABI not available. Context switch inside catch block may be unsafe!"
|
||
|
void
|
||
|
ircd::ctx::exception_handler::end_catch()
|
||
|
noexcept
|
||
|
{
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef HAVE_CXXABI_H
|
||
|
uint
|
||
|
ircd::ctx::exception_handler::uncaught_exceptions()
|
||
|
noexcept
|
||
|
{
|
||
|
const auto &cxa_globals
|
||
|
{
|
||
|
__cxxabiv1::__cxa_get_globals_fast()
|
||
|
};
|
||
|
|
||
|
assert(cxa_globals);
|
||
|
return cxa_globals->uncaughtExceptions;
|
||
|
}
|
||
|
#else
|
||
|
#warning "CXXABI not available. Context switch with uncaught exceptions may be unsafe!"
|
||
|
uint
|
||
|
ircd::ctx::exception_handler::uncaught_exceptions()
|
||
|
noexcept
|
||
|
{
|
||
|
return std::uncaught_exceptions();
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef HAVE_CXXABI_H
|
||
|
uint
|
||
|
ircd::ctx::exception_handler::uncaught_exceptions(const uint &val)
|
||
|
noexcept
|
||
|
{
|
||
|
const auto &cxa_globals
|
||
|
{
|
||
|
__cxxabiv1::__cxa_get_globals_fast()
|
||
|
};
|
||
|
|
||
|
assert(cxa_globals);
|
||
|
const auto ret
|
||
|
{
|
||
|
cxa_globals->uncaughtExceptions
|
||
|
};
|
||
|
|
||
|
assert(unsigned(ret) == unsigned(std::uncaught_exceptions()));
|
||
|
cxa_globals->uncaughtExceptions = val;
|
||
|
return ret;
|
||
|
}
|
||
|
#else
|
||
|
#warning "CXXABI not available. Context switch with uncaught exceptions may be unsafe!"
|
||
|
uint
|
||
|
ircd::ctx::exception_handler::uncaught_exceptions(const uint &val)
|
||
|
noexcept
|
||
|
{
|
||
|
assert(std::uncaught_exceptions() == val);
|
||
|
return std::uncaught_exceptions();
|
||
|
}
|
||
|
#endif
|