2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-19 02:12:24 +00:00
This commit is contained in:
Mario Lang
2013-12-29 14:02:47 +01:00
13 changed files with 181 additions and 253 deletions

View File

@@ -80,6 +80,7 @@ public:
// lock spinlock
unique_lock< detail::spinlock > lk( splk_);
BOOST_ASSERT( waiting_.end() == std::find( waiting_.begin(), waiting_.end(), n) );
// store this fiber in waiting-queue
// in order notify (resume) this fiber later
waiting_.push_back( n);
@@ -104,6 +105,7 @@ public:
// lock spinlock
unique_lock< detail::spinlock > lk( splk_);
BOOST_ASSERT( waiting_.end() == std::find( waiting_.begin(), waiting_.end(), n) );
// store this main-notifier in waiting-queue
// in order to be notified later
waiting_.push_back( n);

View File

@@ -1,90 +0,0 @@
// (C) Copyright 2008-9 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_FIBERS_DETAIL_FUTURE_TRAITS_H
#define BOOST_FIBERS_DETAIL_FUTURE_TRAITS_H
#include <algorithm>
#include <list>
#include <stdexcept>
#include <vector>
#include <boost/config.hpp>
#include <boost/move/move.hpp>
#include <boost/mpl/if.hpp>
#include <boost/next_prior.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_fundamental.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace fibers {
namespace detail {
template<typename T>
struct future_traits
{
typedef boost::scoped_ptr<T> storage_type;
#ifdef BOOST_HAS_RVALUE_REFS
typedef T const& source_reference_type;
struct dummy;
typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,T&&>::type rvalue_source_type;
typedef typename boost::mpl::if_<boost::is_fundamental<T>,T,T&&>::type move_dest_type;
#else
typedef T& source_reference_type;
typedef typename boost::mpl::if_<boost::is_convertible<T&, BOOST_RV_REF( T) >, BOOST_RV_REF( T),T const&>::type rvalue_source_type;
typedef typename boost::mpl::if_<boost::is_convertible<T&,BOOST_RV_REF( T) >,BOOST_RV_REF( T),T>::type move_dest_type;
#endif
static void init(storage_type& storage,source_reference_type t)
{ storage.reset(new T(t)); }
static void init(storage_type& storage,rvalue_source_type t)
{ storage.reset(new T(static_cast<rvalue_source_type>(t))); }
static void cleanup(storage_type& storage)
{ storage.reset(); }
};
template<typename T>
struct future_traits<T&>
{
typedef T* storage_type;
typedef T& source_reference_type;
struct rvalue_source_type {};
typedef T& move_dest_type;
static void init(storage_type& storage,T& t)
{ storage=&t; }
static void cleanup(storage_type& storage)
{ storage=0; }
};
template<>
struct future_traits<void>
{
typedef bool storage_type;
typedef void move_dest_type;
static void init(storage_type& storage)
{ storage=true; }
static void cleanup(storage_type& storage)
{ storage=false; }
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_DETAIL_FUTURE_TRAITS_H

View File

@@ -4,12 +4,13 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_FIBERS_DETAIL_FUTURE_BASE_H
#define BOOST_FIBERS_DETAIL_FUTURE_BASE_H
#ifndef BOOST_FIBERS_DETAIL_SHARED_STATE_H
#define BOOST_FIBERS_DETAIL_SHARED_STATE_H
#include <cstddef>
#include <boost/assert.hpp>
#include <boost/atomic.hpp>
#include <boost/config.hpp>
#include <boost/exception_ptr.hpp>
#include <boost/intrusive_ptr.hpp>
@@ -33,10 +34,10 @@ namespace fibers {
namespace detail {
template< typename R >
class future_base : public noncopyable
class shared_state : public noncopyable
{
private:
std::size_t use_count_;
atomic< std::size_t > use_count_;
mutable mutex mtx_;
mutable condition waiters_;
bool ready_;
@@ -154,14 +155,14 @@ protected:
virtual void deallocate_future() = 0;
public:
typedef intrusive_ptr< future_base > ptr_t;
typedef intrusive_ptr< shared_state > ptr_t;
future_base() :
shared_state() :
use_count_( 0), mtx_(), ready_( false),
value_(), except_()
{}
virtual ~future_base() {}
virtual ~shared_state() {}
void owner_destroyed()
{
@@ -261,10 +262,10 @@ public:
void reset()
{ ready_ = false; }
friend inline void intrusive_ptr_add_ref( future_base * p) BOOST_NOEXCEPT
friend inline void intrusive_ptr_add_ref( shared_state * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( future_base * p)
friend inline void intrusive_ptr_release( shared_state * p)
{
if ( 0 == --p->use_count_)
p->deallocate_future();
@@ -272,10 +273,10 @@ public:
};
template< typename R >
class future_base< R & > : public noncopyable
class shared_state< R & > : public noncopyable
{
private:
std::size_t use_count_;
atomic< std::size_t > use_count_;
mutable mutex mtx_;
mutable condition waiters_;
bool ready_;
@@ -369,14 +370,14 @@ protected:
virtual void deallocate_future() = 0;
public:
typedef intrusive_ptr< future_base > ptr_t;
typedef intrusive_ptr< shared_state > ptr_t;
future_base() :
shared_state() :
use_count_( 0), mtx_(), ready_( false),
value_( 0), except_()
{}
virtual ~future_base() {}
virtual ~shared_state() {}
void owner_destroyed()
{
@@ -452,10 +453,10 @@ public:
void reset()
{ ready_ = false; }
friend inline void intrusive_ptr_add_ref( future_base * p) BOOST_NOEXCEPT
friend inline void intrusive_ptr_add_ref( shared_state * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( future_base * p)
friend inline void intrusive_ptr_release( shared_state * p)
{
if ( 0 == --p->use_count_)
p->deallocate_future();
@@ -463,10 +464,10 @@ public:
};
template<>
class future_base< void > : public noncopyable
class shared_state< void > : public noncopyable
{
private:
std::size_t use_count_;
atomic< std::size_t > use_count_;
mutable mutex mtx_;
mutable condition waiters_;
bool ready_;
@@ -557,13 +558,13 @@ protected:
virtual void deallocate_future() = 0;
public:
typedef intrusive_ptr< future_base > ptr_t;
typedef intrusive_ptr< shared_state > ptr_t;
future_base() :
shared_state() :
use_count_( 0), mtx_(), ready_( false), except_()
{}
virtual ~future_base() {}
virtual ~shared_state() {}
void owner_destroyed()
{
@@ -639,10 +640,10 @@ public:
void reset()
{ ready_ = false; }
friend inline void intrusive_ptr_add_ref( future_base * p) BOOST_NOEXCEPT
friend inline void intrusive_ptr_add_ref( shared_state * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( future_base * p)
friend inline void intrusive_ptr_release( shared_state * p)
{
if ( 0 == --p->use_count_)
p->deallocate_future();
@@ -655,4 +656,4 @@ public:
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_DETAIL_FUTURE_BASE_H
#endif // BOOST_FIBERS_DETAIL_SHARED_STATE_H

View File

@@ -4,13 +4,13 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_FIBERS_DETAIL_FUTURE_OBJECT_H
#define BOOST_FIBERS_DETAIL_FUTURE_OBJECT_H
#ifndef BOOST_FIBERS_DETAIL_SHARED_STATE_OBJECT_H
#define BOOST_FIBERS_DETAIL_SHARED_STATE_OBJECT_H
#include <boost/config.hpp>
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/future/detail/future_base.hpp>
#include <boost/fiber/future/detail/shared_state.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
@@ -21,15 +21,15 @@ namespace fibers {
namespace detail {
template< typename R, typename Allocator >
class future_object : public future_base< R >
class shared_state_object : public shared_state< R >
{
public:
typedef typename Allocator::template rebind<
future_object< R, Allocator >
shared_state_object< R, Allocator >
>::other allocator_t;
future_object( allocator_t const& alloc) :
future_base< R >(), alloc_( alloc)
shared_state_object( allocator_t const& alloc) :
shared_state< R >(), alloc_( alloc)
{}
protected:
@@ -39,7 +39,7 @@ protected:
private:
allocator_t alloc_;
static void destroy_( allocator_t & alloc, future_object * p)
static void destroy_( allocator_t & alloc, shared_state_object * p)
{
alloc.destroy( p);
alloc.deallocate( p, 1);
@@ -52,4 +52,4 @@ private:
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_DETAIL_FUTURE_BASE_H
#endif // BOOST_FIBERS_DETAIL_SHARED_STATE_OBJECT_H

View File

@@ -15,7 +15,7 @@
#include <boost/utility.hpp>
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/future/detail/future_base.hpp>
#include <boost/fiber/future/detail/shared_state.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
@@ -26,7 +26,7 @@ namespace fibers {
namespace detail {
template< typename R >
struct task_base : public future_base< R >
struct task_base : public shared_state< R >
{
typedef intrusive_ptr< task_base > ptr_t;
@@ -41,4 +41,4 @@ struct task_base : public future_base< R >
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_DETAIL_future_base_H
#endif // BOOST_FIBERS_DETAIL_shared_state_H

View File

@@ -15,7 +15,7 @@
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/exceptions.hpp>
#include <boost/fiber/future/detail/future_base.hpp>
#include <boost/fiber/future/detail/shared_state.hpp>
#include <boost/fiber/future/future_status.hpp>
namespace boost {
@@ -34,7 +34,7 @@ template< typename R >
class future : private noncopyable
{
private:
typedef typename detail::future_base< R >::ptr_t ptr_t;
typedef typename detail::shared_state< R >::ptr_t ptr_t;
friend class packaged_task< R() >;
friend class promise< R >;
@@ -45,17 +45,17 @@ private:
typedef void ( dummy::*safe_bool)();
ptr_t future_;
ptr_t state_;
BOOST_MOVABLE_BUT_NOT_COPYABLE( future);
future( ptr_t const& p) :
future_( p)
state_( p)
{}
public:
future() BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a future with no shared state
// after construction, valid() == false
@@ -68,7 +68,7 @@ public:
#ifndef BOOST_NO_RVALUE_REFERENCES
future( future && other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a future with the shared state of other using move semantics
// after construction, other.valid() == false
@@ -86,7 +86,7 @@ public:
}
#else
future( BOOST_RV_REF( future< R >) other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a future with the shared state of other using move semantics
// after construction, other.valid() == false
@@ -107,7 +107,7 @@ public:
void swap( future & other) BOOST_NOEXCEPT
{
//TODO: exchange the shared states of two futures
future_.swap( other.future_);
state_.swap( other.state_);
}
operator safe_bool() const BOOST_NOEXCEPT
@@ -122,7 +122,7 @@ public:
// this is the case only for futures returned by
// promise::get_future(), packaged_task::get_future()
// or async() until the first time get()or share() is called
return 0 != future_.get();
return 0 != state_.get();
}
shared_future< R > share();
@@ -142,7 +142,7 @@ public:
boost::throw_exception(
future_uninitialized() );
ptr_t tmp;
tmp.swap( future_);
tmp.swap( state_);
return tmp->get();
}
@@ -153,7 +153,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
future_->wait();
state_->wait();
}
template< class Rep, class Period >
@@ -164,7 +164,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
return future_->wait_for( timeout_duration);
return state_->wait_for( timeout_duration);
}
future_status wait_until( clock_type::time_point const& timeout_time) const
@@ -174,7 +174,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
return future_->wait_until( timeout_time);
return state_->wait_until( timeout_time);
}
};
@@ -182,7 +182,7 @@ template< typename R >
class future< R & > : private noncopyable
{
private:
typedef typename detail::future_base< R & >::ptr_t ptr_t;
typedef typename detail::shared_state< R & >::ptr_t ptr_t;
friend class packaged_task< R&() >;
friend class promise< R & >;
@@ -193,17 +193,17 @@ private:
typedef void ( dummy::*safe_bool)();
ptr_t future_;
ptr_t state_;
BOOST_MOVABLE_BUT_NOT_COPYABLE( future);
future( ptr_t const& p) :
future_( p)
state_( p)
{}
public:
future() BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a future with no shared state
// after construction, valid() == false
@@ -216,7 +216,7 @@ public:
#ifndef BOOST_NO_RVALUE_REFERENCES
future( future && other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a future with the shared state of other using move semantics
// after construction, other.valid() == false
@@ -234,7 +234,7 @@ public:
}
#else
future( BOOST_RV_REF( future< R & >) other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a future with the shared state of other using move semantics
// after construction, other.valid() == false
@@ -255,7 +255,7 @@ public:
void swap( future & other) BOOST_NOEXCEPT
{
//TODO: exchange the shared states of two futures
future_.swap( other.future_);
state_.swap( other.state_);
}
operator safe_bool() const BOOST_NOEXCEPT
@@ -270,7 +270,7 @@ public:
// this is the case only for futures returned by
// promise::get_future(), packaged_task::get_future()
// or async() until the first time get()or share() is called
return 0 != future_.get();
return 0 != state_.get();
}
shared_future< R & > share();
@@ -290,7 +290,7 @@ public:
boost::throw_exception(
future_uninitialized() );
ptr_t tmp;
tmp.swap( future_);
tmp.swap( state_);
return tmp->get();
}
@@ -301,7 +301,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
future_->wait();
state_->wait();
}
template< class Rep, class Period >
@@ -312,7 +312,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
return future_->wait_for( timeout_duration);
return state_->wait_for( timeout_duration);
}
future_status wait_until( clock_type::time_point const& timeout_time) const
@@ -322,7 +322,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
return future_->wait_until( timeout_time);
return state_->wait_until( timeout_time);
}
};
@@ -330,7 +330,7 @@ template<>
class future< void > : private noncopyable
{
private:
typedef detail::future_base< void >::ptr_t ptr_t;
typedef detail::shared_state< void >::ptr_t ptr_t;
friend class packaged_task< void() >;
friend class promise< void >;
@@ -341,17 +341,17 @@ private:
typedef void ( dummy::*safe_bool)();
ptr_t future_;
ptr_t state_;
BOOST_MOVABLE_BUT_NOT_COPYABLE( future);
future( ptr_t const& p) :
future_( p)
state_( p)
{}
public:
future() BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a future with no shared state
// after construction, valid() == false
@@ -364,7 +364,7 @@ public:
#ifndef BOOST_NO_RVALUE_REFERENCES
future( future && other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a future with the shared state of other using move semantics
// after construction, other.valid() == false
@@ -382,7 +382,7 @@ public:
}
#else
future( BOOST_RV_REF( future< void >) other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a future with the shared state of other using move semantics
// after construction, other.valid() == false
@@ -403,7 +403,7 @@ public:
void swap( future & other) BOOST_NOEXCEPT
{
//TODO: exchange the shared states of two futures
future_.swap( other.future_);
state_.swap( other.state_);
}
operator safe_bool() const BOOST_NOEXCEPT
@@ -418,7 +418,7 @@ public:
// this is the case only for futures returned by
// promise::get_future(), packaged_task::get_future()
// or async() until the first time get()or share() is called
return 0 != future_.get();
return 0 != state_.get();
}
shared_future< void > share();
@@ -438,7 +438,7 @@ public:
boost::throw_exception(
future_uninitialized() );
ptr_t tmp;
tmp.swap( future_);
tmp.swap( state_);
tmp->get();
}
@@ -449,7 +449,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
future_->wait();
state_->wait();
}
template< class Rep, class Period >
@@ -460,7 +460,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
return future_->wait_for( timeout_duration);
return state_->wait_for( timeout_duration);
}
future_status wait_until( clock_type::time_point const& timeout_time) const
@@ -470,7 +470,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
return future_->wait_until( timeout_time);
return state_->wait_until( timeout_time);
}
};
@@ -484,7 +484,7 @@ template< typename R >
class shared_future
{
private:
typedef typename detail::future_base< R >::ptr_t ptr_t;
typedef typename detail::shared_state< R >::ptr_t ptr_t;
friend class future< R >;
@@ -493,15 +493,15 @@ private:
typedef void ( dummy::*safe_bool)();
ptr_t future_;
ptr_t state_;
explicit shared_future( ptr_t const& p) :
future_( p)
state_( p)
{}
public:
shared_future() BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a shared_future with no shared state
// after construction, valid() == false
@@ -514,7 +514,7 @@ public:
}
shared_future( shared_future const& other) :
future_( other.future_)
state_( other.state_)
{
//TODO: constructs a shared future that refers to the same shared state,
// as other, if there's any
@@ -522,15 +522,15 @@ public:
#ifndef BOOST_NO_RVALUE_REFERENCES
shared_future( future< R > && other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
future_.swap( other.future_);
state_.swap( other.state_);
}
shared_future( shared_future && other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
@@ -548,15 +548,15 @@ public:
}
#else
shared_future( BOOST_RV_REF( future< R >) other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
future_.swap( other.future_);
state_.swap( other.state_);
}
shared_future( BOOST_RV_REF( shared_future) other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
@@ -593,7 +593,7 @@ public:
void swap( shared_future & other) BOOST_NOEXCEPT
{
//TODO: exchange the shared states of two shared_futures
future_.swap( other.future_);
state_.swap( other.state_);
}
operator safe_bool() const BOOST_NOEXCEPT
@@ -608,7 +608,7 @@ public:
// this is the case only for shared_futures returned by
// promise::get_shared_future(), packaged_task::get_shared_future()
// or async() until the first time get()or share() is called
return 0 != future_.get();
return 0 != state_.get();
}
R get()
@@ -626,7 +626,7 @@ public:
boost::throw_exception(
future_uninitialized() );
ptr_t tmp;
tmp.swap( future_);
tmp.swap( state_);
return tmp->get();
}
@@ -637,7 +637,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
future_->wait();
state_->wait();
}
template< class Rep, class Period >
@@ -648,7 +648,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
return future_->wait_for( timeout_duration);
return state_->wait_for( timeout_duration);
}
future_status wait_until( clock_type::time_point const& timeout_time) const
@@ -658,7 +658,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
return future_->wait_until( timeout_time);
return state_->wait_until( timeout_time);
}
};
@@ -666,7 +666,7 @@ template< typename R >
class shared_future< R & >
{
private:
typedef typename detail::future_base< R & >::ptr_t ptr_t;
typedef typename detail::shared_state< R & >::ptr_t ptr_t;
friend class future< R & >;
@@ -675,15 +675,15 @@ private:
typedef void ( dummy::*safe_bool)();
ptr_t future_;
ptr_t state_;
explicit shared_future( ptr_t const& p) :
future_( p)
state_( p)
{}
public:
shared_future() BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a shared_future with no shared state
// after construction, valid() == false
@@ -696,7 +696,7 @@ public:
}
shared_future( shared_future const& other) :
future_( other.future_)
state_( other.state_)
{
//TODO: constructs a shared future that refers to the same shared state,
// as other, if there's any
@@ -704,15 +704,15 @@ public:
#ifndef BOOST_NO_RVALUE_REFERENCES
shared_future( future< R & > && other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
future_.swap( other.future_);
state_.swap( other.state_);
}
shared_future( shared_future && other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
@@ -730,15 +730,15 @@ public:
}
#else
shared_future( BOOST_RV_REF( future< R & >) other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
future_.swap( other.future_);
state_.swap( other.state_);
}
shared_future( BOOST_RV_REF( shared_future) other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
@@ -775,7 +775,7 @@ public:
void swap( shared_future & other) BOOST_NOEXCEPT
{
//TODO: exchange the shared states of two shared_futures
future_.swap( other.future_);
state_.swap( other.state_);
}
operator safe_bool() const BOOST_NOEXCEPT
@@ -790,7 +790,7 @@ public:
// this is the case only for shared_futures returned by
// promise::get_shared_future(), packaged_task::get_shared_future()
// or async() until the first time get()or share() is called
return 0 != future_.get();
return 0 != state_.get();
}
R & get()
@@ -808,7 +808,7 @@ public:
boost::throw_exception(
future_uninitialized() );
ptr_t tmp;
tmp.swap( future_);
tmp.swap( state_);
return tmp->get();
}
@@ -819,7 +819,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
future_->wait();
state_->wait();
}
template< class Rep, class Period >
@@ -830,7 +830,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
return future_->wait_for( timeout_duration);
return state_->wait_for( timeout_duration);
}
future_status wait_until( clock_type::time_point const& timeout_time) const
@@ -840,7 +840,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
return future_->wait_until( timeout_time);
return state_->wait_until( timeout_time);
}
};
@@ -848,7 +848,7 @@ template<>
class shared_future< void >
{
private:
typedef detail::future_base< void >::ptr_t ptr_t;
typedef detail::shared_state< void >::ptr_t ptr_t;
friend class future< void >;
@@ -857,15 +857,15 @@ private:
typedef void ( dummy::*safe_bool)();
ptr_t future_;
ptr_t state_;
shared_future( ptr_t const& p) :
future_( p)
state_( p)
{}
public:
shared_future() BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a shared_future with no shared state
// after construction, valid() == false
@@ -878,7 +878,7 @@ public:
}
shared_future( shared_future const& other) :
future_( other.future_)
state_( other.state_)
{
//TODO: constructs a shared future that refers to the same shared state,
// as other, if there's any
@@ -886,15 +886,15 @@ public:
#ifndef BOOST_NO_RVALUE_REFERENCES
shared_future( future< void > && other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
future_.swap( other.future_);
state_.swap( other.state_);
}
shared_future( shared_future && other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
@@ -912,15 +912,15 @@ public:
}
#else
shared_future( BOOST_RV_REF( future< void >) other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
future_.swap( other.future_);
state_.swap( other.state_);
}
shared_future( BOOST_RV_REF( shared_future) other) BOOST_NOEXCEPT :
future_()
state_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
@@ -957,13 +957,13 @@ public:
void swap( future< void > & other) BOOST_NOEXCEPT
{
//TODO: exchange the shared states of two shared_futures
future_.swap( other.future_);
state_.swap( other.state_);
}
void swap( shared_future & other) BOOST_NOEXCEPT
{
//TODO: exchange the shared states of two shared_futures
future_.swap( other.future_);
state_.swap( other.state_);
}
operator safe_bool() const BOOST_NOEXCEPT
@@ -978,7 +978,7 @@ public:
// this is the case only for shared_futures returned by
// promise::get_shared_future(), packaged_task::get_shared_future()
// or async() until the first time get()or share() is called
return 0 != future_.get();
return 0 != state_.get();
}
void get()
@@ -996,7 +996,7 @@ public:
boost::throw_exception(
future_uninitialized() );
ptr_t tmp;
tmp.swap( future_);
tmp.swap( state_);
tmp->get();
}
@@ -1007,7 +1007,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
future_->wait();
state_->wait();
}
template< class Rep, class Period >
@@ -1018,7 +1018,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
return future_->wait_for( timeout_duration);
return state_->wait_for( timeout_duration);
}
future_status wait_until( clock_type::time_point const& timeout_time) const
@@ -1028,7 +1028,7 @@ public:
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
return future_->wait_until( timeout_time);
return state_->wait_until( timeout_time);
}
};

View File

@@ -16,8 +16,8 @@
#include <boost/utility.hpp>
#include <boost/fiber/exceptions.hpp>
#include <boost/fiber/future/detail/future_base.hpp>
#include <boost/fiber/future/detail/future_object.hpp>
#include <boost/fiber/future/detail/shared_state.hpp>
#include <boost/fiber/future/detail/shared_state_object.hpp>
#include <boost/fiber/future/future.hpp>
namespace boost {
@@ -27,7 +27,7 @@ template< typename R >
class promise : private noncopyable
{
private:
typedef typename detail::future_base< R >::ptr_t ptr_t;
typedef typename detail::shared_state< R >::ptr_t ptr_t;
struct dummy
{ void nonnull() {} };
@@ -47,7 +47,7 @@ public:
// TODO: constructs the promise with an empty shared state
// the shared state is allocated using alloc
// alloc must meet the requirements of Allocator
typedef detail::future_object<
typedef detail::shared_state_object<
R, std::allocator< promise< R > >
> object_t;
std::allocator< promise< R > > alloc;
@@ -65,7 +65,7 @@ public:
// TODO: constructs the promise with an empty shared state
// the shared state is allocated using alloc
// alloc must meet the requirements of Allocator
typedef detail::future_object< R, Allocator > object_t;
typedef detail::shared_state_object< R, Allocator > object_t;
typename object_t::allocator_t a( alloc);
future_ = ptr_t(
// placement new
@@ -208,7 +208,7 @@ template< typename R >
class promise< R & > : private noncopyable
{
private:
typedef typename detail::future_base< R & >::ptr_t ptr_t;
typedef typename detail::shared_state< R & >::ptr_t ptr_t;
struct dummy
{ void nonnull() {} };
@@ -228,7 +228,7 @@ public:
// TODO: constructs the promise with an empty shared state
// the shared state is allocated using alloc
// alloc must meet the requirements of Allocator
typedef detail::future_object<
typedef detail::shared_state_object<
R &, std::allocator< promise< R & > >
> object_t;
std::allocator< promise< R > > alloc;
@@ -246,7 +246,7 @@ public:
// TODO: constructs the promise with an empty shared state
// the shared state is allocated using alloc
// alloc must meet the requirements of Allocator
typedef detail::future_object< R &, Allocator > object_t;
typedef detail::shared_state_object< R &, Allocator > object_t;
typename object_t::allocator_t a( alloc);
future_ = ptr_t(
// placement new
@@ -361,7 +361,7 @@ template<>
class promise< void > : private noncopyable
{
private:
typedef detail::future_base< void >::ptr_t ptr_t;
typedef detail::shared_state< void >::ptr_t ptr_t;
struct dummy
{ void nonnull() {} };
@@ -381,7 +381,7 @@ public:
// TODO: constructs the promise with an empty shared state
// the shared state is allocated using alloc
// alloc must meet the requirements of Allocator
typedef detail::future_object<
typedef detail::shared_state_object<
void, std::allocator< promise< void > >
> object_t;
std::allocator< promise< void > > alloc;
@@ -399,7 +399,7 @@ public:
// TODO: constructs the promise with an empty shared state
// the shared state is allocated using alloc
// alloc must meet the requirements of Allocator
typedef detail::future_object< void, Allocator > object_t;
typedef detail::shared_state_object< void, Allocator > object_t;
#if BOOST_MSVC
object_t::allocator_t a( alloc);
#else

View File

@@ -22,6 +22,7 @@ spinlock::spinlock() :
void
spinlock::lock()
{
bool is_fiber = 0 != scheduler::instance()->active().get();
for (;;)
{
// access to CPU's cache
@@ -30,7 +31,7 @@ spinlock::lock()
while ( LOCKED == state_)
{
// busy-wait
if ( scheduler::instance()->active() )
if ( is_fiber)
scheduler::instance()->yield();
else
this_thread::yield();

View File

@@ -53,6 +53,7 @@ mutex::lock()
}
// store this fiber in order to be notified later
BOOST_ASSERT( waiting_.end() == std::find( waiting_.begin(), waiting_.end(), n) );
waiting_.push_back( n);
// suspend this fiber
@@ -61,11 +62,11 @@ mutex::lock()
}
else
{
// local notification for main-fiber
n = detail::scheduler::instance()->get_main_notifier();
for (;;)
{
// local notification for main-fiber
n = detail::scheduler::instance()->get_main_notifier();
unique_lock< detail::spinlock > lk( splk_);
if ( UNLOCKED == state_)
@@ -77,6 +78,7 @@ mutex::lock()
}
// store this fiber in order to be notified later
BOOST_ASSERT( waiting_.end() == std::find( waiting_.begin(), waiting_.end(), n) );
waiting_.push_back( n);
lk.unlock();

View File

@@ -61,6 +61,7 @@ recursive_mutex::lock()
}
// store this fiber in order to be notified later
BOOST_ASSERT( waiting_.end() == std::find( waiting_.begin(), waiting_.end(), n) );
waiting_.push_back( n);
// suspend this fiber
@@ -69,11 +70,11 @@ recursive_mutex::lock()
}
else
{
// local notification for main-fiber
n = detail::scheduler::instance()->get_main_notifier();
for (;;)
{
// local notification for main-fiber
n = detail::scheduler::instance()->get_main_notifier();
unique_lock< detail::spinlock > lk( splk_);
if ( UNLOCKED == state_)
@@ -91,6 +92,7 @@ recursive_mutex::lock()
}
// store this fiber in order to be notified later
BOOST_ASSERT( waiting_.end() == std::find( waiting_.begin(), waiting_.end(), n) );
waiting_.push_back( n);
lk.unlock();

View File

@@ -61,6 +61,7 @@ recursive_timed_mutex::lock()
}
// store this fiber in order to be notified later
BOOST_ASSERT( waiting_.end() == std::find( waiting_.begin(), waiting_.end(), n) );
waiting_.push_back( n);
// suspend this fiber
@@ -69,11 +70,11 @@ recursive_timed_mutex::lock()
}
else
{
// local notification for main-fiber
n = detail::scheduler::instance()->get_main_notifier();
for (;;)
{
// local notification for main-fiber
n = detail::scheduler::instance()->get_main_notifier();
unique_lock< detail::spinlock > lk( splk_);
if ( UNLOCKED == state_)
@@ -91,6 +92,7 @@ recursive_timed_mutex::lock()
}
// store this fiber in order to be notified later
BOOST_ASSERT( waiting_.end() == std::find( waiting_.begin(), waiting_.end(), n) );
waiting_.push_back( n);
lk.unlock();
@@ -157,6 +159,7 @@ recursive_timed_mutex::try_lock_until( clock_type::time_point const& timeout_tim
}
// store this fiber in order to be notified later
BOOST_ASSERT( waiting_.end() == std::find( waiting_.begin(), waiting_.end(), n) );
waiting_.push_back( n);
// suspend this fiber until notified or timed-out
@@ -173,11 +176,11 @@ recursive_timed_mutex::try_lock_until( clock_type::time_point const& timeout_tim
}
else
{
// local notification for main-fiber
n = detail::scheduler::instance()->get_main_notifier();
for (;;)
{
// local notification for main-fiber
n = detail::scheduler::instance()->get_main_notifier();
unique_lock< detail::spinlock > lk( splk_);
if ( clock_type::now() > timeout_time)
@@ -198,6 +201,7 @@ recursive_timed_mutex::try_lock_until( clock_type::time_point const& timeout_tim
}
// store this fiber in order to be notified later
BOOST_ASSERT( waiting_.end() == std::find( waiting_.begin(), waiting_.end(), n) );
waiting_.push_back( n);
lk.unlock();

View File

@@ -53,6 +53,7 @@ timed_mutex::lock()
}
// store this fiber in order to be notified later
BOOST_ASSERT( waiting_.end() == std::find( waiting_.begin(), waiting_.end(), n) );
waiting_.push_back( n);
// suspend this fiber
@@ -61,11 +62,11 @@ timed_mutex::lock()
}
else
{
// local notification for main-fiber
n = detail::scheduler::instance()->get_main_notifier();
for (;;)
{
// local notification for main-fiber
n = detail::scheduler::instance()->get_main_notifier();
unique_lock< detail::spinlock > lk( splk_);
if ( UNLOCKED == state_)
@@ -77,6 +78,7 @@ timed_mutex::lock()
}
// store this fiber in order to be notified later
BOOST_ASSERT( waiting_.end() == std::find( waiting_.begin(), waiting_.end(), n) );
waiting_.push_back( n);
lk.unlock();
@@ -131,6 +133,7 @@ timed_mutex::try_lock_until( clock_type::time_point const& timeout_time)
}
// store this fiber in order to be notified later
BOOST_ASSERT( waiting_.end() == std::find( waiting_.begin(), waiting_.end(), n) );
waiting_.push_back( n);
// suspend this fiber until notified or timed-out
@@ -147,11 +150,11 @@ timed_mutex::try_lock_until( clock_type::time_point const& timeout_time)
}
else
{
// local notification for main-fiber
n = detail::scheduler::instance()->get_main_notifier();
for (;;)
{
// local notification for main-fiber
n = detail::scheduler::instance()->get_main_notifier();
unique_lock< detail::spinlock > lk( splk_);
if ( clock_type::now() > timeout_time)
@@ -166,6 +169,7 @@ timed_mutex::try_lock_until( clock_type::time_point const& timeout_time)
}
// store this fiber in order to be notified later
BOOST_ASSERT( waiting_.end() == std::find( waiting_.begin(), waiting_.end(), n) );
waiting_.push_back( n);
lk.unlock();

View File

@@ -16,22 +16,24 @@
#include <boost/test/unit_test.hpp>
#include <boost/thread.hpp>
boost::fibers::packaged_task< int() > pt;
int fn( int i)
{ return i; }
void exec( boost::shared_ptr< boost::fibers::packaged_task< int() > > pt)
void exec()
{
boost::fibers::fiber f( boost::move( * pt) );
f.join();
boost::fibers::round_robin rr;
boost::fibers::set_scheduling_algorithm( & rr);
boost::fibers::fiber( boost::move( pt) ).join();
}
boost::fibers::future< int > async( int i)
{
boost::shared_ptr< boost::fibers::packaged_task< int() > > pt(
new boost::fibers::packaged_task< int() >(
boost::bind( fn, i) ) );
boost::fibers::future< int > f( pt->get_future() );
boost::thread( boost::bind( exec, pt) ).detach();
boost::fibers::packaged_task< int() > tmp( boost::bind( fn, i) );
boost::fibers::future< int > f( tmp.get_future() );
pt = boost::move( tmp);
boost::thread( boost::bind( exec) ).detach();
return boost::move( f);
}