peerplays-fc/include/fc/task.hpp
Daniel Larimer 9a8767a645 Fixed error_report to_string
Updated fc::datastream and base64 to use error_report
Added url to cmake lists
various other bug fixes
2012-12-15 10:26:03 -05:00

96 lines
2.9 KiB
C++

#ifndef _FC_TASK_HPP_
#define _FC_TASK_HPP_
#include <fc/future.hpp>
#include <fc/priority.hpp>
#include <fc/aligned.hpp>
#include <fc/fwd.hpp>
namespace fc {
struct context;
class spin_lock;
class task_base : virtual public promise_base {
public:
void run();
protected:
~task_base();
uint64_t _posted_num;
priority _prio;
time_point _when;
void _set_active_context(context*);
context* _active_context;
task_base* _next;
task_base(void* func);
// opaque internal / private data used by
// thread/thread_private
friend class thread;
friend class thread_d;
fwd<spin_lock,8> _spinlock;
// avoid rtti info for every possible functor...
void* _promise_impl;
void* _functor;
void (*_destroy_functor)(void*);
void (*_run_functor)(void*, void* );
};
namespace detail {
template<typename T>
struct functor_destructor {
static void destroy( void* v ) { ((T*)v)->~T(); }
};
template<typename T>
struct functor_run {
static void run( void* functor, void* prom ) {
((promise<decltype((*((T*)functor))())>*)prom)->set_value( (*((T*)functor))() );
}
};
template<typename T>
struct void_functor_run {
static void run( void* functor, void* prom ) {
(*((T*)functor))();
((promise<void>*)prom)->set_value();
}
};
}
template<typename R,uint64_t FunctorSize=64>
class task : virtual public task_base, virtual public promise<R> {
public:
template<typename Functor>
task( Functor&& f ):task_base(&_functor) {
typedef typename fc::deduce<Functor>::type FunctorType;
static_assert( sizeof(f) <= sizeof(_functor), "sizeof(Functor) is larger than FunctorSize" );
new ((char*)&_functor) FunctorType( fc::forward<Functor>(f) );
_destroy_functor = &detail::functor_destructor<FunctorType>::destroy;
_promise_impl = static_cast<promise<R>*>(this);
_run_functor = &detail::functor_run<FunctorType>::run;
}
aligned<FunctorSize> _functor;
private:
~task(){}
};
template<uint64_t FunctorSize>
class task<void,FunctorSize> : virtual public task_base, virtual public promise<void> {
public:
template<typename Functor>
task( Functor&& f ):task_base(&_functor) {
typedef typename fc::deduce<Functor>::type FunctorType;
static_assert( sizeof(f) <= sizeof(_functor), "sizeof(Functor) is larger than FunctorSize" );
new ((char*)&_functor) FunctorType( fc::forward<Functor>(f) );
_destroy_functor = &detail::functor_destructor<FunctorType>::destroy;
_promise_impl = static_cast<promise<void>*>(this);
_run_functor = &detail::void_functor_run<FunctorType>::run;
}
aligned<FunctorSize> _functor;
private:
~task(){}
};
}
#endif // _FC_TASK_HPP_