]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: stop supporting ucontext flavor for context switching
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 10 Sep 2024 11:06:30 +0000 (13:06 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 10 Sep 2024 11:07:54 +0000 (13:07 +0200)
meson/boost-context/meson.build
pdns/recursordist/Makefile.am
pdns/recursordist/configure.ac
pdns/recursordist/mtasker_context.cc
pdns/recursordist/mtasker_fcontext.cc [deleted file]
pdns/recursordist/mtasker_ucontext.cc [deleted file]
pdns/version.cc

index 502a8a5ef709e6e1b776827dded400d366e69951..0a0b487c06622e11d099322941d04429542cfd85 100644 (file)
@@ -1,5 +1,2 @@
 dep_boost_context = dependency('boost', modules: ['context'], required: true)
-# Fixed value, we no longer support SystemV
-conf.set('HAVE_BOOST_CONTEXT', true)
-summary('Context', dep_boost_context.found(), bool_yn: true, section: 'Boost')
 
index a1ddd5128847349fc773e104bb50928a49e17964..fbd5384cda384ae7c64ad22f5414c7618daf2f2a 100644 (file)
@@ -68,7 +68,6 @@ EXTRA_DIST = \
        lua_hpp.mk \
        malloctrace.cc malloctrace.hh \
        mkpubsuffixcc \
-       mtasker_fcontext.cc mtasker_ucontext.cc \
        NOTICE \
        opensslsigners.hh opensslsigners.cc \
        portsmplexer.cc \
index bdc9d94ffaf3bd51aa874d69d600b4a7e54aadad..914f903777d0e4f24119a54584b45eb554877238 100644 (file)
@@ -52,18 +52,7 @@ AC_FUNC_STRERROR_R
 PDNS_CHECK_CLOCK_GETTIME
 
 BOOST_REQUIRE([1.54])
-
-# Boost Context was introduced in 1.51 (Aug 2012), but there was an immediate
-# API break in 1.52 (Nov 2012), so we only support that, and later.
-pdns_context_library=""
-AS_IF([test $boost_major_version -ge 152], [BOOST_CONTEXT([], [no])])
-AS_IF([test x"$boost_cv_lib_context" = "xyes"], [
-  pdns_context_library="Boost Context"
-], [
-  AC_CHECK_FUNCS([getcontext makecontext swapcontext], [pdns_context_library="System V ucontexts"])
-])
-AC_MSG_CHECKING([what context library to use for MTasker])
-AS_IF([test -n "$pdns_context_library"], [AC_MSG_RESULT([$pdns_context_library])], [AC_MSG_ERROR([neither boost::context nor System V ucontexts available])])
+BOOST_CONTEXT([], [yes])]
 
 PDNS_ENABLE_UNIT_TESTS
 PDNS_ENABLE_REPRODUCIBLE
@@ -280,5 +269,4 @@ AS_IF([test "x$HAVE_LIBCURL" != "xn"],
   [AC_MSG_NOTICE([libcurl: yes])],
   [AC_MSG_NOTICE([libcurl: no])]
 )
-AC_MSG_NOTICE([Context library: $pdns_context_library])
 AC_MSG_NOTICE([])
index 1661f2dac5d5c50d140051e7695fb32292d5022f..0699b1f94f1ae79dd01076aaeaf86734b611cf37 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
-#ifdef HAVE_CONFIG_H
+
 #include "config.h"
+#include "mtasker_context.hh"
+#include <exception>
+#include <cassert>
+#include <type_traits>
+#include <boost/version.hpp>
+#if BOOST_VERSION < 106100
+#include <boost/context/fcontext.hpp>
+using boost::context::make_fcontext;
+#else
+#include <boost/context/detail/fcontext.hpp>
+using boost::context::detail::make_fcontext;
+#endif /* BOOST_VERSION < 106100 */
+
+// __CET__ is set by the compiler if relevant, so far only relevant/tested for amd64 on OpenBSD
+#if defined(__amd64__)
+#if __CET__ & 0x1
+#define CET_ENDBR __asm("endbr64")
+#else
+#define CET_ENDBR
+#endif
+#else
+#define CET_ENDBR
+#endif
+
+#ifdef PDNS_USE_VALGRIND
+#include <valgrind/valgrind.h>
+#endif /* PDNS_USE_VALGRIND */
+
+#ifdef HAVE_FIBER_SANITIZER
+__thread void* t_mainStack{nullptr};
+__thread size_t t_mainStackSize{0};
+#endif /* HAVE_FIBER_SANITIZER */
+
+#if BOOST_VERSION < 105600
+/* Note: This typedef means functions taking fcontext_t*, like jump_fcontext(),
+ * now require a reinterpret_cast rather than a static_cast, since we're
+ * casting from pdns_context_t->uc_mcontext, which is void**, to
+ * some_opaque_struct**. In later versions fcontext_t is already void*. So if
+ * you remove this, then fix the ugly.
+ */
+using fcontext_t = boost::context::fcontext_t*;
+
+/* Emulate the >= 1.56 API for Boost 1.52 through 1.55 */
+static inline intptr_t
+jump_fcontext(fcontext_t* const ofc, fcontext_t const nfc,
+              intptr_t const arg)
+{
+  /* If the fcontext_t is preallocated then use it, otherwise allocate one
+   * on the stack ('self') and stash a pointer away in *ofc so the returning
+   * MThread can access it. This is safe because we're suspended, so the
+   * context object always outlives the jump.
+   */
+  if (*ofc) {
+    return boost::context::jump_fcontext(*ofc, nfc, arg);
+  }
+  else {
+    boost::context::fcontext_t self;
+    *ofc = &self;
+    auto ret = boost::context::jump_fcontext(*ofc, nfc, arg);
+    *ofc = nullptr;
+    return ret;
+  }
+}
+#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<fcontext_t>::value,
+              "Boost Context has changed the fcontext_t type again :-(");
+#endif
+
+/* Boost context only provides a means of passing a single argument across a
+ * 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;
+  std::function<void(void)>* work = nullptr;
+};
+
+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
+     * context switch to fashion this constructor-like init phase. The work
+     * function object is still only moved after we're (re)started, so may
+     * still be set or changed after a call to pdns_makecontext. This matches
+     * the behaviour of the System V implementation, which can inherently only
+     * be passed ints and pointers.
+     */
+    notifyStackSwitchDone();
+#if BOOST_VERSION < 106100
+    auto args = reinterpret_cast<args_t*>(xargs);
+#else
+    auto args = reinterpret_cast<args_t*>(t.data);
+#endif
+    auto ctx = args->self;
+    auto work = args->work;
+    /* we switch back to pdns_makecontext() */
+    notifyStackSwitchToKernel();
+#if BOOST_VERSION < 106100
+    jump_fcontext(reinterpret_cast<fcontext_t*>(&ctx->uc_mcontext),
+                  static_cast<fcontext_t>(args->prev_ctx), 0);
+#else
+    transfer_t res = jump_fcontext(t.fctx, 0);
+    CET_ENDBR;
+    /* 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<fcontext_t*>(res.data);
+      *ptr = res.fctx;
+    }
+#endif
+    notifyStackSwitchDone();
+    args = nullptr;
+
+    try {
+      auto start = std::move(*work);
+      start();
+    }
+    catch (...) {
+      ctx->exception = std::current_exception();
+    }
+
+    notifyStackSwitchToKernel();
+    /* Emulate the System V uc_link feature. */
+    auto const next_ctx = ctx->uc_link->uc_mcontext;
+#if BOOST_VERSION < 106100
+    jump_fcontext(reinterpret_cast<fcontext_t*>(&ctx->uc_mcontext),
+                  static_cast<fcontext_t>(next_ctx),
+                  reinterpret_cast<intptr_t>(ctx));
+#else
+    jump_fcontext(static_cast<fcontext_t>(next_ctx), 0);
+#endif
+
+#ifdef NDEBUG
+    __builtin_unreachable();
+#endif
+  }
+}
+
+pdns_ucontext_t::pdns_ucontext_t() :
+  uc_mcontext(nullptr), uc_link(nullptr)
+{
+#ifdef PDNS_USE_VALGRIND
+  valgrind_id = 0;
+#endif /* PDNS_USE_VALGRIND */
+}
+
+pdns_ucontext_t::~pdns_ucontext_t()
+{
+  /* There's nothing to delete here since fcontext doesn't require anything
+   * to be heap allocated.
+   */
+#ifdef PDNS_USE_VALGRIND
+  if (valgrind_id != 0) {
+    VALGRIND_STACK_DEREGISTER(valgrind_id);
+  }
+#endif /* PDNS_USE_VALGRIND */
+}
+
+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
+  intptr_t ptr = jump_fcontext(reinterpret_cast<fcontext_t*>(&octx.uc_mcontext),
+                               static_cast<fcontext_t>(ctx.uc_mcontext), 0);
+
+  auto origctx = reinterpret_cast<pdns_ucontext_t*>(ptr);
+  if (origctx && origctx->exception)
+    std::rethrow_exception(origctx->exception);
+#else
+  transfer_t res = jump_fcontext(static_cast<fcontext_t>(ctx.uc_mcontext), &octx.uc_mcontext);
+  CET_ENDBR;
+  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<fcontext_t*>(res.data);
+    *ptr = res.fctx;
+  }
+  if (ctx.exception) {
+    std::rethrow_exception(ctx.exception);
+  }
 #endif
+}
 
-#if defined(HAVE_BOOST_CONTEXT)
-#include "mtasker_fcontext.cc" // NOLINT(bugprone-suspicious-include)
+void pdns_makecontext(pdns_ucontext_t& ctx, std::function<void(void)>& start)
+{
+  assert(ctx.uc_link);
+  assert(ctx.uc_stack.size() >= 8192);
+  assert(!ctx.uc_mcontext);
+  ctx.uc_mcontext = make_fcontext(&ctx.uc_stack[ctx.uc_stack.size() - 1],
+                                  ctx.uc_stack.size() - 1, &threadWrapper);
+  args_t args;
+  args.self = &ctx;
+  args.work = &start;
+  /* jumping to threadwrapper */
+  notifyStackSwitch(&ctx.uc_stack[ctx.uc_stack.size() - 1], ctx.uc_stack.size() - 1);
+#if BOOST_VERSION < 106100
+  jump_fcontext(reinterpret_cast<fcontext_t*>(&args.prev_ctx),
+                static_cast<fcontext_t>(ctx.uc_mcontext),
+                reinterpret_cast<intptr_t>(&args));
 #else
-#include "mtasker_ucontext.cc" // NOLINT(bugprone-suspicious-include)
+  transfer_t res = jump_fcontext(static_cast<fcontext_t>(ctx.uc_mcontext),
+                                 &args);
+  CET_ENDBR;
+  /* back from threadwrapper, updating the context */
+  ctx.uc_mcontext = res.fctx;
 #endif
+  notifyStackSwitchDone();
+}
diff --git a/pdns/recursordist/mtasker_fcontext.cc b/pdns/recursordist/mtasker_fcontext.cc
deleted file mode 100644 (file)
index e489b40..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * This file is part of PowerDNS or dnsdist.
- * Copyright -- PowerDNS.COM B.V. and its contributors
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * In addition, for the avoidance of any doubt, permission is granted to
- * link this program with OpenSSL and to (re)distribute the binaries
- * produced as the result of such linking.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#include "mtasker_context.hh"
-#include <exception>
-#include <cassert>
-#include <type_traits>
-#include <boost/version.hpp>
-#if BOOST_VERSION < 106100
-#include <boost/context/fcontext.hpp>
-using boost::context::make_fcontext;
-#else
-#include <boost/context/detail/fcontext.hpp>
-using boost::context::detail::make_fcontext;
-#endif /* BOOST_VERSION < 106100 */
-
-// __CET__ is set by the compiler if relevant, so far only relevant/tested for amd64 on OpenBSD
-#if defined(__amd64__)
-#if __CET__ & 0x1
-#define CET_ENDBR __asm("endbr64")
-#else
-#define CET_ENDBR
-#endif
-#else
-#define CET_ENDBR
-#endif
-
-#ifdef PDNS_USE_VALGRIND
-#include <valgrind/valgrind.h>
-#endif /* PDNS_USE_VALGRIND */
-
-#ifdef HAVE_FIBER_SANITIZER
-__thread void* t_mainStack{nullptr};
-__thread size_t t_mainStackSize{0};
-#endif /* HAVE_FIBER_SANITIZER */
-
-#if BOOST_VERSION < 105600
-/* Note: This typedef means functions taking fcontext_t*, like jump_fcontext(),
- * now require a reinterpret_cast rather than a static_cast, since we're
- * casting from pdns_context_t->uc_mcontext, which is void**, to
- * some_opaque_struct**. In later versions fcontext_t is already void*. So if
- * you remove this, then fix the ugly.
- */
-using fcontext_t = boost::context::fcontext_t*;
-
-/* Emulate the >= 1.56 API for Boost 1.52 through 1.55 */
-static inline intptr_t
-jump_fcontext(fcontext_t* const ofc, fcontext_t const nfc,
-              intptr_t const arg)
-{
-  /* If the fcontext_t is preallocated then use it, otherwise allocate one
-   * on the stack ('self') and stash a pointer away in *ofc so the returning
-   * MThread can access it. This is safe because we're suspended, so the
-   * context object always outlives the jump.
-   */
-  if (*ofc) {
-    return boost::context::jump_fcontext(*ofc, nfc, arg);
-  }
-  else {
-    boost::context::fcontext_t self;
-    *ofc = &self;
-    auto ret = boost::context::jump_fcontext(*ofc, nfc, arg);
-    *ofc = nullptr;
-    return ret;
-  }
-}
-#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<fcontext_t>::value,
-              "Boost Context has changed the fcontext_t type again :-(");
-#endif
-
-/* Boost context only provides a means of passing a single argument across a
- * 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;
-  std::function<void(void)>* work = nullptr;
-};
-
-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
-     * context switch to fashion this constructor-like init phase. The work
-     * function object is still only moved after we're (re)started, so may
-     * still be set or changed after a call to pdns_makecontext. This matches
-     * the behaviour of the System V implementation, which can inherently only
-     * be passed ints and pointers.
-     */
-    notifyStackSwitchDone();
-#if BOOST_VERSION < 106100
-    auto args = reinterpret_cast<args_t*>(xargs);
-#else
-    auto args = reinterpret_cast<args_t*>(t.data);
-#endif
-    auto ctx = args->self;
-    auto work = args->work;
-    /* we switch back to pdns_makecontext() */
-    notifyStackSwitchToKernel();
-#if BOOST_VERSION < 106100
-    jump_fcontext(reinterpret_cast<fcontext_t*>(&ctx->uc_mcontext),
-                  static_cast<fcontext_t>(args->prev_ctx), 0);
-#else
-    transfer_t res = jump_fcontext(t.fctx, 0);
-    CET_ENDBR;
-    /* 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<fcontext_t*>(res.data);
-      *ptr = res.fctx;
-    }
-#endif
-    notifyStackSwitchDone();
-    args = nullptr;
-
-    try {
-      auto start = std::move(*work);
-      start();
-    }
-    catch (...) {
-      ctx->exception = std::current_exception();
-    }
-
-    notifyStackSwitchToKernel();
-    /* Emulate the System V uc_link feature. */
-    auto const next_ctx = ctx->uc_link->uc_mcontext;
-#if BOOST_VERSION < 106100
-    jump_fcontext(reinterpret_cast<fcontext_t*>(&ctx->uc_mcontext),
-                  static_cast<fcontext_t>(next_ctx),
-                  reinterpret_cast<intptr_t>(ctx));
-#else
-    jump_fcontext(static_cast<fcontext_t>(next_ctx), 0);
-#endif
-
-#ifdef NDEBUG
-    __builtin_unreachable();
-#endif
-  }
-}
-
-pdns_ucontext_t::pdns_ucontext_t() :
-  uc_mcontext(nullptr), uc_link(nullptr)
-{
-#ifdef PDNS_USE_VALGRIND
-  valgrind_id = 0;
-#endif /* PDNS_USE_VALGRIND */
-}
-
-pdns_ucontext_t::~pdns_ucontext_t()
-{
-  /* There's nothing to delete here since fcontext doesn't require anything
-   * to be heap allocated.
-   */
-#ifdef PDNS_USE_VALGRIND
-  if (valgrind_id != 0) {
-    VALGRIND_STACK_DEREGISTER(valgrind_id);
-  }
-#endif /* PDNS_USE_VALGRIND */
-}
-
-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
-  intptr_t ptr = jump_fcontext(reinterpret_cast<fcontext_t*>(&octx.uc_mcontext),
-                               static_cast<fcontext_t>(ctx.uc_mcontext), 0);
-
-  auto origctx = reinterpret_cast<pdns_ucontext_t*>(ptr);
-  if (origctx && origctx->exception)
-    std::rethrow_exception(origctx->exception);
-#else
-  transfer_t res = jump_fcontext(static_cast<fcontext_t>(ctx.uc_mcontext), &octx.uc_mcontext);
-  CET_ENDBR;
-  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<fcontext_t*>(res.data);
-    *ptr = res.fctx;
-  }
-  if (ctx.exception) {
-    std::rethrow_exception(ctx.exception);
-  }
-#endif
-}
-
-void pdns_makecontext(pdns_ucontext_t& ctx, std::function<void(void)>& start)
-{
-  assert(ctx.uc_link);
-  assert(ctx.uc_stack.size() >= 8192);
-  assert(!ctx.uc_mcontext);
-  ctx.uc_mcontext = make_fcontext(&ctx.uc_stack[ctx.uc_stack.size() - 1],
-                                  ctx.uc_stack.size() - 1, &threadWrapper);
-  args_t args;
-  args.self = &ctx;
-  args.work = &start;
-  /* jumping to threadwrapper */
-  notifyStackSwitch(&ctx.uc_stack[ctx.uc_stack.size() - 1], ctx.uc_stack.size() - 1);
-#if BOOST_VERSION < 106100
-  jump_fcontext(reinterpret_cast<fcontext_t*>(&args.prev_ctx),
-                static_cast<fcontext_t>(ctx.uc_mcontext),
-                reinterpret_cast<intptr_t>(&args));
-#else
-  transfer_t res = jump_fcontext(static_cast<fcontext_t>(ctx.uc_mcontext),
-                                 &args);
-  CET_ENDBR;
-  /* back from threadwrapper, updating the context */
-  ctx.uc_mcontext = res.fctx;
-#endif
-  notifyStackSwitchDone();
-}
diff --git a/pdns/recursordist/mtasker_ucontext.cc b/pdns/recursordist/mtasker_ucontext.cc
deleted file mode 100644 (file)
index 9fcb3da..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * This file is part of PowerDNS or dnsdist.
- * Copyright -- PowerDNS.COM B.V. and its contributors
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * In addition, for the avoidance of any doubt, permission is granted to
- * link this program with OpenSSL and to (re)distribute the binaries
- * produced as the result of such linking.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#include "mtasker_context.hh"
-#include <system_error>
-#include <exception>
-#include <cstring>
-#include <cassert>
-#include <csignal>
-#include <cstdint>
-#include <ucontext.h>
-
-#ifdef PDNS_USE_VALGRIND
-#include <valgrind/valgrind.h>
-#endif /* PDNS_USE_VALGRIND */
-
-#ifdef HAVE_FIBER_SANITIZER
-__thread void* t_mainStack{nullptr};
-__thread size_t t_mainStackSize{0};
-#endif /* HAVE_FIBER_SANITIZER */
-
-template <typename Message>
-static __attribute__((noinline, cold, noreturn)) void
-throw_errno(Message&& msg)
-{
-  throw std::system_error(errno, std::system_category(), std::forward<Message>(msg));
-}
-
-static inline std::pair<int, int>
-splitPointer(void* const ptr) noexcept
-{
-  static_assert(sizeof(int) == 4, "splitPointer() requires an 4 byte 'int'");
-  // In theory, we need this assertion. In practice, it prevents compilation
-  // on EL6 i386. Without the assertion, everything works.
-  // If you ever run into trouble with this code, please heed the warnings at
-  // http://man7.org/linux/man-pages/man3/makecontext.3.html#NOTES
-  //    static_assert (sizeof(uintptr_t) == 8,
-  //                    "splitPointer() requires an 8 byte 'uintptr_t'");
-  std::pair<int, int> words;
-  auto rep = reinterpret_cast<uintptr_t>(ptr);
-  uint32_t const hw = rep >> 32;
-  auto const lw = static_cast<uint32_t>(rep);
-  std::memcpy(&words.first, &hw, 4);
-  std::memcpy(&words.second, &lw, 4);
-  return words;
-}
-
-template <typename T>
-static inline T*
-joinPtr(int const first, int const second) noexcept
-{
-  static_assert(sizeof(int) == 4, "joinPtr() requires an 4 byte 'int'");
-  // See above.
-  //    static_assert (sizeof(uintptr_t) == 8,
-  //                    "joinPtr() requires an 8 byte 'uintptr_t'");
-  uint32_t hw;
-  uint32_t lw;
-  std::memcpy(&hw, &first, 4);
-  std::memcpy(&lw, &second, 4);
-  return reinterpret_cast<T*>((static_cast<uintptr_t>(hw) << 32) | lw);
-}
-
-extern "C"
-{
-  static void
-  threadWrapper(int const ctx0, int const ctx1, int const fun0, int const fun1)
-  {
-    notifyStackSwitchDone();
-    auto ctx = joinPtr<pdns_ucontext_t>(ctx0, ctx1);
-    try {
-      auto start = std::move(*joinPtr<std::function<void()>>(fun0, fun1));
-      start();
-    }
-    catch (...) {
-      ctx->exception = std::current_exception();
-    }
-    notifyStackSwitchToKernel();
-  }
-} // extern "C"
-
-pdns_ucontext_t::pdns_ucontext_t()
-{
-  uc_mcontext = new ::ucontext_t();
-  uc_link = nullptr;
-#ifdef PDNS_USE_VALGRIND
-  valgrind_id = 0;
-#endif /* PDNS_USE_VALGRIND */
-}
-
-pdns_ucontext_t::~pdns_ucontext_t()
-{
-  delete static_cast<ucontext_t*>(uc_mcontext);
-#ifdef PDNS_USE_VALGRIND
-  if (valgrind_id != 0) {
-    VALGRIND_STACK_DEREGISTER(valgrind_id);
-  }
-#endif /* PDNS_USE_VALGRIND */
-}
-
-void pdns_swapcontext(pdns_ucontext_t& __restrict octx, pdns_ucontext_t const& __restrict ctx)
-{
-  if (::swapcontext(static_cast<ucontext_t*>(octx.uc_mcontext),
-                    static_cast<ucontext_t*>(ctx.uc_mcontext))) {
-    throw_errno("swapcontext() failed");
-  }
-  if (ctx.exception) {
-    std::rethrow_exception(ctx.exception);
-  }
-}
-
-void pdns_makecontext(pdns_ucontext_t& ctx, std::function<void(void)>& start)
-{
-  assert(ctx.uc_link);
-  assert(ctx.uc_stack.size());
-
-  auto const mcp = static_cast<ucontext_t*>(ctx.uc_mcontext);
-  auto const next = static_cast<ucontext_t*>(ctx.uc_link->uc_mcontext);
-  if (::getcontext(mcp)) {
-    throw_errno("getcontext() failed");
-  }
-  mcp->uc_link = next;
-  mcp->uc_stack.ss_sp = ctx.uc_stack.data();
-  mcp->uc_stack.ss_size = ctx.uc_stack.size() - 1;
-  mcp->uc_stack.ss_flags = 0;
-
-  auto ctxarg = splitPointer(&ctx);
-  auto funarg = splitPointer(&start);
-  return ::makecontext(mcp, reinterpret_cast<void (*)(void)>(&threadWrapper),
-                       4, ctxarg.first, ctxarg.second,
-                       funarg.first, funarg.second);
-}
index 771c1fdced06139a4dc0d1048bef0d27877d564f..9e7b8bc6d1e0bbdf8b951276aea14484070bf68f 100644 (file)
@@ -110,9 +110,6 @@ string getBuildConfiguration()
 #ifdef HAVE_LIBDECAF
       << " decaf"
 #endif
-#ifdef HAVE_BOOST_CONTEXT
-      << " fcontext"
-#endif
 #ifdef HAVE_LIBCRYPTO_ECDSA
       << " libcrypto-ecdsa"
 #endif