diff --git a/pdns/mtasker.cc b/pdns/mtasker.cc index 43294c9537cc..9fcb7d31f2dd 100644 --- a/pdns/mtasker.cc +++ b/pdns/mtasker.cc @@ -344,6 +344,8 @@ templatebool MTasker::schedule(struct timeval* n } else if(i->ttd.tv_sec) break; + else + ++i; } } return false; diff --git a/pdns/mtasker_fcontext.cc b/pdns/mtasker_fcontext.cc index 362a2f797fc5..0ab87b6f6cc3 100644 --- a/pdns/mtasker_fcontext.cc +++ b/pdns/mtasker_fcontext.cc @@ -152,7 +152,7 @@ threadWrapper (transfer_t const t) { #if BOOST_VERSION < 106100 jump_fcontext (reinterpret_cast(&ctx->uc_mcontext), static_cast(next_ctx), - static_cast(ctx->exception)); + reinterpret_cast(ctx)); #else jump_fcontext (static_cast(next_ctx), 0); #endif @@ -189,10 +189,12 @@ pdns_swapcontext 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); - } + intptr_t ptr = jump_fcontext(reinterpret_cast(&octx.uc_mcontext), + static_cast(ctx.uc_mcontext), 0); + + auto origctx = reinterpret_cast(ptr); + if(origctx && origctx->exception) + std::rethrow_exception (origctx->exception); #else transfer_t res = jump_fcontext (static_cast(ctx.uc_mcontext), &octx.uc_mcontext); if (res.data) { diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index 0775481e1296..a3ab6121fd39 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -206,6 +206,7 @@ testrunner_SOURCES = \ ixfr.cc ixfr.hh \ logger.cc logger.hh \ misc.cc misc.hh \ + mtasker_context.cc \ negcache.hh negcache.cc \ namespaces.hh \ nsecrecords.cc \ @@ -237,6 +238,7 @@ testrunner_SOURCES = \ test-iputils_hh.cc \ test-ixfr_cc.cc \ test-misc_hh.cc \ + test-mtasker.cc \ test-nmtree.cc \ test-negcache_cc.cc \ test-rcpgenerator_cc.cc \ @@ -254,10 +256,12 @@ testrunner_SOURCES = \ testrunner_LDFLAGS = \ $(AM_LDFLAGS) \ + $(BOOST_CONTEXT_LDFLAGS) \ $(BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS) \ $(LIBCRYPTO_LDFLAGS) testrunner_LDADD = \ + $(BOOST_CONTEXT_LIBS) \ $(BOOST_UNIT_TEST_FRAMEWORK_LIBS) \ $(LIBCRYPTO_LIBS) \ $(RT_LIBS) diff --git a/pdns/recursordist/test-mtasker.cc b/pdns/recursordist/test-mtasker.cc new file mode 100644 index 000000000000..f6f1b5b46549 --- /dev/null +++ b/pdns/recursordist/test-mtasker.cc @@ -0,0 +1,60 @@ +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_NO_MAIN + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include +#include +#include "mtasker.hh" + +BOOST_AUTO_TEST_SUITE(mtasker_cc) + +static int g_result; + +static void doSomething(void* p) +{ + MTasker<>* mt = reinterpret_cast*>(p); + int i=12, o; + mt->waitEvent(i, &o); + g_result = o; + +} + +BOOST_AUTO_TEST_CASE(test_Simple) { + MTasker<> mt; + mt.makeThread(doSomething, &mt); + struct timeval now; + gettimeofday(&now, 0); + bool first=true; + int o=24; + for(;;) { + while(mt.schedule(&now)); + if(first) { + mt.sendEvent(12, &o); + first=false; + } + if(mt.noProcesses()) + break; + } + BOOST_CHECK_EQUAL(g_result, o); +} + +static void willThrow(void* p) +{ + throw std::runtime_error("Help!"); +} + + +BOOST_AUTO_TEST_CASE(test_MtaskerException) { + BOOST_CHECK_THROW( { + MTasker<> mt; + mt.makeThread(willThrow, 0); + struct timeval now; + + for(;;) { + mt.schedule(&now); + } + }, std::exception); +} +BOOST_AUTO_TEST_SUITE_END()