mirror of
https://github.com/boostorg/fiber.git
synced 2026-02-19 02:12:24 +00:00
use allocator_traits
This commit is contained in:
@@ -37,22 +37,25 @@ public:
|
||||
|
||||
private:
|
||||
struct node {
|
||||
typedef intrusive_ptr< node > ptr;
|
||||
typedef typename std::allocator_traits< Allocator >::template rebind_alloc< node > allocator_type;
|
||||
typedef intrusive_ptr< node > ptr_t;
|
||||
typedef typename std::allocator_traits< Allocator >::template rebind_alloc<
|
||||
node
|
||||
> allocator_t;
|
||||
typedef std::allocator_traits< allocator_t > allocator_traits_t;
|
||||
|
||||
std::size_t use_count{ 0 };
|
||||
allocator_type & alloc;
|
||||
T va;
|
||||
ptr nxt{};
|
||||
std::size_t use_count{ 0 };
|
||||
allocator_t alloc;
|
||||
T va;
|
||||
ptr_t nxt{};
|
||||
|
||||
node( T const& t, allocator_type & alloc_) noexcept :
|
||||
node( T const& t, allocator_t const& alloc_) noexcept :
|
||||
alloc{ alloc_ },
|
||||
va{ t } {
|
||||
}
|
||||
|
||||
node( T && t, allocator_type & alloc_) noexcept :
|
||||
node( T && t, allocator_t & alloc_) noexcept :
|
||||
alloc{ alloc_ },
|
||||
va{ std::forward< T >( t) } {
|
||||
va{ std::move( t) } {
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -63,30 +66,32 @@ private:
|
||||
friend
|
||||
void intrusive_ptr_release( node * p) noexcept {
|
||||
if ( 0 == --p->use_count) {
|
||||
allocator_type & alloc( p->alloc);
|
||||
std::allocator_traits< allocator_type >::destroy( alloc, p);
|
||||
std::allocator_traits< allocator_type >::deallocate( alloc, p, 1);
|
||||
allocator_t alloc( p->alloc);
|
||||
allocator_traits_t::destroy( alloc, p);
|
||||
allocator_traits_t::deallocate( alloc, p, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef typename std::allocator_traits< Allocator >::template rebind_alloc< node > allocator_type;
|
||||
using ptr_t = typename node::ptr_t;
|
||||
using allocator_t = typename node::allocator_t;
|
||||
using allocator_traits_t = typename node::allocator_traits_t;
|
||||
|
||||
enum class queue_status {
|
||||
open = 0,
|
||||
closed
|
||||
};
|
||||
|
||||
allocator_type alloc_;
|
||||
queue_status state_{ queue_status::open };
|
||||
std::size_t count_{ 0 };
|
||||
typename node::ptr head_{};
|
||||
typename node::ptr * tail_;
|
||||
mutable mutex mtx_{};
|
||||
condition not_empty_cond_{};
|
||||
condition not_full_cond_{};
|
||||
std::size_t hwm_;
|
||||
std::size_t lwm_;
|
||||
allocator_t alloc_;
|
||||
queue_status state_{ queue_status::open };
|
||||
std::size_t count_{ 0 };
|
||||
ptr_t head_{};
|
||||
ptr_t * tail_;
|
||||
mutable mutex mtx_{};
|
||||
condition not_empty_cond_{};
|
||||
condition not_full_cond_{};
|
||||
std::size_t hwm_;
|
||||
std::size_t lwm_;
|
||||
|
||||
bool is_closed_() const noexcept {
|
||||
return queue_status::closed == state_;
|
||||
@@ -111,7 +116,7 @@ private:
|
||||
return count_ >= hwm_;
|
||||
}
|
||||
|
||||
channel_op_status push_( typename node::ptr const& new_node,
|
||||
channel_op_status push_( ptr_t new_node,
|
||||
std::unique_lock< boost::fibers::mutex > & lk) {
|
||||
if ( is_closed_() ) {
|
||||
return channel_op_status::closed;
|
||||
@@ -122,7 +127,7 @@ private:
|
||||
return push_and_notify_( new_node, lk);
|
||||
}
|
||||
|
||||
channel_op_status try_push_( typename node::ptr const& new_node,
|
||||
channel_op_status try_push_( ptr_t new_node,
|
||||
std::unique_lock< boost::fibers::mutex > & lk) noexcept {
|
||||
if ( is_closed_() ) {
|
||||
return channel_op_status::closed;
|
||||
@@ -134,7 +139,7 @@ private:
|
||||
}
|
||||
|
||||
template< typename Clock, typename Duration >
|
||||
channel_op_status push_wait_until_( typename node::ptr const& new_node,
|
||||
channel_op_status push_wait_until_( ptr_t new_node,
|
||||
std::chrono::time_point< Clock, Duration > const& timeout_time,
|
||||
std::unique_lock< boost::fibers::mutex > & lk) {
|
||||
if ( is_closed_() ) {
|
||||
@@ -148,7 +153,7 @@ private:
|
||||
return push_and_notify_( new_node, lk);
|
||||
}
|
||||
|
||||
channel_op_status push_and_notify_( typename node::ptr const& new_node,
|
||||
channel_op_status push_and_notify_( ptr_t new_node,
|
||||
std::unique_lock< boost::fibers::mutex > & lk) noexcept {
|
||||
push_tail_( new_node);
|
||||
lk.unlock();
|
||||
@@ -156,7 +161,7 @@ private:
|
||||
return channel_op_status::success;
|
||||
}
|
||||
|
||||
void push_tail_( typename node::ptr new_node) noexcept {
|
||||
void push_tail_( ptr_t new_node) noexcept {
|
||||
* tail_ = new_node;
|
||||
tail_ = & new_node->nxt;
|
||||
++count_;
|
||||
@@ -179,7 +184,7 @@ private:
|
||||
return std::move( old_head->va);
|
||||
}
|
||||
|
||||
typename node::ptr pop_head_() noexcept {
|
||||
ptr_t pop_head_() noexcept {
|
||||
auto old_head = head_;
|
||||
head_ = old_head->nxt;
|
||||
if ( ! head_) {
|
||||
@@ -236,17 +241,30 @@ public:
|
||||
}
|
||||
|
||||
channel_op_status push( value_type const& va) {
|
||||
typename node::ptr new_node(
|
||||
new ( alloc_.allocate( 1) ) node( va, alloc_) );
|
||||
typename allocator_traits_t::pointer ptr{
|
||||
allocator_traits_t::allocate( alloc_, 1) };
|
||||
try {
|
||||
allocator_traits_t::construct( alloc_, ptr, va, alloc_);
|
||||
} catch (...) {
|
||||
allocator_traits_t::deallocate( alloc_, ptr, 1);
|
||||
throw;
|
||||
}
|
||||
std::unique_lock< mutex > lk( mtx_);
|
||||
return push_( new_node, lk);
|
||||
return push_( { detail::convert( ptr) }, lk);
|
||||
}
|
||||
|
||||
channel_op_status push( value_type && va) {
|
||||
typename node::ptr new_node(
|
||||
new ( alloc_.allocate( 1) ) node( std::forward< value_type >( va), alloc_) );
|
||||
typename allocator_traits_t::pointer ptr{
|
||||
allocator_traits_t::allocate( alloc_, 1) };
|
||||
try {
|
||||
allocator_traits_t::construct(
|
||||
alloc_, ptr, std::move( va), alloc_);
|
||||
} catch (...) {
|
||||
allocator_traits_t::deallocate( alloc_, ptr, 1);
|
||||
throw;
|
||||
}
|
||||
std::unique_lock< mutex > lk( mtx_);
|
||||
return push_( new_node, lk);
|
||||
return push_( { detail::convert( ptr) }, lk);
|
||||
}
|
||||
|
||||
template< typename Rep, typename Period >
|
||||
@@ -266,33 +284,59 @@ public:
|
||||
template< typename Clock, typename Duration >
|
||||
channel_op_status push_wait_until( value_type const& va,
|
||||
std::chrono::time_point< Clock, Duration > const& timeout_time) {
|
||||
typename node::ptr new_node(
|
||||
new ( alloc_.allocate( 1) ) node( va, alloc_) );
|
||||
typename allocator_traits_t::pointer ptr{
|
||||
allocator_traits_t::allocate( alloc_, 1) };
|
||||
try {
|
||||
allocator_traits_t::construct( alloc_, ptr, va, alloc_);
|
||||
} catch (...) {
|
||||
allocator_traits_t::deallocate( alloc_, ptr, 1);
|
||||
throw;
|
||||
}
|
||||
std::unique_lock< mutex > lk( mtx_);
|
||||
return push_wait_until_( new_node, timeout_time, lk);
|
||||
return push_wait_until_( { detail::convert( ptr) }, timeout_time, lk);
|
||||
}
|
||||
|
||||
template< typename Clock, typename Duration >
|
||||
channel_op_status push_wait_until( value_type && va,
|
||||
std::chrono::time_point< Clock, Duration > const& timeout_time) {
|
||||
typename node::ptr new_node(
|
||||
new ( alloc_.allocate( 1) ) node( std::forward< value_type >( va), alloc_) );
|
||||
typename allocator_traits_t::pointer ptr{
|
||||
allocator_traits_t::allocate( alloc_, 1) };
|
||||
try {
|
||||
allocator_traits_t::construct(
|
||||
alloc_, ptr, std::move( va), alloc_);
|
||||
} catch (...) {
|
||||
allocator_traits_t::deallocate( alloc_, ptr, 1);
|
||||
throw;
|
||||
}
|
||||
std::unique_lock< mutex > lk( mtx_);
|
||||
return push_wait_until_( new_node, timeout_time, lk);
|
||||
return push_wait_until_( { detail::convert( ptr) }, timeout_time, lk);
|
||||
}
|
||||
|
||||
channel_op_status try_push( value_type const& va) noexcept {
|
||||
typename node::ptr new_node(
|
||||
new ( alloc_.allocate( 1) ) node( va, alloc_) );
|
||||
typename allocator_traits_t::pointer ptr{
|
||||
allocator_traits_t::allocate( alloc_, 1) };
|
||||
try {
|
||||
allocator_traits_t::construct( alloc_, ptr, va, alloc_);
|
||||
} catch (...) {
|
||||
allocator_traits_t::deallocate( alloc_, ptr, 1);
|
||||
throw;
|
||||
}
|
||||
std::unique_lock< mutex > lk( mtx_);
|
||||
return try_push_( new_node, lk);
|
||||
return try_push_( { detail::convert( ptr) }, lk);
|
||||
}
|
||||
|
||||
channel_op_status try_push( value_type && va) noexcept {
|
||||
typename node::ptr new_node(
|
||||
new ( alloc_.allocate( 1) ) node( std::forward< value_type >( va), alloc_) );
|
||||
typename allocator_traits_t::pointer ptr{
|
||||
allocator_traits_t::allocate( alloc_, 1) };
|
||||
try {
|
||||
allocator_traits_t::construct(
|
||||
alloc_, ptr, std::move( va), alloc_);
|
||||
} catch (...) {
|
||||
allocator_traits_t::deallocate( alloc_, ptr, 1);
|
||||
throw;
|
||||
}
|
||||
std::unique_lock< mutex > lk( mtx_);
|
||||
return try_push_( new_node, lk);
|
||||
return try_push_( { detail::convert( ptr) }, lk);
|
||||
}
|
||||
|
||||
channel_op_status pop( value_type & va) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define BOOST_FIBERS_DETAIL_CONVERT_H
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
@@ -33,6 +34,22 @@ std::chrono::steady_clock::time_point convert(
|
||||
return std::chrono::steady_clock::now() + ( timeout_time - Clock::now() );
|
||||
}
|
||||
|
||||
// suggested by Howard Hinnant
|
||||
template< typename T >
|
||||
inline
|
||||
T * convert( T * p) noexcept {
|
||||
return p;
|
||||
}
|
||||
|
||||
template< typename Pointer >
|
||||
inline
|
||||
typename std::pointer_traits< Pointer >::element_type *
|
||||
convert( Pointer p) noexcept {
|
||||
return nullptr != p
|
||||
? to_raw_pointer( p.operator->() )
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#ifndef BOOST_FIBERS_DETAIL_SHARED_STATE_OBJECT_H
|
||||
#define BOOST_FIBERS_DETAIL_SHARED_STATE_OBJECT_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/fiber/detail/config.hpp>
|
||||
@@ -23,9 +25,9 @@ namespace detail {
|
||||
template< typename R, typename Allocator >
|
||||
class shared_state_object : public shared_state< R > {
|
||||
public:
|
||||
typedef typename Allocator::template rebind<
|
||||
shared_state_object< R, Allocator >
|
||||
>::other allocator_t;
|
||||
typedef typename std::allocator_traits< Allocator >::template rebind_alloc<
|
||||
shared_state_object
|
||||
> allocator_t;
|
||||
|
||||
shared_state_object( allocator_t const& alloc) :
|
||||
shared_state< R >(), alloc_( alloc) {
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
#define BOOST_FIBERS_DETAIL_TASK_OBJECT_H
|
||||
|
||||
#include <exception>
|
||||
#include <utility> // std::forward()
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/context/detail/invoke.hpp>
|
||||
@@ -27,13 +28,13 @@ namespace detail {
|
||||
template< typename Fn, typename Allocator, typename R, typename ... Args >
|
||||
class task_object : public task_base< R, Args ... > {
|
||||
public:
|
||||
typedef typename Allocator::template rebind<
|
||||
task_object< Fn, Allocator, R, Args ... >
|
||||
>::other allocator_t;
|
||||
typedef typename std::allocator_traits< Allocator >::template rebind_alloc<
|
||||
task_object
|
||||
> allocator_t;
|
||||
|
||||
explicit task_object( allocator_t const& alloc, Fn && fn) :
|
||||
task_object( allocator_t const& alloc, Fn && fn) :
|
||||
task_base< R, Args ... >(),
|
||||
fn_( std::forward< Fn >( fn) ),
|
||||
fn_( std::move( fn) ),
|
||||
alloc_( alloc) {
|
||||
}
|
||||
|
||||
@@ -69,9 +70,9 @@ public:
|
||||
task_object< Fn, Allocator, void, Args ... >
|
||||
>::other allocator_t;
|
||||
|
||||
explicit task_object( allocator_t const& alloc, Fn && fn) :
|
||||
task_object( allocator_t const& alloc, Fn && fn) :
|
||||
task_base< void, Args ... >(),
|
||||
fn_( std::forward< Fn >( fn) ),
|
||||
fn_( std::move( fn) ),
|
||||
alloc_( alloc) {
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/fiber/detail/convert.hpp>
|
||||
#include <boost/fiber/exceptions.hpp>
|
||||
#include <boost/fiber/future/detail/task_base.hpp>
|
||||
#include <boost/fiber/future/detail/task_object.hpp>
|
||||
@@ -42,31 +43,30 @@ public:
|
||||
}
|
||||
|
||||
template< typename Fn >
|
||||
explicit packaged_task( Fn && fn) {
|
||||
typedef detail::task_object<
|
||||
Fn,
|
||||
std::allocator< packaged_task< R() > >,
|
||||
R,
|
||||
Args ...
|
||||
> object_t;
|
||||
std::allocator< packaged_task< R() > > alloc;
|
||||
typename object_t::allocator_t a{ alloc };
|
||||
task_ = ptr_t{
|
||||
// placement new
|
||||
::new( a.allocate( 1) ) object_t{ a, std::forward< Fn >( fn) } };
|
||||
explicit packaged_task( Fn && fn) :
|
||||
packaged_task{ std::allocator_arg,
|
||||
std::allocator< packaged_task >{},
|
||||
std::forward< Fn >( fn) } {
|
||||
}
|
||||
|
||||
template< typename Fn, typename Allocator >
|
||||
explicit packaged_task( std::allocator_arg_t, Allocator const& alloc, Fn && fn) {
|
||||
packaged_task( std::allocator_arg_t, Allocator const& alloc, Fn && fn) {
|
||||
typedef detail::task_object<
|
||||
Fn,
|
||||
Allocator,
|
||||
R
|
||||
Fn, Allocator, R, Args ...
|
||||
> object_t;
|
||||
typedef std::allocator_traits<
|
||||
typename object_t::allocator_t
|
||||
> traits_t;
|
||||
typename object_t::allocator_t a{ alloc };
|
||||
task_ = ptr_t{
|
||||
// placement new
|
||||
::new( a.allocate( 1) ) object_t{ a, std::forward< Fn >( fn) } };
|
||||
typename traits_t::pointer ptr{ traits_t::allocate( a, 1) };
|
||||
|
||||
try {
|
||||
traits_t::construct( a, ptr, a, std::forward< Fn >( fn) );
|
||||
} catch (...) {
|
||||
traits_t::deallocate( a, ptr, 1);
|
||||
throw;
|
||||
}
|
||||
task_.reset( convert( ptr) );
|
||||
}
|
||||
|
||||
packaged_task( packaged_task const&) = delete;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/fiber/detail/convert.hpp>
|
||||
#include <boost/fiber/exceptions.hpp>
|
||||
#include <boost/fiber/future/detail/shared_state.hpp>
|
||||
#include <boost/fiber/future/detail/shared_state_object.hpp>
|
||||
@@ -36,10 +37,17 @@ struct promise_base {
|
||||
template< typename Allocator >
|
||||
promise_base( std::allocator_arg_t, Allocator alloc) {
|
||||
typedef detail::shared_state_object< R, Allocator > object_t;
|
||||
typedef std::allocator_traits< typename object_t::allocator_t > traits_t;
|
||||
typename object_t::allocator_t a{ alloc };
|
||||
future_ = ptr_t{
|
||||
// placement new
|
||||
::new( a.allocate( 1) ) object_t{ a } };
|
||||
typename traits_t::pointer ptr{ traits_t::allocate( a, 1) };
|
||||
|
||||
try {
|
||||
traits_t::construct( a, ptr, a);
|
||||
} catch (...) {
|
||||
traits_t::deallocate( a, ptr, 1);
|
||||
throw;
|
||||
}
|
||||
future_.reset( convert( ptr) );
|
||||
}
|
||||
|
||||
~promise_base() {
|
||||
|
||||
@@ -8,18 +8,19 @@
|
||||
#ifndef BOOST_FIBERS_UNBOUNDED_CHANNEL_H
|
||||
#define BOOST_FIBERS_UNBOUNDED_CHANNEL_H
|
||||
|
||||
#include <algorithm> // std::move()
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <memory> // std::allocator
|
||||
#include <mutex> // std::unique_lock
|
||||
#include <utility> // std::forward()
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
|
||||
#include <boost/fiber/channel_op_status.hpp>
|
||||
#include <boost/fiber/condition.hpp>
|
||||
#include <boost/fiber/detail/convert.hpp>
|
||||
#include <boost/fiber/exceptions.hpp>
|
||||
#include <boost/fiber/mutex.hpp>
|
||||
#include <boost/fiber/operations.hpp>
|
||||
@@ -38,22 +39,25 @@ public:
|
||||
|
||||
private:
|
||||
struct node {
|
||||
typedef intrusive_ptr< node > ptr;
|
||||
typedef typename std::allocator_traits< Allocator >::template rebind_alloc< node > allocator_type;
|
||||
typedef intrusive_ptr< node > ptr_t;
|
||||
typedef typename std::allocator_traits< Allocator >::template rebind_alloc<
|
||||
node
|
||||
> allocator_t;
|
||||
typedef std::allocator_traits< allocator_t > allocator_traits_t;
|
||||
|
||||
std::size_t use_count{ 0 };
|
||||
allocator_type & alloc;
|
||||
T va;
|
||||
ptr nxt{};
|
||||
std::size_t use_count{ 0 };
|
||||
allocator_t alloc;
|
||||
T va;
|
||||
ptr_t nxt{};
|
||||
|
||||
node( T const& t, allocator_type & alloc_) noexcept :
|
||||
node( T const& t, allocator_t const& alloc_) noexcept :
|
||||
alloc{ alloc_ },
|
||||
va{ t } {
|
||||
}
|
||||
|
||||
node( T && t, allocator_type & alloc_) noexcept :
|
||||
node( T && t, allocator_t const& alloc_) noexcept :
|
||||
alloc{ alloc_ },
|
||||
va{ std::forward< T >( t) } {
|
||||
va{ std::move( t) } {
|
||||
}
|
||||
|
||||
friend
|
||||
@@ -64,26 +68,28 @@ private:
|
||||
friend
|
||||
void intrusive_ptr_release( node * p) noexcept {
|
||||
if ( 0 == --p->use_count) {
|
||||
allocator_type & alloc( p->alloc);
|
||||
std::allocator_traits< allocator_type >::destroy( alloc, p);
|
||||
std::allocator_traits< allocator_type >::deallocate( alloc, p, 1);
|
||||
allocator_t alloc( p->alloc);
|
||||
allocator_traits_t::destroy( alloc, p);
|
||||
allocator_traits_t::deallocate( alloc, p, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef typename std::allocator_traits< Allocator >::template rebind_alloc< node > allocator_type;
|
||||
using ptr_t = typename node::ptr_t;
|
||||
using allocator_t = typename node::allocator_t;
|
||||
using allocator_traits_t = typename node::allocator_traits_t;
|
||||
|
||||
enum class queue_status {
|
||||
open = 0,
|
||||
closed
|
||||
};
|
||||
|
||||
allocator_type alloc_;
|
||||
queue_status state_{ queue_status::open };
|
||||
typename node::ptr head_{};
|
||||
typename node::ptr * tail_;
|
||||
mutable mutex mtx_{};
|
||||
condition not_empty_cond_{};
|
||||
allocator_t alloc_;
|
||||
queue_status state_{ queue_status::open };
|
||||
ptr_t head_{};
|
||||
ptr_t * tail_;
|
||||
mutable mutex mtx_{};
|
||||
condition not_empty_cond_{};
|
||||
|
||||
bool is_closed_() const noexcept {
|
||||
return queue_status::closed == state_;
|
||||
@@ -99,7 +105,7 @@ private:
|
||||
return ! head_;
|
||||
}
|
||||
|
||||
channel_op_status push_( typename node::ptr const& new_node,
|
||||
channel_op_status push_( ptr_t new_node,
|
||||
std::unique_lock< mutex > & lk) noexcept {
|
||||
if ( is_closed_() ) {
|
||||
return channel_op_status::closed;
|
||||
@@ -107,7 +113,7 @@ private:
|
||||
return push_and_notify_( new_node, lk);
|
||||
}
|
||||
|
||||
channel_op_status push_and_notify_( typename node::ptr const& new_node,
|
||||
channel_op_status push_and_notify_( ptr_t new_node,
|
||||
std::unique_lock< mutex > & lk) noexcept {
|
||||
push_tail_( new_node);
|
||||
lk.unlock();
|
||||
@@ -115,7 +121,7 @@ private:
|
||||
return channel_op_status::success;
|
||||
}
|
||||
|
||||
void push_tail_( typename node::ptr new_node) noexcept {
|
||||
void push_tail_( ptr_t new_node) noexcept {
|
||||
* tail_ = new_node;
|
||||
tail_ = & new_node->nxt;
|
||||
}
|
||||
@@ -126,7 +132,7 @@ private:
|
||||
return std::move( old_head->va);
|
||||
}
|
||||
|
||||
typename node::ptr pop_head_() noexcept {
|
||||
ptr_t pop_head_() noexcept {
|
||||
auto old_head = head_;
|
||||
head_ = old_head->nxt;
|
||||
if ( ! head_) {
|
||||
@@ -150,18 +156,31 @@ public:
|
||||
close_( lk);
|
||||
}
|
||||
|
||||
channel_op_status push( value_type const& va) noexcept {
|
||||
typename node::ptr new_node(
|
||||
new ( alloc_.allocate( 1) ) node( va, alloc_) );
|
||||
channel_op_status push( value_type const& va) {
|
||||
typename allocator_traits_t::pointer ptr{
|
||||
allocator_traits_t::allocate( alloc_, 1) };
|
||||
try {
|
||||
allocator_traits_t::construct( alloc_, ptr, va, alloc_);
|
||||
} catch (...) {
|
||||
allocator_traits_t::deallocate( alloc_, ptr, 1);
|
||||
throw;
|
||||
}
|
||||
std::unique_lock< mutex > lk( mtx_);
|
||||
return push_( new_node, lk);
|
||||
return push_( { detail::convert( ptr) }, lk);
|
||||
}
|
||||
|
||||
channel_op_status push( value_type && va) noexcept {
|
||||
typename node::ptr new_node(
|
||||
new ( alloc_.allocate( 1) ) node( std::forward< value_type >( va), alloc_) );
|
||||
channel_op_status push( value_type && va) {
|
||||
typename allocator_traits_t::pointer ptr{
|
||||
allocator_traits_t::allocate( alloc_, 1) };
|
||||
try {
|
||||
allocator_traits_t::construct(
|
||||
alloc_, ptr, std::move( va), alloc_);
|
||||
} catch (...) {
|
||||
allocator_traits_t::deallocate( alloc_, ptr, 1);
|
||||
throw;
|
||||
}
|
||||
std::unique_lock< mutex > lk( mtx_);
|
||||
return push_( new_node, lk);
|
||||
return push_( { detail::convert( ptr) }, lk);
|
||||
}
|
||||
|
||||
channel_op_status pop( value_type & va) {
|
||||
|
||||
@@ -27,6 +27,22 @@ project boost/fiber/test
|
||||
<threading>multi
|
||||
;
|
||||
|
||||
run test_future.cpp :
|
||||
: :
|
||||
[ requires cxx11_constexpr
|
||||
cxx11_decltype
|
||||
cxx11_deleted_functions
|
||||
cxx11_explicit_conversion_operators
|
||||
cxx11_hdr_tuple
|
||||
cxx11_lambdas
|
||||
cxx11_noexcept
|
||||
cxx11_nullptr
|
||||
cxx11_template_aliases
|
||||
cxx11_rvalue_references
|
||||
cxx11_variadic_macros
|
||||
cxx11_variadic_templates
|
||||
cxx14_initialized_lambda_captures ] ;
|
||||
|
||||
run test_fiber.cpp :
|
||||
: :
|
||||
[ requires cxx11_constexpr
|
||||
@@ -139,22 +155,6 @@ run test_fss.cpp :
|
||||
cxx11_variadic_templates
|
||||
cxx14_initialized_lambda_captures ] ;
|
||||
|
||||
run test_future.cpp :
|
||||
: :
|
||||
[ requires cxx11_constexpr
|
||||
cxx11_decltype
|
||||
cxx11_deleted_functions
|
||||
cxx11_explicit_conversion_operators
|
||||
cxx11_hdr_tuple
|
||||
cxx11_lambdas
|
||||
cxx11_noexcept
|
||||
cxx11_nullptr
|
||||
cxx11_template_aliases
|
||||
cxx11_rvalue_references
|
||||
cxx11_variadic_macros
|
||||
cxx11_variadic_templates
|
||||
cxx14_initialized_lambda_captures ] ;
|
||||
|
||||
run test_mutex_mt.cpp :
|
||||
: :
|
||||
[ requires cxx11_constexpr
|
||||
|
||||
Reference in New Issue
Block a user