Add support for boost 1.56.

This commit is contained in:
Eric Frias 2014-09-07 18:02:39 -04:00
parent 9b6facea3f
commit 454573e048
6 changed files with 105 additions and 39 deletions

View file

@ -1,9 +1,19 @@
#pragma once
#if defined(_MSC_VER) && _MSC_VER >= 1400
#pragma warning(push)
#pragma warning(disable:4996)
#endif
#include <boost/signals2/signal.hpp>
#if defined(_MSC_VER) && _MSC_VER >= 1400
#pragma warning(pop)
#endif
#include <fc/thread/future.hpp>
#include <fc/thread/thread.hpp>
namespace fc {
#if !defined(BOOST_NO_TEMPLATE_ALIASES)
template<typename T>
@ -37,4 +47,3 @@ namespace fc {
p->wait( timeout_us );
}
}

View file

@ -1,7 +1,4 @@
#pragma once
namespace boost {
template<typename T> class atomic;
}
namespace fc {
class microseconds;

View file

@ -1,9 +1,5 @@
#pragma once
namespace boost {
template<typename T> class atomic;
}
namespace fc {
class microseconds;
class time_point;

View file

@ -7,10 +7,18 @@
#include <boost/version.hpp>
#if BOOST_VERSION >= 105400
#include <boost/coroutine/stack_context.hpp>
#include <boost/coroutine/stack_allocator.hpp>
# include <boost/coroutine/stack_context.hpp>
namespace bc = boost::context;
namespace bco = boost::coroutines;
# if BOOST_VERSION >= 105600 && !defined(NDEBUG)
# include <boost/assert.hpp>
# include <boost/coroutine/protected_stack_allocator.hpp>
typedef bco::protected_stack_allocator stack_allocator;
# else
# include <boost/coroutine/stack_allocator.hpp>
typedef bco::stack_allocator stack_allocator;
# endif
#elif BOOST_VERSION >= 105300
#include <boost/coroutine/stack_allocator.hpp>
namespace bc = boost::context;
@ -35,12 +43,12 @@ namespace fc {
struct context {
typedef fc::context* ptr;
#if BOOST_VERSION >= 105400
#if BOOST_VERSION >= 105400
bco::stack_context stack_ctx;
#endif
#endif
context( void (*sf)(intptr_t), bco::stack_allocator& alloc, fc::thread* t )
context( void (*sf)(intptr_t), stack_allocator& alloc, fc::thread* t )
: caller_context(0),
stack_alloc(&alloc),
next_blocked(0),
@ -54,7 +62,11 @@ namespace fc {
complete(false),
cur_task(0)
{
#if BOOST_VERSION >= 105400
#if BOOST_VERSION >= 105600
size_t stack_size = stack_allocator::traits_type::default_size() * 4;
alloc.allocate(stack_ctx, stack_size);
my_context = bc::make_fcontext( stack_ctx.sp, stack_ctx.size, sf);
#elif BOOST_VERSION >= 105400
size_t stack_size = bco::stack_allocator::default_stacksize() * 4;
alloc.allocate(stack_ctx, stack_size);
my_context = bc::make_fcontext( stack_ctx.sp, stack_ctx.size, sf);
@ -71,7 +83,9 @@ namespace fc {
}
context( fc::thread* t) :
#if BOOST_VERSION >= 105300
#if BOOST_VERSION >= 105600
my_context(nullptr),
#elif BOOST_VERSION >= 105300
my_context(new bc::fcontext_t),
#endif
caller_context(0),
@ -89,20 +103,17 @@ namespace fc {
{}
~context() {
#if BOOST_VERSION >= 105400
#if BOOST_VERSION >= 105600
if(stack_alloc)
stack_alloc->deallocate( stack_ctx );
#elif BOOST_VERSION >= 105400
if(stack_alloc)
stack_alloc->deallocate( stack_ctx );
else
delete my_context;
#elif BOOST_VERSION >= 105400
if(stack_alloc)
stack_alloc->deallocate( my_context->fc_stack.sp, bco::stack_allocator::default_stacksize() * 4 );
else
delete my_context;
#elif BOOST_VERSION >= 105300
if(stack_alloc)
stack_alloc->deallocate( my_context->fc_stack.sp, bco::stack_allocator::default_stacksize() * 4);
stack_alloc->deallocate( my_context->fc_stack.sp, stack_allocator::default_stacksize() * 4);
else
delete my_context;
#else
@ -196,13 +207,13 @@ namespace fc {
#if BOOST_VERSION >= 105300
#if BOOST_VERSION >= 105300 && BOOST_VERSION < 105600
bc::fcontext_t* my_context;
#else
bc::fcontext_t my_context;
#endif
fc::context* caller_context;
bco::stack_allocator* stack_alloc;
stack_allocator* stack_alloc;
priority prio;
//promise_base* prom;
std::vector<blocked_promise> blocking_prom;

View file

@ -68,26 +68,26 @@ namespace fc {
}
fc::thread& self;
boost::thread* boost_thread;
bco::stack_allocator stack_alloc;
stack_allocator stack_alloc;
boost::condition_variable task_ready;
boost::mutex task_ready_mutex;
boost::atomic<task_base*> task_in_queue;
std::vector<task_base*> task_pqueue;
std::vector<task_base*> task_sch_queue;
std::vector<fc::context*> sleep_pqueue;
std::vector<fc::context*> free_list;
std::vector<task_base*> task_pqueue; // heap of tasks that have never started, ordered by proirity & scheduling time
std::vector<task_base*> task_sch_queue; // heap of tasks that have never started but are scheduled for a time in the future, ordered by the time they should be run
std::vector<fc::context*> sleep_pqueue; // heap of running tasks that have sleeped, ordered by the time they should resume
std::vector<fc::context*> free_list; // list of unused contexts that are ready for deletion
bool done;
fc::string name;
fc::context* current;
fc::context* current; // the currently-executing task in this thread
fc::context* pt_head;
fc::context* pt_head; // list of contexts that can be reused for new tasks
fc::context* ready_head;
fc::context* ready_head; // linked list (using 'next') of contexts that are ready to run
fc::context* ready_tail;
fc::context* blocked;
fc::context* blocked; // linked list of contexts (using 'next_blocked') blocked on promises via wait()
// values for thread specific data objects for this thread
std::vector<detail::specific_data_info> thread_specific_data;
@ -321,8 +321,10 @@ namespace fc {
current = next;
if( reschedule ) ready_push_back(prev);
// 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 >= 105300
// fc_dlog( logger::get("fc_context"), "from ${from} to ${to}", ( "from", int64_t(prev) )( "to", int64_t(next) ) );
#if 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 );
#else
bc::jump_fcontext( &prev->my_context, &next->my_context, 0 );
@ -350,7 +352,9 @@ 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 >= 105300
#if 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 );
#else
bc::jump_fcontext( &prev->my_context, &next->my_context, (intptr_t)this );

View file

@ -93,7 +93,7 @@ BOOST_AUTO_TEST_CASE( test_non_preemptable_assertion )
BOOST_TEST_PASSPOINT();
}
BOOST_AUTO_TEST_CASE( cancel_an_active_task )
BOOST_AUTO_TEST_CASE( cancel_an_sleeping_task )
{
enum task_result{sleep_completed, sleep_aborted};
fc::future<task_result> task = fc::async([]() {
@ -128,6 +128,55 @@ BOOST_AUTO_TEST_CASE( cancel_an_active_task )
}
}
BOOST_AUTO_TEST_CASE( cancel_a_task_waiting_on_promise )
{
enum task_result{task_completed, task_aborted};
fc::promise<void>::ptr promise_to_wait_on(new fc::promise<void>());
fc::future<task_result> task = fc::async([promise_to_wait_on]() {
BOOST_TEST_MESSAGE("Starting async task");
try
{
promise_to_wait_on->wait_until(fc::time_point::now() + fc::seconds(5));
return task_completed;
}
catch (const fc::canceled_exception&)
{
BOOST_TEST_MESSAGE("Caught canceled_exception inside task-to-be-canceled");
throw;
}
catch (const fc::timeout_exception&)
{
BOOST_TEST_MESSAGE("Caught timeout_exception inside task-to-be-canceled");
throw;
}
catch (const fc::exception& e)
{
BOOST_TEST_MESSAGE("Caught unexpected exception inside task-to-be-canceled: " << e.to_detail_string());
return task_aborted;
}
}, "test_task");
fc::time_point start_time = fc::time_point::now();
// wait a bit for the task to start running
fc::usleep(fc::milliseconds(100));
BOOST_TEST_MESSAGE("Canceling task");
task.cancel("canceling to test if cancel works");
//promise_to_wait_on->set_value();
try
{
task_result result = task.wait();
BOOST_CHECK_MESSAGE(result != task_completed, "task should have been canceled");
}
catch (fc::exception& e)
{
BOOST_TEST_MESSAGE("Caught exception from canceled task: " << e.what());
BOOST_CHECK_MESSAGE(fc::time_point::now() - start_time < fc::seconds(4), "Task was not canceled quickly");
}
}
BOOST_AUTO_TEST_CASE( cleanup_cancelled_task )
{