Add support for boost 1.56.
This commit is contained in:
parent
9b6facea3f
commit
454573e048
6 changed files with 105 additions and 39 deletions
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
#pragma once
|
||||
namespace boost {
|
||||
template<typename T> class atomic;
|
||||
}
|
||||
|
||||
namespace fc {
|
||||
class microseconds;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
namespace boost {
|
||||
template<typename T> class atomic;
|
||||
}
|
||||
|
||||
namespace fc {
|
||||
class microseconds;
|
||||
class time_point;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue