From: Remi Gacogne Date: Fri, 23 Sep 2016 14:08:15 +0000 (+0200) Subject: rec: Add support for boost::context >= 1.61 X-Git-Tag: dnsdist-1.1.0-beta2~116^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f53de853d71bd1c058b507549d35312f9fa4847f;p=pdns rec: Add support for boost::context >= 1.61 --- diff --git a/pdns/mtasker_fcontext.cc b/pdns/mtasker_fcontext.cc index 1b2a11be2..d8d4e2a1a 100644 --- a/pdns/mtasker_fcontext.cc +++ b/pdns/mtasker_fcontext.cc @@ -23,10 +23,15 @@ #include #include #include -#include #include - +#if BOOST_VERSION >= 106100 +#include +using boost::context::detail::make_fcontext; +#else +#include using boost::context::make_fcontext; +#endif /* BOOST_VERSION >= 106100 */ + #if BOOST_VERSION < 105600 /* Note: This typedef means functions taking fcontext_t*, like jump_fcontext(), @@ -57,8 +62,15 @@ jump_fcontext (fcontext_t* const ofc, fcontext_t const nfc, } } #else + +#if BOOST_VERSION < 106100 using boost::context::fcontext_t; using boost::context::jump_fcontext; +#else +using boost::context::detail::fcontext_t; +using boost::context::detail::jump_fcontext; +using boost::context::detail::transfer_t; +#endif /* BOOST_VERSION < 106100 */ static_assert (std::is_pointer::value, "Boost Context has changed the fcontext_t type again :-("); @@ -68,7 +80,9 @@ static_assert (std::is_pointer::value, * jump. args_t simply provides a way to pass more by reference. */ struct args_t { +#if BOOST_VERSION < 106100 fcontext_t prev_ctx = nullptr; +#endif pdns_ucontext_t* self = nullptr; boost::function* work = nullptr; }; @@ -76,7 +90,11 @@ struct args_t { extern "C" { static void +#if BOOST_VERSION < 106100 threadWrapper (intptr_t const xargs) { +#else +threadWrapper (transfer_t const t) { +#endif /* Access the args passed from pdns_makecontext, and copy them directly from * the calling stack on to ours (we're now using the MThreads stack). * This saves heap allocating an args object, at the cost of an extra @@ -86,11 +104,28 @@ threadWrapper (intptr_t const xargs) { * the behaviour of the System V implementation, which can inherently only * be passed ints and pointers. */ +#if BOOST_VERSION < 106100 auto args = reinterpret_cast(xargs); +#else + auto args = reinterpret_cast(t.data); +#endif auto ctx = args->self; auto work = args->work; + /* we switch back to pdns_makecontext() */ +#if BOOST_VERSION < 106100 jump_fcontext (reinterpret_cast(&ctx->uc_mcontext), static_cast(args->prev_ctx), 0); +#else + transfer_t res = jump_fcontext (t.fctx, 0); + /* we got switched back from pdns_swapcontext() */ + if (res.data) { + /* if res.data is not a nullptr, it holds a pointer to the context + we just switched from, and we need to fill it to be able to + switch back to it later. */ + fcontext_t* ptr = static_cast(res.data); + *ptr = res.fctx; + } +#endif args = nullptr; try { @@ -102,9 +137,14 @@ threadWrapper (intptr_t const xargs) { /* Emulate the System V uc_link feature. */ auto const next_ctx = ctx->uc_link->uc_mcontext; +#if BOOST_VERSION < 106100 jump_fcontext (reinterpret_cast(&ctx->uc_mcontext), static_cast(next_ctx), static_cast(ctx->exception)); +#else + jump_fcontext (static_cast(next_ctx), 0); +#endif + #ifdef NDEBUG __builtin_unreachable(); #endif @@ -125,10 +165,27 @@ pdns_ucontext_t::~pdns_ucontext_t void pdns_swapcontext (pdns_ucontext_t& __restrict octx, pdns_ucontext_t const& __restrict ctx) { + /* we either switch back to threadwrapper() if it's the first time, + or we switch back to pdns_swapcontext(), + in both case we will be returning from a call to jump_fcontext(). */ +#if BOOST_VERSION < 106100 if (jump_fcontext (reinterpret_cast(&octx.uc_mcontext), static_cast(ctx.uc_mcontext), 0)) { std::rethrow_exception (ctx.exception); } +#else + transfer_t res = jump_fcontext (static_cast(ctx.uc_mcontext), &octx.uc_mcontext); + if (res.data) { + /* if res.data is not a nullptr, it holds a pointer to the context + we just switched from, and we need to fill it to be able to + switch back to it later. */ + fcontext_t* ptr = static_cast(res.data); + *ptr = res.fctx; + } + if (ctx.exception) { + std::rethrow_exception (ctx.exception); + } +#endif } void @@ -142,7 +199,15 @@ pdns_makecontext args_t args; args.self = &ctx; args.work = &start; + /* jumping to threadwrapper */ +#if BOOST_VERSION < 106100 jump_fcontext (reinterpret_cast(&args.prev_ctx), static_cast(ctx.uc_mcontext), reinterpret_cast(&args)); +#else + transfer_t res = jump_fcontext (static_cast(ctx.uc_mcontext), + &args); + /* back from threadwrapper, updating the context */ + ctx.uc_mcontext = res.fctx; +#endif } diff --git a/pdns/recursordist/configure.ac b/pdns/recursordist/configure.ac index 7a07d96d1..fe5e62561 100644 --- a/pdns/recursordist/configure.ac +++ b/pdns/recursordist/configure.ac @@ -46,7 +46,7 @@ pdns_context_library="System V ucontexts" AC_DEFUN([PDNS_SELECT_CONTEXT_IMPL], [ AC_MSG_CHECKING([whether Boost is new enough to use the context library...]) - if test $boost_major_version -ge 152 -a $boost_major_version -lt 161 ; then + if test $boost_major_version -ge 152; then AC_MSG_RESULT([yes]) if test $boost_major_version -ge 157; then BOOST_THREAD([$1]) @@ -55,9 +55,15 @@ AC_DEFUN([PDNS_SELECT_CONTEXT_IMPL], [ LDFLAGS="$LDFLAGS $BOOST_THREAD_LDFLAGS" fi AC_MSG_NOTICE([checking whether the Boost context library actually links...]) - BOOST_FIND_HEADER([boost/context/fcontext.hpp], [ : ], [ - BOOST_FIND_LIB([context], [$1], [boost/context/fcontext.hpp], [[]]) - ]) + if test $boost_major_version -ge 161; then + BOOST_FIND_HEADER([boost/context/detail/fcontext.hpp], [ : ], [ + BOOST_FIND_LIB([context], [$1], [boost/context/detail/fcontext.hpp], [[]]) + ]) + else + BOOST_FIND_HEADER([boost/context/fcontext.hpp], [ : ], [ + BOOST_FIND_LIB([context], [$1], [boost/context/fcontext.hpp], [[]]) + ]) + fi case $boost_cv_lib_context in (yes) pdns_context_library="Boost context"