Merge pull request #284 from lowsfer/fiber-ctor-with-prop

Allow setting fiber properties on construction
This commit is contained in:
Oliver Kowalke
2021-10-02 22:37:28 +02:00
committed by GitHub
3 changed files with 99 additions and 2 deletions
+24 -1
View File
@@ -452,22 +452,35 @@ private:
public:
template< typename StackAlloc >
worker_context( launch policy,
fiber_properties* properties,
boost::context::preallocated const& palloc, StackAlloc && salloc,
Fn && fn, Arg ... arg) :
context{ 1, type::worker_context, policy },
fn_( std::forward< Fn >( fn) ),
arg_( std::forward< Arg >( arg) ... ) {
if ( properties != nullptr ) {
set_properties(properties);
properties->set_context(this);
}
c_ = boost::context::fiber{ std::allocator_arg, palloc, std::forward< StackAlloc >( salloc),
std::bind( & worker_context::run_, this, std::placeholders::_1) };
#if (defined(BOOST_USE_UCONTEXT)||defined(BOOST_USE_WINFIB))
c_ = std::move( c_).resume();
#endif
}
template< typename StackAlloc >
worker_context( launch policy,
boost::context::preallocated const& palloc, StackAlloc && salloc,
Fn && fn, Arg ... arg) :
worker_context( policy, palloc, salloc, nullptr, std::forward<Fn>( fn ), std::forward<Arg>( arg ) ... ){
}
};
template< typename StackAlloc, typename Fn, typename ... Arg >
static intrusive_ptr< context > make_worker_context( launch policy,
static intrusive_ptr< context > make_worker_context_with_properties( launch policy,
fiber_properties* properties,
StackAlloc && salloc,
Fn && fn, Arg ... arg) {
typedef worker_context< Fn, Arg ... > context_t;
@@ -484,12 +497,22 @@ static intrusive_ptr< context > make_worker_context( launch policy,
return intrusive_ptr< context >{
new ( storage) context_t{
policy,
properties,
boost::context::preallocated{ storage, size, sctx },
std::forward< StackAlloc >( salloc),
std::forward< Fn >( fn),
std::forward< Arg >( arg) ... } };
}
template< typename StackAlloc, typename Fn, typename ... Arg >
static intrusive_ptr< context > make_worker_context( launch policy,
StackAlloc && salloc,
Fn && fn, Arg ... arg){
return make_worker_context_with_properties( policy, nullptr, std::forward<StackAlloc>(salloc),
std::forward<Fn>( fn ), std::forward<Arg>( arg ) ... );
}
}}
#ifdef _MSC_VER
+63 -1
View File
@@ -105,7 +105,69 @@ public:
#else
fiber( launch policy, std::allocator_arg_t, StackAllocator && salloc, Fn && fn, Arg ... arg) :
#endif
impl_{ make_worker_context( policy, std::forward< StackAllocator >( salloc), std::forward< Fn >( fn), std::forward< Arg >( arg) ... ) } {
fiber{ policy,
static_cast<fiber_properties*>(nullptr),
std::allocator_arg, std::forward< StackAllocator >( salloc),
std::forward< Fn >( fn), std::forward< Arg >( arg) ... } {
}
template< typename Fn,
typename ... Arg,
typename = detail::disable_overload< fiber, Fn >,
typename = detail::disable_overload< launch, Fn >,
typename = detail::disable_overload< std::allocator_arg_t, Fn >
>
#if BOOST_COMP_GNUC < 50000000
explicit fiber( fiber_properties* properties, Fn && fn, Arg && ... arg) :
#else
fiber( fiber_properties* properties, Fn && fn, Arg ... arg) :
#endif
fiber{ launch::post,
properties,
std::allocator_arg, default_stack(),
std::forward< Fn >( fn), std::forward< Arg >( arg) ... } {
}
template< typename Fn,
typename ... Arg,
typename = detail::disable_overload< fiber, Fn >
>
#if BOOST_COMP_GNUC < 50000000
fiber( launch policy, fiber_properties* properties, Fn && fn, Arg && ... arg) :
#else
fiber( launch policy, fiber_properties* properties, Fn && fn, Arg ... arg) :
#endif
fiber{ policy,
properties,
std::allocator_arg, default_stack(),
std::forward< Fn >( fn), std::forward< Arg >( arg) ... } {
}
template< typename StackAllocator,
typename Fn,
typename ... Arg
>
#if BOOST_COMP_GNUC < 50000000
fiber( fiber_properties* properties, std::allocator_arg_t, StackAllocator && salloc, Fn && fn, Arg && ... arg) :
#else
fiber( fiber_properties* properties, std::allocator_arg_t, StackAllocator && salloc, Fn && fn, Arg ... arg) :
#endif
fiber{ launch::post,
properties,
std::allocator_arg, std::forward< StackAllocator >( salloc),
std::forward< Fn >( fn), std::forward< Arg >( arg) ... } {
}
template< typename StackAllocator,
typename Fn,
typename ... Arg
>
#if BOOST_COMP_GNUC < 50000000
fiber( launch policy, fiber_properties* properties, std::allocator_arg_t, StackAllocator && salloc, Fn && fn, Arg && ... arg) :
#else
fiber( launch policy, fiber_properties* properties, std::allocator_arg_t, StackAllocator && salloc, Fn && fn, Arg ... arg) :
#endif
impl_{ make_worker_context_with_properties( policy, properties, std::forward< StackAllocator >( salloc), std::forward< Fn >( fn), std::forward< Arg >( arg) ... ) } {
start_();
}
+12
View File
@@ -10,6 +10,7 @@
#ifndef BOOST_FIBERS_PROPERTIES_HPP
#define BOOST_FIBERS_PROPERTIES_HPP
#include <boost/assert.hpp>
#include <boost/fiber/detail/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
@@ -50,6 +51,9 @@ public:
// fiber_properties, and by implication every subclass, must accept a back
// pointer to its context.
// For fiber_properties passed to fiber constructors, nullptr must be
// used here.
explicit fiber_properties( context * ctx) noexcept :
ctx_{ ctx } {
}
@@ -64,6 +68,14 @@ public:
void set_algorithm( algo::algorithm * algo) noexcept {
algo_ = algo;
}
// not really intended for public use, but required to set properties
// on fiber/context construction.
void set_context( context* ctx ) noexcept {
BOOST_ASSERT( ctx_ == nullptr );
BOOST_ASSERT( ctx != nullptr );
ctx_ = ctx;
}
};
}} // namespace boost::fibers