Boost 1.61 compatibility fix

This commit is contained in:
Anton Autushka 2017-11-09 15:18:58 +03:00
parent cb627980a5
commit c2a37a83bd
4 changed files with 130 additions and 4 deletions

View file

@ -6,7 +6,14 @@
#include <boost/version.hpp>
#if BOOST_VERSION >= 105400
#define BOOST_COROUTINES_NO_DEPRECATION_WARNING
#if BOOST_VERSION >= 106100
#include <boost/coroutine/stack_allocator.hpp>
namespace bc = boost::context::detail;
namespace bco = boost::coroutines;
typedef bco::stack_allocator stack_allocator;
#elif BOOST_VERSION >= 105400
# include <boost/coroutine/stack_context.hpp>
namespace bc = boost::context;
namespace bco = boost::coroutines;
@ -47,8 +54,13 @@ namespace fc {
bco::stack_context stack_ctx;
#endif
#if BOOST_VERSION >= 106100
using context_fn = void (*)(bc::transfer_t);
#else
using context_fn = void(*)(intptr_t);
#endif
context( void (*sf)(intptr_t), stack_allocator& alloc, fc::thread* t )
context( context_fn sf, stack_allocator& alloc, fc::thread* t )
: caller_context(0),
stack_alloc(&alloc),
next_blocked(0),

View file

@ -18,6 +18,8 @@ namespace fc {
class thread_d {
public:
using context_pair = std::pair<thread_d*, fc::context*>;
thread_d(fc::thread& s)
:self(s), boost_thread(0),
task_in_queue(0),
@ -397,7 +399,11 @@ namespace fc {
}
// slog( "jump to %p from %p", next, prev );
// fc_dlog( logger::get("fc_context"), "from ${from} to ${to}", ( "from", int64_t(prev) )( "to", int64_t(next) ) );
#if BOOST_VERSION >= 105600
#if BOOST_VERSION >= 106100
auto p = context_pair{nullptr, prev};
auto t = bc::jump_fcontext( next->my_context, &p );
static_cast<context_pair*>(t.data)->second->my_context = t.fctx;
#elif BOOST_VERSION >= 105600
bc::jump_fcontext( &prev->my_context, next->my_context, 0 );
#elif BOOST_VERSION >= 105300
bc::jump_fcontext( prev->my_context, next->my_context, 0 );
@ -439,7 +445,11 @@ namespace fc {
// slog( "jump to %p from %p", next, prev );
// fc_dlog( logger::get("fc_context"), "from ${from} to ${to}", ( "from", int64_t(prev) )( "to", int64_t(next) ) );
#if BOOST_VERSION >= 105600
#if BOOST_VERSION >= 106100
auto p = context_pair{this, prev};
auto t = bc::jump_fcontext( next->my_context, &p );
static_cast<context_pair*>(t.data)->second->my_context = t.fctx;
#elif BOOST_VERSION >= 105600
bc::jump_fcontext( &prev->my_context, next->my_context, (intptr_t)this );
#elif BOOST_VERSION >= 105300
bc::jump_fcontext( prev->my_context, next->my_context, (intptr_t)this );
@ -467,9 +477,17 @@ namespace fc {
return true;
}
#if BOOST_VERSION >= 106100
static void start_process_tasks( bc::transfer_t my )
{
auto p = static_cast<context_pair*>(my.data);
auto self = static_cast<thread_d*>(p->first);
p->second->my_context = my.fctx;
#else
static void start_process_tasks( intptr_t my )
{
thread_d* self = (thread_d*)my;
#endif
try
{
self->process_tasks();

View file

@ -51,6 +51,7 @@ add_executable( all_tests all_tests.cpp
crypto/sha_tests.cpp
network/http/websocket_test.cpp
thread/task_cancel.cpp
thread/thread_tests.cpp
bloom_test.cpp
real128_test.cpp
utf8_test.cpp

View file

@ -0,0 +1,95 @@
#include <boost/test/unit_test.hpp>
#include <fc/thread/thread.hpp>
using namespace fc;
BOOST_AUTO_TEST_SUITE(thread_tests)
BOOST_AUTO_TEST_CASE(executes_task)
{
bool called = false;
fc::thread thread("my");
thread.async([&called]{called = true;}).wait();
BOOST_CHECK(called);
}
BOOST_AUTO_TEST_CASE(returns_value_from_function)
{
fc::thread thread("my");
BOOST_CHECK_EQUAL(10, thread.async([]{return 10;}).wait());
}
BOOST_AUTO_TEST_CASE(executes_multiple_tasks)
{
bool called1 = false;
bool called2 = false;
fc::thread thread("my");
auto future1 = thread.async([&called1]{called1 = true;});
auto future2 = thread.async([&called2]{called2 = true;});
future2.wait();
future1.wait();
BOOST_CHECK(called1);
BOOST_CHECK(called2);
}
BOOST_AUTO_TEST_CASE(calls_tasks_in_order)
{
std::string result;
fc::thread thread("my");
auto future1 = thread.async([&result]{result += "hello ";});
auto future2 = thread.async([&result]{result += "world";});
future2.wait();
future1.wait();
BOOST_CHECK_EQUAL("hello world", result);
}
BOOST_AUTO_TEST_CASE(yields_execution)
{
std::string result;
fc::thread thread("my");
auto future1 = thread.async([&result]{fc::yield(); result += "world";});
auto future2 = thread.async([&result]{result += "hello ";});
future2.wait();
future1.wait();
BOOST_CHECK_EQUAL("hello world", result);
}
BOOST_AUTO_TEST_CASE(quits_infinite_loop)
{
fc::thread thread("my");
auto f = thread.async([]{while (true) fc::yield();});
thread.quit();
BOOST_CHECK_THROW(f.wait(), fc::canceled_exception);
}
BOOST_AUTO_TEST_CASE(reschedules_yielded_task)
{
int reschedule_count = 0;
fc::thread thread("my");
auto future = thread.async([&reschedule_count]
{
while (reschedule_count < 10)
{
fc::yield();
reschedule_count++;
}
});
future.wait();
BOOST_CHECK_EQUAL(10, reschedule_count);
}
BOOST_AUTO_TEST_SUITE_END()