Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r58529 - in sandbox/fiber: . boost boost/fiber boost/fiber/spin libs/fiber/doc libs/fiber/examples libs/fiber/src libs/fiber/test
From: oliver.kowalke_at_[hidden]
Date: 2009-12-26 04:44:26


Author: olli
Date: 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
New Revision: 58529
URL: http://svn.boost.org/trac/boost/changeset/58529

Log:
- fifo in channel renamed

Added:
   sandbox/fiber/boost/fiber/bounded_channel.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/spin/bounded_channel.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/spin/unbounded_channel.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/unbounded_channel.hpp (contents, props changed)
Removed:
   sandbox/fiber/boost/fiber/bounded_fifo.hpp
   sandbox/fiber/boost/fiber/spin/bounded_fifo.hpp
   sandbox/fiber/boost/fiber/spin/unbounded_fifo.hpp
   sandbox/fiber/boost/fiber/unbounded_fifo.hpp
Text files modified:
   sandbox/fiber/boost/fiber.hpp | 8 ++++----
   sandbox/fiber/boost/fiber/spin/condition.hpp | 8 +++++++-
   sandbox/fiber/boost/fiber/strategy.hpp | 9 +++++++++
   sandbox/fiber/boost/fiber/utility.hpp | 9 +++++++++
   sandbox/fiber/change.log | 6 ++++++
   sandbox/fiber/libs/fiber/doc/fiber_ref.qbk | 15 +++++++++++++++
   sandbox/fiber/libs/fiber/doc/fifos.qbk | 32 ++++++++++++++++----------------
   sandbox/fiber/libs/fiber/doc/spin_fifos.qbk | 32 ++++++++++++++++----------------
   sandbox/fiber/libs/fiber/examples/ping_pong.cpp | 2 +-
   sandbox/fiber/libs/fiber/examples/ping_pong_mt.cpp | 2 +-
   sandbox/fiber/libs/fiber/src/strategy.cpp | 18 ++++++++++++++++++
   sandbox/fiber/libs/fiber/test/test_auto_reset_event.cpp | 1 -
   sandbox/fiber/libs/fiber/test/test_condition.cpp | 1 -
   sandbox/fiber/libs/fiber/test/test_manual_reset_event.cpp | 1 -
   sandbox/fiber/libs/fiber/test/test_mutex.cpp | 1 -
   sandbox/fiber/libs/fiber/test/test_utility.cpp | 23 +++++++++++++++++++++++
   16 files changed, 125 insertions(+), 43 deletions(-)

Modified: sandbox/fiber/boost/fiber.hpp
==============================================================================
--- sandbox/fiber/boost/fiber.hpp (original)
+++ sandbox/fiber/boost/fiber.hpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -9,7 +9,7 @@
 
 #include <boost/fiber/auto_reset_event.hpp>
 #include <boost/fiber/barrier.hpp>
-#include <boost/fiber/bounded_fifo.hpp>
+#include <boost/fiber/bounded_channel.hpp>
 #include <boost/fiber/condition.hpp>
 #include <boost/fiber/count_down_event.hpp>
 #include <boost/fiber/exceptions.hpp>
@@ -20,14 +20,14 @@
 #include <boost/fiber/scheduler.hpp>
 #include <boost/fiber/spin/auto_reset_event.hpp>
 #include <boost/fiber/spin/barrier.hpp>
-#include <boost/fiber/spin/bounded_fifo.hpp>
+#include <boost/fiber/spin/bounded_channel.hpp>
 #include <boost/fiber/spin/condition.hpp>
 #include <boost/fiber/spin/count_down_event.hpp>
 #include <boost/fiber/spin/future.hpp>
 #include <boost/fiber/spin/manual_reset_event.hpp>
 #include <boost/fiber/spin/mutex.hpp>
-#include <boost/fiber/spin/unbounded_fifo.hpp>
-#include <boost/fiber/unbounded_fifo.hpp>
+#include <boost/fiber/spin/unbounded_channel.hpp>
+#include <boost/fiber/unbounded_channel.hpp>
 #include <boost/fiber/utility.hpp>
 
 #endif // BOOST_FIBER_H

Added: sandbox/fiber/boost/fiber/bounded_channel.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/bounded_channel.hpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -0,0 +1,309 @@
+
+// Copyright Oliver Kowalke 2009.
+// 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_BOUNDED_CHANNEL_H
+#define BOOST_FIBERS_BOUNDED_CHANNEL_H
+
+#include <cstddef>
+#include <stdexcept>
+
+#include <boost/intrusive_ptr.hpp>
+#include <boost/optional.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber/condition.hpp>
+#include <boost/fiber/exceptions.hpp>
+#include <boost/fiber/mutex.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fibers {
+
+template< typename T >
+class bounded_channel
+{
+public:
+ typedef optional< T > value_type;
+
+private:
+ class impl : private noncopyable
+ {
+ private:
+ struct node
+ {
+ typedef intrusive_ptr< node > ptr;
+
+ std::size_t use_count;
+ value_type va;
+ ptr next;
+
+ node() :
+ use_count( 0),
+ va(),
+ next()
+ {}
+
+ inline friend void intrusive_ptr_add_ref( node * p)
+ { ++p->use_count; }
+
+ inline friend void intrusive_ptr_release( node * p)
+ { if ( --p->use_count == 0) delete p; }
+ };
+
+ enum state
+ {
+ ACTIVE = 0,
+ DEACTIVE
+ };
+
+ state state_;
+ std::size_t count_;
+ typename node::ptr head_;
+ mutable mutex head_mtx_;
+ typename node::ptr tail_;
+ mutable mutex tail_mtx_;
+ condition not_empty_cond_;
+ condition not_full_cond_;
+ std::size_t hwm_;
+ std::size_t lwm_;
+ std::size_t use_count_;
+
+ bool active_() const
+ { return ACTIVE == state_; }
+
+ void deactivate_()
+ { state_ = DEACTIVE; }
+
+ std::size_t size_() const
+ { return count_; }
+
+ bool empty_() const
+ { return head_ == get_tail_(); }
+
+ bool full_() const
+ { return size_() >= hwm_; }
+
+ typename node::ptr get_tail_() const
+ {
+ mutex::scoped_lock lk( tail_mtx_);
+ typename node::ptr tmp = tail_;
+ return tmp;
+ }
+
+ typename node::ptr pop_head_()
+ {
+ typename node::ptr old_head = head_;
+ head_ = old_head->next;
+ --count_;
+ return old_head;
+ }
+
+ public:
+ template< typename Strategy >
+ impl(
+ scheduler< Strategy > & sched,
+ std::size_t hwm,
+ std::size_t lwm) :
+ state_( ACTIVE),
+ count_( 0),
+ head_( new node() ),
+ head_mtx_( sched),
+ tail_( head_),
+ tail_mtx_( sched),
+ not_empty_cond_( sched),
+ not_full_cond_( sched),
+ hwm_( hwm),
+ lwm_( lwm),
+ use_count_( 0)
+ {
+ if ( hwm_ < lwm_)
+ throw invalid_watermark();
+ }
+
+ template< typename Strategy >
+ impl(
+ scheduler< Strategy > & sched,
+ std::size_t wm) :
+ state_( ACTIVE),
+ count_( 0),
+ head_( new node() ),
+ head_mtx_( sched),
+ tail_( head_),
+ tail_mtx_( sched),
+ not_empty_cond_( sched),
+ not_full_cond_( sched),
+ hwm_( wm),
+ lwm_( wm),
+ use_count_( 0)
+ {}
+
+ void upper_bound( std::size_t hwm)
+ {
+ if ( hwm < lwm_)
+ throw invalid_watermark();
+ unsigned int tmp( hwm_);
+ hwm_ = hwm;
+ if ( hwm_ > tmp) not_full_cond_.notify_one();
+ }
+
+ std::size_t upper_bound() const
+ { return hwm_; }
+
+ void lower_bound( std::size_t lwm)
+ {
+ if ( lwm > hwm_ )
+ throw invalid_watermark();
+ unsigned int tmp( lwm_);
+ lwm_ = lwm;
+ if ( lwm_ > tmp) not_full_cond_.notify_one();
+ }
+
+ std::size_t lower_bound() const
+ { return lwm_; }
+
+ void deactivate()
+ { deactivate_(); }
+
+ bool empty() const
+ {
+ mutex::scoped_lock lk( head_mtx_);
+ return empty_();
+ }
+
+ void put( T const& t)
+ {
+ typename node::ptr new_node( new node() );
+ {
+ mutex::scoped_lock lk( tail_mtx_);
+
+ if ( full_() )
+ {
+ while ( active_() && full_() )
+ not_full_cond_.wait( lk);
+ }
+
+ if ( ! active_() )
+ throw std::runtime_error("queue is not active");
+
+ tail_->va = t;
+ tail_->next = new_node;
+ tail_ = new_node;
+ ++count_;
+ }
+ not_empty_cond_.notify_one();
+ }
+
+ bool take( value_type & va)
+ {
+ mutex::scoped_lock lk( head_mtx_);
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ while ( active_() && empty_() )
+ not_empty_cond_.wait( lk);
+ }
+ catch ( fiber_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ swap( va, head_->va);
+ pop_head_();
+ if ( size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // for submiting an action object
+ not_full_cond_.notify_all();
+ }
+ return va;
+ }
+
+ bool try_take( value_type & va)
+ {
+ mutex::scoped_lock lk( head_mtx_);
+ if ( empty_() )
+ return false;
+ swap( va, head_->va);
+ pop_head_();
+ bool valid = va;
+ if ( valid && size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // in order to submit an task
+ not_full_cond_.notify_all();
+ }
+ return valid;
+ }
+
+ friend void intrusive_ptr_add_ref( impl * p)
+ { ++( p->use_count_s); }
+
+ friend void intrusive_ptr_release( impl * p)
+ { if ( --( & p->use_count_) == 1) delete p; }
+ };
+
+ intrusive_ptr< impl > impl_;
+
+public:
+ template< typename Strategy >
+ bounded_channel(
+ scheduler< Strategy > & sched,
+ unsigned int hwm,
+ unsigned int lwm) :
+ impl_( new impl( sched, hwm, lwm) )
+ {}
+
+ template< typename Strategy >
+ bounded_channel(
+ scheduler< Strategy > & sched,
+ unsigned int wm) :
+ impl_( new impl( sched, wm) )
+ {}
+
+ void upper_bound( std::size_t hwm)
+ { impl_->upper_bound( hwm); }
+
+ std::size_t upper_bound() const
+ { return impl_->upper_bound(); }
+
+ void lower_bound( std::size_t lwm)
+ { impl_->lower_bound( lwm); }
+
+ std::size_t lower_bound() const
+ { return impl_->lower_bound(); }
+
+ void deactivate()
+ { impl_->deactivate(); }
+
+ bool empty() const
+ { return impl_->empty(); }
+
+ void put( T const& t)
+ { impl_->put( t); }
+
+ bool take( value_type & va)
+ { return impl_->take( va);}
+
+ bool try_take( value_type & va)
+ { return impl_->try_take( va); }
+};
+
+}}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBERS_BOUNDED_CHANNEL_H

Deleted: sandbox/fiber/boost/fiber/bounded_fifo.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/bounded_fifo.hpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
+++ (empty file)
@@ -1,308 +0,0 @@
-
-// Copyright Oliver Kowalke 2009.
-// 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_BOUNDED_FIFO_H
-#define BOOST_FIBERS_BOUNDED_FIFO_H
-
-#include <cstddef>
-#include <stdexcept>
-
-#include <boost/intrusive_ptr.hpp>
-#include <boost/optional.hpp>
-#include <boost/utility.hpp>
-
-#include <boost/fiber/condition.hpp>
-#include <boost/fiber/exceptions.hpp>
-#include <boost/fiber/mutex.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-namespace boost {
-namespace fibers {
-
-template< typename T >
-class bounded_fifo
-{
-public:
- typedef optional< T > value_type;
-
-private:
- class impl : private noncopyable
- {
- private:
- struct node
- {
- typedef intrusive_ptr< node > ptr;
-
- std::size_t use_count;
- value_type va;
- ptr next;
-
- node() :
- use_count( 0),
- va(),
- next()
- {}
-
- inline friend void intrusive_ptr_add_ref( node * p)
- { ++p->use_count; }
-
- inline friend void intrusive_ptr_release( node * p)
- { if ( --p->use_count == 0) delete p; }
- };
-
- enum state
- {
- ACTIVE = 0,
- DEACTIVE
- };
-
- state state_;
- std::size_t count_;
- typename node::ptr head_;
- mutable mutex head_mtx_;
- typename node::ptr tail_;
- mutable mutex tail_mtx_;
- condition not_empty_cond_;
- condition not_full_cond_;
- std::size_t hwm_;
- std::size_t lwm_;
- std::size_t use_count_;
-
- bool active_() const
- { return ACTIVE == state_; }
-
- void deactivate_()
- { state_ = DEACTIVE; }
-
- std::size_t size_() const
- { return count_; }
-
- bool empty_() const
- { return head_ == get_tail_(); }
-
- bool full_() const
- { return size_() >= hwm_; }
-
- typename node::ptr get_tail_() const
- {
- mutex::scoped_lock lk( tail_mtx_);
- typename node::ptr tmp = tail_;
- return tmp;
- }
-
- typename node::ptr pop_head_()
- {
- typename node::ptr old_head = head_;
- head_ = old_head->next;
- --count_;
- return old_head;
- }
-
- public:
- template< typename Strategy >
- impl(
- scheduler< Strategy > & sched,
- std::size_t hwm,
- std::size_t lwm) :
- state_( ACTIVE),
- count_( 0),
- head_( new node() ),
- head_mtx_( sched),
- tail_( head_),
- tail_mtx_( sched),
- not_empty_cond_( sched),
- not_full_cond_( sched),
- hwm_( hwm),
- lwm_( lwm),
- use_count_( 0)
- {
- if ( hwm_ < lwm_)
- throw invalid_watermark();
- }
-
- template< typename Strategy >
- impl(
- scheduler< Strategy > & sched,
- std::size_t wm) :
- state_( ACTIVE),
- count_( 0),
- head_( new node() ),
- head_mtx_( sched),
- tail_( head_),
- tail_mtx_( sched),
- not_empty_cond_( sched),
- not_full_cond_( sched),
- hwm_( wm),
- lwm_( wm),
- use_count_( 0)
- {}
-
- void upper_bound( std::size_t hwm)
- {
- if ( hwm < lwm_)
- throw invalid_watermark();
- unsigned int tmp( hwm_);
- hwm_ = hwm;
- if ( hwm_ > tmp) not_full_cond_.notify_one();
- }
-
- std::size_t upper_bound() const
- { return hwm_; }
-
- void lower_bound( std::size_t lwm)
- {
- if ( lwm > hwm_ )
- throw invalid_watermark();
- unsigned int tmp( lwm_);
- lwm_ = lwm;
- if ( lwm_ > tmp) not_full_cond_.notify_one();
- }
-
- std::size_t lower_bound() const
- { return lwm_; }
-
- void deactivate()
- { deactivate_(); }
-
- bool empty() const
- {
- mutex::scoped_lock lk( head_mtx_);
- return empty_();
- }
-
- void put( T const& t)
- {
- typename node::ptr new_node( new node() );
- {
- mutex::scoped_lock lk( tail_mtx_);
-
- if ( full_() )
- {
- while ( active_() && full_() )
- not_full_cond_.wait( lk);
- }
- if ( ! active_() )
- throw std::runtime_error("queue is not active");
-
- tail_->va = t;
- tail_->next = new_node;
- tail_ = new_node;
- ++count_;
- }
- not_empty_cond_.notify_one();
- }
-
- bool take( value_type & va)
- {
- mutex::scoped_lock lk( head_mtx_);
- bool empty = empty_();
- if ( ! active_() && empty)
- return false;
- if ( empty)
- {
- try
- {
- while ( active_() && empty_() )
- not_empty_cond_.wait( lk);
- }
- catch ( fiber_interrupted const&)
- { return false; }
- }
- if ( ! active_() && empty_() )
- return false;
- swap( va, head_->va);
- pop_head_();
- if ( size_() <= lwm_)
- {
- if ( lwm_ == hwm_)
- not_full_cond_.notify_one();
- else
- // more than one producer could be waiting
- // for submiting an action object
- not_full_cond_.notify_all();
- }
- return va;
- }
-
- bool try_take( value_type & va)
- {
- mutex::scoped_lock lk( head_mtx_);
- if ( empty_() )
- return false;
- swap( va, head_->va);
- pop_head_();
- bool valid = va;
- if ( valid && size_() <= lwm_)
- {
- if ( lwm_ == hwm_)
- not_full_cond_.notify_one();
- else
- // more than one producer could be waiting
- // in order to submit an task
- not_full_cond_.notify_all();
- }
- return valid;
- }
-
- friend void intrusive_ptr_add_ref( impl * p)
- { ++( p->use_count_s); }
-
- friend void intrusive_ptr_release( impl * p)
- { if ( --( & p->use_count_) == 1) delete p; }
- };
-
- intrusive_ptr< impl > impl_;
-
-public:
- template< typename Strategy >
- bounded_fifo(
- scheduler< Strategy > & sched,
- unsigned int hwm,
- unsigned int lwm) :
- impl_( new impl( sched, hwm, lwm) )
- {}
-
- template< typename Strategy >
- bounded_fifo(
- scheduler< Strategy > & sched,
- unsigned int wm) :
- impl_( new impl( sched, wm) )
- {}
-
- void upper_bound( std::size_t hwm)
- { impl_->upper_bound( hwm); }
-
- std::size_t upper_bound() const
- { return impl_->upper_bound(); }
-
- void lower_bound( std::size_t lwm)
- { impl_->lower_bound( lwm); }
-
- std::size_t lower_bound() const
- { return impl_->lower_bound(); }
-
- void deactivate()
- { impl_->deactivate(); }
-
- bool empty() const
- { return impl_->empty(); }
-
- void put( T const& t)
- { impl_->put( t); }
-
- bool take( value_type & va)
- { return impl_->take( va);}
-
- bool try_take( value_type & va)
- { return impl_->try_take( va); }
-};
-
-}}
-
-#include <boost/config/abi_suffix.hpp>
-
-#endif // BOOST_FIBERS_BOUNDED_FIFO_H

Added: sandbox/fiber/boost/fiber/spin/bounded_channel.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/spin/bounded_channel.hpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -0,0 +1,313 @@
+
+// Copyright Oliver Kowalke 2009.
+// 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_SPIN_BOUNDED_CHANNEL_H
+#define BOOST_FIBERS_SPIN_BOUNDED_CHANNEL_H
+
+#include <cstddef>
+#include <stdexcept>
+
+#include <boost/atomic.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/optional.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber/exceptions.hpp>
+#include <boost/fiber/spin/condition.hpp>
+#include <boost/fiber/spin/mutex.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fibers {
+namespace spin {
+
+template< typename T >
+class bounded_channel
+{
+public:
+ typedef optional< T > value_type;
+
+private:
+ class impl : private noncopyable
+ {
+ private:
+ struct node
+ {
+ typedef intrusive_ptr< node > ptr;
+
+ atomic< std::size_t > use_count;
+ value_type va;
+ ptr next;
+
+ node() :
+ use_count( 0),
+ va(),
+ next()
+ {}
+
+ inline friend void intrusive_ptr_add_ref( node * p)
+ { p->use_count.fetch_add( 1, memory_order_relaxed); }
+
+ inline friend void intrusive_ptr_release( node * p)
+ {
+ if ( p->use_count.fetch_sub( 1, memory_order_release) == 1)
+ {
+ atomic_thread_fence( memory_order_acquire);
+ delete p;
+ }
+ }
+ };
+
+ enum state
+ {
+ ACTIVE = 0,
+ DEACTIVE
+ };
+
+ atomic< state > state_;
+ atomic< std::size_t > count_;
+ typename node::ptr head_;
+ mutable mutex head_mtx_;
+ typename node::ptr tail_;
+ mutable mutex tail_mtx_;
+ condition not_empty_cond_;
+ condition not_full_cond_;
+ unsigned int hwm_;
+ unsigned int lwm_;
+ atomic< std::size_t > use_count_;
+
+ bool active_() const
+ { return ACTIVE == state_.load(); }
+
+ void deactivate_()
+ { state_.store( DEACTIVE); }
+
+ std::size_t size_() const
+ { return count_.load(); }
+
+ bool empty_() const
+ { return head_ == get_tail_(); }
+
+ bool full_() const
+ { return size_() >= hwm_; }
+
+ typename node::ptr get_tail_() const
+ {
+ mutex::scoped_lock lk( tail_mtx_);
+ typename node::ptr tmp = tail_;
+ return tmp;
+ }
+
+ typename node::ptr pop_head_()
+ {
+ typename node::ptr old_head = head_;
+ head_ = old_head->next;
+ count_.fetch_sub( 1);
+ return old_head;
+ }
+
+ public:
+ impl(
+ std::size_t hwm,
+ std::size_t lwm) :
+ state_( ACTIVE),
+ count_( 0),
+ head_( new node() ),
+ head_mtx_(),
+ tail_( head_),
+ tail_mtx_(),
+ not_empty_cond_(),
+ not_full_cond_(),
+ hwm_( hwm),
+ lwm_( lwm),
+ use_count_( 0)
+ {
+ if ( hwm_ < lwm_)
+ throw invalid_watermark();
+ }
+
+ impl( std::size_t wm) :
+ state_( ACTIVE),
+ count_( 0),
+ head_( new node() ),
+ head_mtx_(),
+ tail_( head_),
+ tail_mtx_(),
+ not_empty_cond_(),
+ not_full_cond_(),
+ hwm_( wm),
+ lwm_( wm),
+ use_count_( 0)
+ {}
+
+ void upper_bound_( std::size_t hwm)
+ {
+ if ( hwm < lwm_)
+ throw invalid_watermark();
+ unsigned int tmp( hwm_);
+ hwm_ = hwm;
+ if ( hwm_ > tmp) not_full_cond_.notify_one();
+ }
+
+ std::size_t upper_bound() const
+ { return hwm_; }
+
+ void lower_bound_( std::size_t lwm)
+ {
+ if ( lwm > hwm_ )
+ throw invalid_watermark();
+ unsigned int tmp( lwm_);
+ lwm_ = lwm;
+ if ( lwm_ > tmp) not_full_cond_.notify_one();
+ }
+
+ std::size_t lower_bound() const
+ { return lwm_; }
+
+ void deactivate()
+ { deactivate_(); }
+
+ bool empty() const
+ {
+ mutex::scoped_lock lk( head_mtx_);
+ return empty_();
+ }
+
+ void put( T const& t)
+ {
+ typename node::ptr new_node( new node() );
+ {
+ mutex::scoped_lock lk( tail_mtx_);
+
+ if ( full_() )
+ {
+ while ( active_() && full_() )
+ not_full_cond_.wait( lk);
+ }
+
+ if ( ! active_() )
+ throw std::runtime_error("queue is not active");
+
+ tail_->va = t;
+ tail_->next = new_node;
+ tail_ = new_node;
+ count_.fetch_add( 1);
+ }
+ not_empty_cond_.notify_one();
+ }
+
+ bool take( value_type & va)
+ {
+ mutex::scoped_lock lk( head_mtx_);
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ while ( active_() && empty_() )
+ not_empty_cond_.wait( lk);
+ }
+ catch ( fiber_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ swap( va, head_->va);
+ pop_head_();
+ if ( size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // for submiting an action object
+ not_full_cond_.notify_all();
+ }
+ return va;
+ }
+
+ bool try_take( value_type & va)
+ {
+ mutex::scoped_lock lk( head_mtx_);
+ if ( empty_() )
+ return false;
+ swap( va, head_->va);
+ pop_head_();
+ bool valid = va;
+ if ( valid && size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // in order to submit an task
+ not_full_cond_.notify_all();
+ }
+ return valid;
+ }
+
+ inline friend void intrusive_ptr_add_ref( impl * p)
+ { p->use_count_.fetch_add( 1, memory_order_relaxed); }
+
+ inline friend void intrusive_ptr_release( impl * p)
+ {
+ if ( p->use_count_.fetch_sub( 1, memory_order_release) == 1)
+ {
+ atomic_thread_fence( memory_order_acquire);
+ delete p;
+ }
+ }
+ };
+
+ intrusive_ptr< impl > impl_;
+
+public:
+ bounded_channel(
+ std::size_t hwm,
+ std::size_t lwm) :
+ impl_( new impl( hwm, lwm) )
+ {}
+
+ bounded_channel( std::size_t wm) :
+ impl_( new impl( wm) )
+ {}
+
+ void upper_bound( std::size_t hwm)
+ { impl_->upper_bound( hwm); }
+
+ std::size_t upper_bound() const
+ { return impl_->upper_bound(); }
+
+ void lower_bound( std::size_t lwm)
+ { impl_->lower_bound( lwm); }
+
+ std::size_t lower_bound() const
+ { return impl_->lower_bound(); }
+
+ void deactivate()
+ { impl_->deactivate(); }
+
+ bool empty() const
+ { return impl_->empty(); }
+
+ void put( T const& t)
+ { impl_->put( t); }
+
+ bool take( value_type & va)
+ { return impl_->take( va);}
+
+ bool try_take( value_type & va)
+ { return impl_->try_take( va); }
+};
+
+}}}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBERS_SPIN_BOUNDED_CHANNEL_H

Deleted: sandbox/fiber/boost/fiber/spin/bounded_fifo.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/spin/bounded_fifo.hpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
+++ (empty file)
@@ -1,312 +0,0 @@
-
-// Copyright Oliver Kowalke 2009.
-// 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_SPIN_BOUNDED_FIFO_H
-#define BOOST_FIBERS_SPIN_BOUNDED_FIFO_H
-
-#include <cstddef>
-#include <stdexcept>
-
-#include <boost/atomic.hpp>
-#include <boost/intrusive_ptr.hpp>
-#include <boost/optional.hpp>
-#include <boost/utility.hpp>
-
-#include <boost/fiber/exceptions.hpp>
-#include <boost/fiber/spin/condition.hpp>
-#include <boost/fiber/spin/mutex.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-namespace boost {
-namespace fibers {
-namespace spin {
-
-template< typename T >
-class bounded_fifo
-{
-public:
- typedef optional< T > value_type;
-
-private:
- class impl : private noncopyable
- {
- private:
- struct node
- {
- typedef intrusive_ptr< node > ptr;
-
- atomic< std::size_t > use_count;
- value_type va;
- ptr next;
-
- node() :
- use_count( 0),
- va(),
- next()
- {}
-
- inline friend void intrusive_ptr_add_ref( node * p)
- { p->use_count.fetch_add( 1, memory_order_relaxed); }
-
- inline friend void intrusive_ptr_release( node * p)
- {
- if ( p->use_count.fetch_sub( 1, memory_order_release) == 1)
- {
- atomic_thread_fence( memory_order_acquire);
- delete p;
- }
- }
- };
-
- enum state
- {
- ACTIVE = 0,
- DEACTIVE
- };
-
- atomic< state > state_;
- atomic< std::size_t > count_;
- typename node::ptr head_;
- mutable mutex head_mtx_;
- typename node::ptr tail_;
- mutable mutex tail_mtx_;
- condition not_empty_cond_;
- condition not_full_cond_;
- unsigned int hwm_;
- unsigned int lwm_;
- atomic< std::size_t > use_count_;
-
- bool active_() const
- { return ACTIVE == state_.load(); }
-
- void deactivate_()
- { state_.store( DEACTIVE); }
-
- std::size_t size_() const
- { return count_.load(); }
-
- bool empty_() const
- { return head_ == get_tail_(); }
-
- bool full_() const
- { return size_() >= hwm_; }
-
- typename node::ptr get_tail_() const
- {
- mutex::scoped_lock lk( tail_mtx_);
- typename node::ptr tmp = tail_;
- return tmp;
- }
-
- typename node::ptr pop_head_()
- {
- typename node::ptr old_head = head_;
- head_ = old_head->next;
- count_.fetch_sub( 1);
- return old_head;
- }
-
- public:
- impl(
- std::size_t hwm,
- std::size_t lwm) :
- state_( ACTIVE),
- count_( 0),
- head_( new node() ),
- head_mtx_(),
- tail_( head_),
- tail_mtx_(),
- not_empty_cond_(),
- not_full_cond_(),
- hwm_( hwm),
- lwm_( lwm),
- use_count_( 0)
- {
- if ( hwm_ < lwm_)
- throw invalid_watermark();
- }
-
- impl( std::size_t wm) :
- state_( ACTIVE),
- count_( 0),
- head_( new node() ),
- head_mtx_(),
- tail_( head_),
- tail_mtx_(),
- not_empty_cond_(),
- not_full_cond_(),
- hwm_( wm),
- lwm_( wm),
- use_count_( 0)
- {}
-
- void upper_bound_( std::size_t hwm)
- {
- if ( hwm < lwm_)
- throw invalid_watermark();
- unsigned int tmp( hwm_);
- hwm_ = hwm;
- if ( hwm_ > tmp) not_full_cond_.notify_one();
- }
-
- std::size_t upper_bound() const
- { return hwm_; }
-
- void lower_bound_( std::size_t lwm)
- {
- if ( lwm > hwm_ )
- throw invalid_watermark();
- unsigned int tmp( lwm_);
- lwm_ = lwm;
- if ( lwm_ > tmp) not_full_cond_.notify_one();
- }
-
- std::size_t lower_bound() const
- { return lwm_; }
-
- void deactivate()
- { deactivate_(); }
-
- bool empty() const
- {
- mutex::scoped_lock lk( head_mtx_);
- return empty_();
- }
-
- void put( T const& t)
- {
- typename node::ptr new_node( new node() );
- {
- mutex::scoped_lock lk( tail_mtx_);
-
- if ( full_() )
- {
- while ( active_() && full_() )
- not_full_cond_.wait( lk);
- }
- if ( ! active_() )
- throw std::runtime_error("queue is not active");
-
- tail_->va = t;
- tail_->next = new_node;
- tail_ = new_node;
- count_.fetch_add( 1);
- }
- not_empty_cond_.notify_one();
- }
-
- bool take( value_type & va)
- {
- mutex::scoped_lock lk( head_mtx_);
- bool empty = empty_();
- if ( ! active_() && empty)
- return false;
- if ( empty)
- {
- try
- {
- while ( active_() && empty_() )
- not_empty_cond_.wait( lk);
- }
- catch ( fiber_interrupted const&)
- { return false; }
- }
- if ( ! active_() && empty_() )
- return false;
- swap( va, head_->va);
- pop_head_();
- if ( size_() <= lwm_)
- {
- if ( lwm_ == hwm_)
- not_full_cond_.notify_one();
- else
- // more than one producer could be waiting
- // for submiting an action object
- not_full_cond_.notify_all();
- }
- return va;
- }
-
- bool try_take( value_type & va)
- {
- mutex::scoped_lock lk( head_mtx_);
- if ( empty_() )
- return false;
- swap( va, head_->va);
- pop_head_();
- bool valid = va;
- if ( valid && size_() <= lwm_)
- {
- if ( lwm_ == hwm_)
- not_full_cond_.notify_one();
- else
- // more than one producer could be waiting
- // in order to submit an task
- not_full_cond_.notify_all();
- }
- return valid;
- }
-
- inline friend void intrusive_ptr_add_ref( impl * p)
- { p->use_count_.fetch_add( 1, memory_order_relaxed); }
-
- inline friend void intrusive_ptr_release( impl * p)
- {
- if ( p->use_count_.fetch_sub( 1, memory_order_release) == 1)
- {
- atomic_thread_fence( memory_order_acquire);
- delete p;
- }
- }
- };
-
- intrusive_ptr< impl > impl_;
-
-public:
- bounded_fifo(
- std::size_t hwm,
- std::size_t lwm) :
- impl_( new impl( hwm, lwm) )
- {}
-
- bounded_fifo( std::size_t wm) :
- impl_( new impl( wm) )
- {}
-
- void upper_bound( std::size_t hwm)
- { impl_->upper_bound( hwm); }
-
- std::size_t upper_bound() const
- { return impl_->upper_bound(); }
-
- void lower_bound( std::size_t lwm)
- { impl_->lower_bound( lwm); }
-
- std::size_t lower_bound() const
- { return impl_->lower_bound(); }
-
- void deactivate()
- { impl_->deactivate(); }
-
- bool empty() const
- { return impl_->empty(); }
-
- void put( T const& t)
- { impl_->put( t); }
-
- bool take( value_type & va)
- { return impl_->take( va);}
-
- bool try_take( value_type & va)
- { return impl_->try_take( va); }
-};
-
-}}}
-
-#include <boost/config/abi_suffix.hpp>
-
-#endif // BOOST_FIBERS_SPIN_BOUNDED_FIFO_H

Modified: sandbox/fiber/boost/fiber/spin/condition.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/spin/condition.hpp (original)
+++ sandbox/fiber/boost/fiber/spin/condition.hpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -14,6 +14,7 @@
 #include <boost/assert.hpp>
 #include <boost/atomic.hpp>
 #include <boost/thread/locks.hpp>
+#include <boost/thread/thread.hpp>
 #include <boost/utility.hpp>
 
 #include <boost/fiber/exceptions.hpp>
@@ -79,7 +80,12 @@
                 for (;;)
                 {
                         while ( SLEEPING == cmd_.load() )
- this_fiber::yield();
+ {
+ if ( this_fiber::runs_as_fiber() )
+ this_fiber::yield();
+ else
+ this_thread::yield();
+ }
 
                         mutex::scoped_lock lk( check_mtx_);
                         BOOST_ASSERT( lk);

Added: sandbox/fiber/boost/fiber/spin/unbounded_channel.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/spin/unbounded_channel.hpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -0,0 +1,212 @@
+
+// Copyright Oliver Kowalke 2009.
+// 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_SPIN_UNBOUNDED_CHANNEL_H
+#define BOOST_FIBERS_SPIN_UNBOUNDED_CHANNEL_H
+
+#include <cstddef>
+#include <stdexcept>
+
+#include <boost/atomic.hpp>
+#include <boost/config.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/optional.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber/exceptions.hpp>
+#include <boost/fiber/spin/condition.hpp>
+#include <boost/fiber/spin/mutex.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fibers {
+namespace spin {
+
+template< typename T >
+class unbounded_channel
+{
+public:
+ typedef optional< T > value_type;
+
+private:
+ class impl : private noncopyable
+ {
+ private:
+ struct node
+ {
+ typedef intrusive_ptr< node > ptr;
+
+ atomic< std::size_t > use_count;
+ value_type va;
+ ptr next;
+
+ node() :
+ use_count( 0),
+ va(),
+ next()
+ {}
+
+ inline friend void intrusive_ptr_add_ref( node * p)
+ { p->use_count.fetch_add( 1, memory_order_relaxed); }
+
+ inline friend void intrusive_ptr_release( node * p)
+ {
+ if ( p->use_count.fetch_sub( 1, memory_order_release) == 1)
+ {
+ atomic_thread_fence( memory_order_acquire);
+ delete p;
+ }
+ }
+ };
+
+ enum state
+ {
+ ACTIVE = 0,
+ DEACTIVE
+ };
+
+ atomic< state > state_;
+ typename node::ptr head_;
+ mutable mutex head_mtx_;
+ typename node::ptr tail_;
+ mutable mutex tail_mtx_;
+ condition not_empty_cond_;
+ atomic< std::size_t > use_count_;
+
+ bool active_() const
+ { return ACTIVE == state_.load(); }
+
+ void deactivate_()
+ { state_.store( DEACTIVE); }
+
+ bool empty_() const
+ { return head_ == get_tail_(); }
+
+ typename node::ptr get_tail_() const
+ {
+ mutex::scoped_lock lk( tail_mtx_);
+ typename node::ptr tmp = tail_;
+ return tmp;
+ }
+
+ typename node::ptr pop_head_()
+ {
+ typename node::ptr old_head = head_;
+ head_ = old_head->next;
+ return old_head;
+ }
+
+ public:
+ impl() :
+ state_( ACTIVE),
+ head_( new node() ),
+ head_mtx_(),
+ tail_( head_),
+ tail_mtx_(),
+ not_empty_cond_(),
+ use_count_( 0)
+ {}
+
+ void deactivate()
+ { deactivate_(); }
+
+ bool empty() const
+ {
+ mutex::scoped_lock lk( head_mtx_);
+ return empty_();
+ }
+
+ void put( T const& t)
+ {
+ typename node::ptr new_node( new node() );
+ {
+ mutex::scoped_lock lk( tail_mtx_);
+
+ if ( ! active_() )
+ throw std::runtime_error("queue is not active");
+
+ tail_->va = t;
+ tail_->next = new_node;
+ tail_ = new_node;
+ }
+ not_empty_cond_.notify_one();
+ }
+
+ bool take( value_type & va)
+ {
+ mutex::scoped_lock lk( head_mtx_);
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ while ( active_() && empty_() )
+ not_empty_cond_.wait( lk);
+ }
+ catch ( fiber_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ swap( va, head_->va);
+ pop_head_();
+ return va;
+ }
+
+ bool try_take( value_type & va)
+ {
+ mutex::scoped_lock lk( head_mtx_);
+ if ( empty_() )
+ return false;
+ swap( va, head_->va);
+ pop_head_();
+ return va;
+ }
+
+ inline friend void intrusive_ptr_add_ref( impl * p)
+ { p->use_count_.fetch_add( 1, memory_order_relaxed); }
+
+ inline friend void intrusive_ptr_release( impl * p)
+ {
+ if ( p->use_count_.fetch_sub( 1, memory_order_release) == 1)
+ {
+ atomic_thread_fence( memory_order_acquire);
+ delete p;
+ }
+ }
+ };
+
+ intrusive_ptr< impl > impl_;
+
+public:
+ unbounded_channel() :
+ impl_( new impl() )
+ {}
+
+ void deactivate()
+ { impl_->deactivate(); }
+
+ bool empty()
+ { return impl_->empty(); }
+
+ void put( T const& t)
+ { impl_->put( t); }
+
+ bool take( value_type & va)
+ { return impl_->take( va); }
+
+ bool try_take( value_type & va)
+ { return impl_->try_take( va); }
+};
+
+}}}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBERS_SPIN_UNBOUNDED_CHANNEL_H

Deleted: sandbox/fiber/boost/fiber/spin/unbounded_fifo.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/spin/unbounded_fifo.hpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
+++ (empty file)
@@ -1,209 +0,0 @@
-
-// Copyright Oliver Kowalke 2009.
-// 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_SPIN_UNBOUNDED_FIFO_H
-#define BOOST_FIBERS_SPIN_UNBOUNDED_FIFO_H
-
-#include <cstddef>
-
-#include <boost/atomic.hpp>
-#include <boost/config.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-#include <boost/intrusive_ptr.hpp>
-#include <boost/optional.hpp>
-#include <boost/utility.hpp>
-
-#include <boost/fiber/exceptions.hpp>
-#include <boost/fiber/spin/condition.hpp>
-#include <boost/fiber/spin/mutex.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-namespace boost {
-namespace fibers {
-namespace spin {
-
-template< typename T >
-class unbounded_fifo
-{
-public:
- typedef optional< T > value_type;
-
-private:
- class impl : private noncopyable
- {
- private:
- struct node
- {
- typedef intrusive_ptr< node > ptr;
-
- atomic< std::size_t > use_count;
- value_type va;
- ptr next;
-
- node() :
- use_count( 0),
- va(),
- next()
- {}
-
- inline friend void intrusive_ptr_add_ref( node * p)
- { p->use_count.fetch_add( 1, memory_order_relaxed); }
-
- inline friend void intrusive_ptr_release( node * p)
- {
- if ( p->use_count.fetch_sub( 1, memory_order_release) == 1)
- {
- atomic_thread_fence( memory_order_acquire);
- delete p;
- }
- }
- };
-
- enum state
- {
- ACTIVE = 0,
- DEACTIVE
- };
-
- atomic< state > state_;
- typename node::ptr head_;
- mutable mutex head_mtx_;
- typename node::ptr tail_;
- mutable mutex tail_mtx_;
- condition not_empty_cond_;
- atomic< std::size_t > use_count_;
-
- bool active_() const
- { return ACTIVE == state_.load(); }
-
- void deactivate_()
- { state_.store( DEACTIVE); }
-
- bool empty_() const
- { return head_ == get_tail_(); }
-
- typename node::ptr get_tail_() const
- {
- mutex::scoped_lock lk( tail_mtx_);
- typename node::ptr tmp = tail_;
- return tmp;
- }
-
- typename node::ptr pop_head_()
- {
- typename node::ptr old_head = head_;
- head_ = old_head->next;
- return old_head;
- }
-
- public:
- impl() :
- state_( ACTIVE),
- head_( new node() ),
- head_mtx_(),
- tail_( head_),
- tail_mtx_(),
- not_empty_cond_(),
- use_count_( 0)
- {}
-
- void deactivate()
- { deactivate_(); }
-
- bool empty() const
- {
- mutex::scoped_lock lk( head_mtx_);
- return empty_();
- }
-
- void put( T const& t)
- {
- typename node::ptr new_node( new node() );
- {
- mutex::scoped_lock lk( tail_mtx_);
-
- tail_->va = t;
- tail_->next = new_node;
- tail_ = new_node;
- }
- not_empty_cond_.notify_one();
- }
-
- bool take( value_type & va)
- {
- mutex::scoped_lock lk( head_mtx_);
- bool empty = empty_();
- if ( ! active_() && empty)
- return false;
- if ( empty)
- {
- try
- {
- while ( active_() && empty_() )
- not_empty_cond_.wait( lk);
- }
- catch ( fiber_interrupted const&)
- { return false; }
- }
- if ( ! active_() && empty_() )
- return false;
- swap( va, head_->va);
- pop_head_();
- return va;
- }
-
- bool try_take( value_type & va)
- {
- mutex::scoped_lock lk( head_mtx_);
- if ( empty_() )
- return false;
- swap( va, head_->va);
- pop_head_();
- return va;
- }
-
- inline friend void intrusive_ptr_add_ref( impl * p)
- { p->use_count_.fetch_add( 1, memory_order_relaxed); }
-
- inline friend void intrusive_ptr_release( impl * p)
- {
- if ( p->use_count_.fetch_sub( 1, memory_order_release) == 1)
- {
- atomic_thread_fence( memory_order_acquire);
- delete p;
- }
- }
- };
-
- intrusive_ptr< impl > impl_;
-
-public:
- unbounded_fifo() :
- impl_( new impl() )
- {}
-
- void deactivate()
- { impl_->deactivate(); }
-
- bool empty()
- { return impl_->empty(); }
-
- void put( T const& t)
- { impl_->put( t); }
-
- bool take( value_type & va)
- { return impl_->take( va); }
-
- bool try_take( value_type & va)
- { return impl_->try_take( va); }
-};
-
-}}}
-
-#include <boost/config/abi_suffix.hpp>
-
-#endif // BOOST_FIBERS_SPIN_UNBOUNDED_FIFO_H

Modified: sandbox/fiber/boost/fiber/strategy.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/strategy.hpp (original)
+++ sandbox/fiber/boost/fiber/strategy.hpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -12,6 +12,7 @@
 #include <boost/atomic.hpp>
 #include <boost/function.hpp>
 #include <boost/intrusive_ptr.hpp>
+#include <boost/move/move.hpp>
 #include <boost/thread/tss.hpp>
 
 #include <boost/fiber/detail/interrupt_flags.hpp>
@@ -42,6 +43,8 @@
 void at_fiber_exit( Callable);
 void at_fiber_exit( function< void() >);
 void at_fiber_exit( void (*)() );
+void submit_fiber( fiber);
+void submit_fiber( BOOST_RV_REF( fiber) );
 
 class disable_interruption;
 class restore_interruption;
@@ -72,6 +75,8 @@
         friend void this_fiber::at_fiber_exit( Callable);
         friend void this_fiber::at_fiber_exit( function< void() >);
         friend void this_fiber::at_fiber_exit( void (*)() );
+ friend void this_fiber::submit_fiber( fiber);
+ friend void this_fiber::submit_fiber( BOOST_RV_REF( fiber) );
         friend class this_fiber::disable_interruption;
         friend class this_fiber::restore_interruption;
         friend class auto_reset_event;
@@ -104,6 +109,10 @@
 
         static void cancel_();
 
+ static void submit_fiber_( fiber);
+
+ static void submit_fiber_( BOOST_RV_REF( fiber) );
+
         atomic< std::size_t > use_count_;
 
 protected:

Added: sandbox/fiber/boost/fiber/unbounded_channel.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/unbounded_channel.hpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -0,0 +1,201 @@
+
+// Copyright Oliver Kowalke 2009.
+// 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_UNBOUNDED_CHANNEL_H
+#define BOOST_FIBERS_UNBOUNDED_CHANNEL_H
+
+#include <cstddef>
+#include <stdexcept>
+
+#include <boost/config.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/optional.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber/condition.hpp>
+#include <boost/fiber/exceptions.hpp>
+#include <boost/fiber/mutex.hpp>
+#include <boost/fiber/scheduler.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fibers {
+
+template< typename T >
+class unbounded_channel
+{
+public:
+ typedef optional< T > value_type;
+
+private:
+ class impl : private noncopyable
+ {
+ private:
+ struct node
+ {
+ typedef intrusive_ptr< node > ptr;
+
+ std::size_t use_count;
+ value_type va;
+ ptr next;
+
+ node() :
+ use_count( 0),
+ va(),
+ next()
+ {}
+
+ inline friend void intrusive_ptr_add_ref( node * p)
+ { ++p->use_count; }
+
+ inline friend void intrusive_ptr_release( node * p)
+ { if ( --p->use_count == 0) delete p; }
+ };
+
+ enum state
+ {
+ ACTIVE = 0,
+ DEACTIVE
+ };
+
+ state state_;
+ typename node::ptr head_;
+ mutable mutex head_mtx_;
+ typename node::ptr tail_;
+ mutable mutex tail_mtx_;
+ condition not_empty_cond_;
+ std::size_t use_count_;
+
+ bool active_() const
+ { return ACTIVE == state_; }
+
+ void deactivate_()
+ { state_ = DEACTIVE; }
+
+ bool empty_() const
+ { return head_ == get_tail_(); }
+
+ typename node::ptr get_tail_() const
+ {
+ mutex::scoped_lock lk( tail_mtx_);
+ typename node::ptr tmp = tail_;
+ return tmp;
+ }
+
+ typename node::ptr pop_head_()
+ {
+ typename node::ptr old_head = head_;
+ head_ = old_head->next;
+ return old_head;
+ }
+
+ public:
+ template< typename Strategy >
+ impl( scheduler< Strategy > & sched) :
+ state_( ACTIVE),
+ head_( new node() ),
+ head_mtx_( sched),
+ tail_( head_),
+ tail_mtx_( sched),
+ not_empty_cond_( sched),
+ use_count_( 0)
+ {}
+
+ void deactivate()
+ { deactivate_(); }
+
+ bool empty() const
+ {
+ mutex::scoped_lock lk( head_mtx_);
+ return empty_();
+ }
+
+ void put( T const& t)
+ {
+ typename node::ptr new_node( new node() );
+ {
+ mutex::scoped_lock lk( tail_mtx_);
+
+ if ( ! active_() )
+ throw std::runtime_error("channel is not active");
+
+ tail_->va = t;
+ tail_->next = new_node;
+ tail_ = new_node;
+ }
+ not_empty_cond_.notify_one();
+ }
+
+ bool take( value_type & va)
+ {
+ mutex::scoped_lock lk( head_mtx_);
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ while ( active_() && empty_() )
+ not_empty_cond_.wait( lk);
+ }
+ catch ( fiber_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ swap( va, head_->va);
+ pop_head_();
+ return va;
+ }
+
+ bool try_take( value_type & va)
+ {
+ mutex::scoped_lock lk( head_mtx_);
+ if ( empty_() )
+ return false;
+ swap( va, head_->va);
+ pop_head_();
+ return va;
+ }
+
+ friend void intrusive_ptr_add_ref( impl * p)
+ { ++( p->use_count_); }
+
+ friend void intrusive_ptr_release( impl * p)
+ { if ( --( p->use_count_) == 1) delete p; }
+ };
+
+ intrusive_ptr< impl > impl_;
+
+public:
+ template< typename Strategy >
+ unbounded_channel( scheduler< Strategy > & sched) :
+ impl_( new impl( sched) )
+ {}
+
+ void deactivate()
+ { impl_->deactivate(); }
+
+ bool empty() const
+ { return impl_->empty(); }
+
+ void put( T const& t)
+ { impl_->put( t); }
+
+ bool take( value_type & va)
+ { return impl_->take( va); }
+
+ bool try_take( value_type & va)
+ { return impl_->try_take( va); }
+};
+
+}}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBERS_UNBOUNDED_CHANNEL_H

Deleted: sandbox/fiber/boost/fiber/unbounded_fifo.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/unbounded_fifo.hpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
+++ (empty file)
@@ -1,197 +0,0 @@
-
-// Copyright Oliver Kowalke 2009.
-// 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_UNBOUNDED_FIFO_H
-#define BOOST_FIBERS_UNBOUNDED_FIFO_H
-
-#include <cstddef>
-
-#include <boost/config.hpp>
-#include <boost/intrusive_ptr.hpp>
-#include <boost/optional.hpp>
-#include <boost/utility.hpp>
-
-#include <boost/fiber/condition.hpp>
-#include <boost/fiber/exceptions.hpp>
-#include <boost/fiber/mutex.hpp>
-#include <boost/fiber/scheduler.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-namespace boost {
-namespace fibers {
-
-template< typename T >
-class unbounded_fifo
-{
-public:
- typedef optional< T > value_type;
-
-private:
- class impl : private noncopyable
- {
- private:
- struct node
- {
- typedef intrusive_ptr< node > ptr;
-
- std::size_t use_count;
- value_type va;
- ptr next;
-
- node() :
- use_count( 0),
- va(),
- next()
- {}
-
- inline friend void intrusive_ptr_add_ref( node * p)
- { ++p->use_count; }
-
- inline friend void intrusive_ptr_release( node * p)
- { if ( --p->use_count == 0) delete p; }
- };
-
- enum state
- {
- ACTIVE = 0,
- DEACTIVE
- };
-
- state state_;
- typename node::ptr head_;
- mutable mutex head_mtx_;
- typename node::ptr tail_;
- mutable mutex tail_mtx_;
- condition not_empty_cond_;
- std::size_t use_count_;
-
- bool active_() const
- { return ACTIVE == state_; }
-
- void deactivate_()
- { state_ = DEACTIVE; }
-
- bool empty_() const
- { return head_ == get_tail_(); }
-
- typename node::ptr get_tail_() const
- {
- mutex::scoped_lock lk( tail_mtx_);
- typename node::ptr tmp = tail_;
- return tmp;
- }
-
- typename node::ptr pop_head_()
- {
- typename node::ptr old_head = head_;
- head_ = old_head->next;
- return old_head;
- }
-
- public:
- template< typename Strategy >
- impl( scheduler< Strategy > & sched) :
- state_( ACTIVE),
- head_( new node() ),
- head_mtx_( sched),
- tail_( head_),
- tail_mtx_( sched),
- not_empty_cond_( sched),
- use_count_( 0)
- {}
-
- void deactivate()
- { deactivate_(); }
-
- bool empty() const
- {
- mutex::scoped_lock lk( head_mtx_);
- return empty_();
- }
-
- void put( T const& t)
- {
- typename node::ptr new_node( new node() );
- {
- mutex::scoped_lock lk( tail_mtx_);
-
- tail_->va = t;
- tail_->next = new_node;
- tail_ = new_node;
- }
- not_empty_cond_.notify_one();
- }
-
- bool take( value_type & va)
- {
- mutex::scoped_lock lk( head_mtx_);
- bool empty = empty_();
- if ( ! active_() && empty)
- return false;
- if ( empty)
- {
- try
- {
- while ( active_() && empty_() )
- not_empty_cond_.wait( lk);
- }
- catch ( fiber_interrupted const&)
- { return false; }
- }
- if ( ! active_() && empty_() )
- return false;
- swap( va, head_->va);
- pop_head_();
- return va;
- }
-
- bool try_take( value_type & va)
- {
- mutex::scoped_lock lk( head_mtx_);
- if ( empty_() )
- return false;
- swap( va, head_->va);
- pop_head_();
- return va;
- }
-
- friend void intrusive_ptr_add_ref( impl * p)
- { ++( p->use_count_); }
-
- friend void intrusive_ptr_release( impl * p)
- { if ( --( p->use_count_) == 1) delete p; }
- };
-
- intrusive_ptr< impl > impl_;
-
-public:
- template< typename Strategy >
- unbounded_fifo( scheduler< Strategy > & sched) :
- impl_( new impl( sched) )
- {}
-
- void deactivate()
- { impl_->deactivate(); }
-
- bool empty() const
- { return impl_->empty(); }
-
- void put( T const& t)
- { impl_->put( t); }
-
- bool take( value_type & va)
- { return impl_->take( va); }
-
- bool try_take( value_type & va)
- { return impl_->try_take( va); }
-};
-
-}}
-
-#include <boost/config/abi_suffix.hpp>
-
-#endif // BOOST_FIBERS_UNBOUNDED_FIFO_H

Modified: sandbox/fiber/boost/fiber/utility.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/utility.hpp (original)
+++ sandbox/fiber/boost/fiber/utility.hpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -9,6 +9,7 @@
 
 #include <boost/bind.hpp>
 #include <boost/function.hpp>
+#include <boost/move/move.hpp>
 
 #include <boost/fiber/fiber.hpp>
 #include <boost/fiber/strategy.hpp>
@@ -66,6 +67,14 @@
 void cancel()
 { fibers::strategy::cancel_(); }
 
+inline
+void submit_fiber( fiber f)
+{ fibers::strategy::submit_fiber_( f); }
+
+inline
+void submit_fiber( BOOST_RV_REF( fiber) f)
+{ fibers::strategy::submit_fiber_( f); }
+
 }}
 
 #include <boost/config/abi_suffix.hpp>

Modified: sandbox/fiber/change.log
==============================================================================
--- sandbox/fiber/change.log (original)
+++ sandbox/fiber/change.log 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -1,3 +1,9 @@
+0.3.5:
+------
+- boudned/unbounded-fifo renamed to bounded/unbounded-channel
+- new function this_fiber::submit_fiber( fiber f) in order to pass
+ a new fiber to the scheduler running the active fiber
+
 0.3.4:
 ------
 - spinning sync. primitives check if invoked in a fiber

Modified: sandbox/fiber/libs/fiber/doc/fiber_ref.qbk
==============================================================================
--- sandbox/fiber/libs/fiber/doc/fiber_ref.qbk (original)
+++ sandbox/fiber/libs/fiber/doc/fiber_ref.qbk 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -596,6 +596,21 @@
 ]
 [endsect]
 
+[section:submit Non-member function `submit_fiber( fiber)`]
+
+ #include <boost/fiber/utility.hpp>
+
+ namespace this_fiber
+ {
+ void submit_fiber( fiber);
+ }
+
+[variablelist
+[[Effects:] [Submits the passed fiber to the scheduler running the active fiber.]]
+[[Throws:] [__fiber_error__ if an error occurs.]]
+]
+[endsect]
+
 [section:disable_interruption Class `disable_interruption`]
 
     #include <boost/fiber/interruption.hpp>

Modified: sandbox/fiber/libs/fiber/doc/fifos.qbk
==============================================================================
--- sandbox/fiber/libs/fiber/doc/fifos.qbk (original)
+++ sandbox/fiber/libs/fiber/doc/fifos.qbk 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -12,7 +12,7 @@
 [note fifos are bound to the __scheduler__ passed to the construtor and can only be used by fibers
 managed by this scheduler.]
 
- typedef boost::fibers::unbounded_fifo< int > fifo_t;
+ typedef boost::fibers::unbounded_channel< int > fifo_t;
 
     void send( fifo_t fifo)
     {
@@ -40,16 +40,16 @@
     }
 
 
-[section:unbounded_fifo Template `template< typename T > unbounded_fifo`]
+[section:unbounded_channel Template `template< typename T > unbounded_channel`]
 
- #include <boost/fiber/unbounded_fifo.hpp>
+ #include <boost/fiber/unbounded_channel.hpp>
 
     template< typename T >
- class unbounded_fifo : private noncopyable
+ class unbounded_channel : private noncopyable
     {
     public:
         template< typename Strategy >
- unbounded_fifo( scheduler< Strategy > & sched);
+ unbounded_channel( scheduler< Strategy > & sched);
 
         void deactivate();
 
@@ -62,9 +62,9 @@
         bool try_take( boost::optional< T > & va);
     };
 
-[section:constructor `template< typename Strategy > unbounded_fifo( scheduler< Strategy > & sched)`]
+[section:constructor `template< typename Strategy > unbounded_channel( scheduler< Strategy > & sched)`]
 [variablelist
-[[Effects:] [Constructs an object of class `unbounded_fifo`.]]
+[[Effects:] [Constructs an object of class `unbounded_channel`.]]
 [[Throws:] [Nothing.]]
 ]
 [endsect]
@@ -112,19 +112,19 @@
 [endsect]
 
 
-[section:bounded_fifo Template `template< typename T > bounded_fifo`]
+[section:bounded_channel Template `template< typename T > bounded_channel`]
 
- #include <boost/fiber/bounded_fifo.hpp>
+ #include <boost/fiber/bounded_channel.hpp>
 
     template< typename T >
- class bounded_fifo : private noncopyable
+ class bounded_channel : private noncopyable
     {
     public:
         template< typename Strategy >
- bounded_fifo( scheduler< Strategy > & sched, std::size_t wm);
+ bounded_channel( scheduler< Strategy > & sched, std::size_t wm);
 
         template< typename Strategy >
- bounded_fifo( scheduler< Strategy > & sched, std::size_t hwm, std::size_t lwm);
+ bounded_channel( scheduler< Strategy > & sched, std::size_t hwm, std::size_t lwm);
 
         void deactivate();
 
@@ -137,16 +137,16 @@
         bool try_take( boost::optional< T > & va);
     };
 
-[section:constructor `template< typename Strategy > bounded_fifo( scheduler< Strategy > & sched, std::size_t wm)`]
+[section:constructor `template< typename Strategy > bounded_channel( scheduler< Strategy > & sched, std::size_t wm)`]
 [variablelist
-[[Effects:] [Constructs an object of class `bounded_fifo` which will contain a maximum of `wm` items.]]
+[[Effects:] [Constructs an object of class `bounded_channel` which will contain a maximum of `wm` items.]]
 [[Throws:] [Nothing.]]
 ]
 [endsect]
 
-[section:constructor2 `template< typename Strategy > bounded_fifo( scheduler< Strategy > & sched, std::size_t wm)`]
+[section:constructor2 `template< typename Strategy > bounded_channel( scheduler< Strategy > & sched, std::size_t wm)`]
 [variablelist
-[[Effects:] [Constructs an object of class `bounded_fifo` which will contain a maximum of `wm` items.]]
+[[Effects:] [Constructs an object of class `bounded_channel` which will contain a maximum of `wm` items.]]
 [[Throws:] [Nothing.]]
 ]
 [endsect]

Modified: sandbox/fiber/libs/fiber/doc/spin_fifos.qbk
==============================================================================
--- sandbox/fiber/libs/fiber/doc/spin_fifos.qbk (original)
+++ sandbox/fiber/libs/fiber/doc/spin_fifos.qbk 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -12,7 +12,7 @@
 [note fifos are ['not] bound to a __scheduler__ and can only be used by fibers
 managed by different schedulers or code not running in a fiber.]
 
- typedef boost::fibers::spin::unbounded_fifo< int > fifo_t;
+ typedef boost::fibers::spin::unbounded_channel< int > fifo_t;
 
     void send( fifo_t fifo)
     {
@@ -40,15 +40,15 @@
     }
 
 
-[section:unbounded_fifo Template `template< typename T > unbounded_fifo`]
+[section:unbounded_channel Template `template< typename T > unbounded_channel`]
 
- #include <boost/fiber/spin/unbounded_fifo.hpp>
+ #include <boost/fiber/spin/unbounded_channel.hpp>
 
     template< typename T >
- class unbounded_fifo : private noncopyable
+ class unbounded_channel : private noncopyable
     {
     public:
- unbounded_fifo();
+ unbounded_channel();
 
         void deactivate();
 
@@ -61,9 +61,9 @@
         bool try_take( boost::optional< T > & va);
     };
 
-[section:constructor `unbounded_fifo()`]
+[section:constructor `unbounded_channel()`]
 [variablelist
-[[Effects:] [Constructs an object of class `unbounded_fifo`.]]
+[[Effects:] [Constructs an object of class `unbounded_channel`.]]
 [[Throws:] [Nothing.]]
 ]
 [endsect]
@@ -111,17 +111,17 @@
 [endsect]
 
 
-[section:bounded_fifo Template `template< typename T > bounded_fifo`]
+[section:bounded_channel Template `template< typename T > bounded_channel`]
 
- #include <boost/fiber/spin/bounded_fifo.hpp>
+ #include <boost/fiber/spin/bounded_channel.hpp>
 
     template< typename T >
- class bounded_fifo : private noncopyable
+ class bounded_channel : private noncopyable
     {
     public:
- bounded_fifo( std::size_t wm);
+ bounded_channel( std::size_t wm);
 
- bounded_fifo( std::size_t hwm, std::size_t lwm);
+ bounded_channel( std::size_t hwm, std::size_t lwm);
 
         void deactivate();
 
@@ -134,16 +134,16 @@
         bool try_take( boost::optional< T > & va);
     };
 
-[section:constructor `bounded_fifo( std::size_t wm)`]
+[section:constructor `bounded_channel( std::size_t wm)`]
 [variablelist
-[[Effects:] [Constructs an object of class `bounded_fifo` which will contain a maximum of `wm` items.]]
+[[Effects:] [Constructs an object of class `bounded_channel` which will contain a maximum of `wm` items.]]
 [[Throws:] [Nothing.]]
 ]
 [endsect]
 
-[section:constructor2 `bounded_fifo( std::size_t hwm, std::size_t lwm)`]
+[section:constructor2 `bounded_channel( std::size_t hwm, std::size_t lwm)`]
 [variablelist
-[[Effects:] [Constructs an object of class `bounded_fifo` which will contain a maximum of `hwm` items.]]
+[[Effects:] [Constructs an object of class `bounded_channel` which will contain a maximum of `hwm` items.]]
 [[Throws:] [Nothing.]]
 ]
 [endsect]

Modified: sandbox/fiber/libs/fiber/examples/ping_pong.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/examples/ping_pong.cpp (original)
+++ sandbox/fiber/libs/fiber/examples/ping_pong.cpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -10,7 +10,7 @@
 
 #include <boost/fiber.hpp>
 
-typedef boost::fibers::unbounded_fifo< std::string > fifo_t;
+typedef boost::fibers::unbounded_channel< std::string > fifo_t;
 typedef boost::intrusive_ptr< fifo_t > fifo_ptr;
 
 inline

Modified: sandbox/fiber/libs/fiber/examples/ping_pong_mt.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/examples/ping_pong_mt.cpp (original)
+++ sandbox/fiber/libs/fiber/examples/ping_pong_mt.cpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -12,7 +12,7 @@
 
 #include <boost/fiber.hpp>
 
-typedef boost::fibers::spin::unbounded_fifo< std::string > fifo_t;
+typedef boost::fibers::spin::unbounded_channel< std::string > fifo_t;
 
 inline
 void ping(

Modified: sandbox/fiber/libs/fiber/src/strategy.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/strategy.cpp (original)
+++ sandbox/fiber/libs/fiber/src/strategy.cpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -101,6 +101,24 @@
         active->info_->st->cancel( active_fiber->get_id() );
 }
 
+void
+strategy::submit_fiber_( fiber f)
+{
+ fiber * active( active_fiber.get() );
+ if ( ! active) throw fiber_error("not a fiber");
+ if ( ! active->info_->st) throw scheduler_error("no valid scheduler");
+ active->info_->st->add( f);
+}
+
+void
+strategy::submit_fiber_( BOOST_RV_REF( fiber) f)
+{
+ fiber * active( active_fiber.get() );
+ if ( ! active) throw fiber_error("not a fiber");
+ if ( ! active->info_->st) throw scheduler_error("no valid scheduler");
+ active->info_->st->add( f);
+}
+
 strategy::strategy() :
         use_count_( 0),
         master_fiber()

Modified: sandbox/fiber/libs/fiber/test/test_auto_reset_event.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/test/test_auto_reset_event.cpp (original)
+++ sandbox/fiber/libs/fiber/test/test_auto_reset_event.cpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -12,7 +12,6 @@
 
 #include <boost/bind.hpp>
 #include <boost/cstdint.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/function.hpp>
 #include <boost/ref.hpp>
 #include <boost/test/unit_test.hpp>

Modified: sandbox/fiber/libs/fiber/test/test_condition.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/test/test_condition.cpp (original)
+++ sandbox/fiber/libs/fiber/test/test_condition.cpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -12,7 +12,6 @@
 
 #include <boost/bind.hpp>
 #include <boost/cstdint.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/function.hpp>
 #include <boost/ref.hpp>
 #include <boost/test/unit_test.hpp>

Modified: sandbox/fiber/libs/fiber/test/test_manual_reset_event.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/test/test_manual_reset_event.cpp (original)
+++ sandbox/fiber/libs/fiber/test/test_manual_reset_event.cpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -12,7 +12,6 @@
 
 #include <boost/bind.hpp>
 #include <boost/cstdint.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/function.hpp>
 #include <boost/ref.hpp>
 #include <boost/test/unit_test.hpp>

Modified: sandbox/fiber/libs/fiber/test/test_mutex.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/test/test_mutex.cpp (original)
+++ sandbox/fiber/libs/fiber/test/test_mutex.cpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -13,7 +13,6 @@
 #include <vector>
 
 #include <boost/bind.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/function.hpp>
 #include <boost/ref.hpp>
 #include <boost/test/unit_test.hpp>

Modified: sandbox/fiber/libs/fiber/test/test_utility.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/test/test_utility.cpp (original)
+++ sandbox/fiber/libs/fiber/test/test_utility.cpp 2009-12-26 04:44:24 EST (Sat, 26 Dec 2009)
@@ -47,6 +47,13 @@
         }
 }
 
+void submit_fn( int n)
+{
+ boost::this_fiber::submit_fiber(
+ boost::fibers::make_fiber(
+ & yield_fn, n, boost::fiber::default_stacksize) );
+}
+
 void test_case_1()
 {
         boost::fibers::scheduler<> sched;
@@ -111,6 +118,21 @@
         BOOST_CHECK_EQUAL( 2, value);
 }
 
+void test_case_5()
+{
+ value = 0;
+ boost::fibers::scheduler<> sched;
+ sched.make_fiber( submit_fn, 5, boost::fiber::default_stacksize);
+ BOOST_CHECK_EQUAL( 0, value);
+
+ for (;;)
+ {
+ while ( sched.run() );
+ if ( sched.empty() ) break;
+ }
+ BOOST_CHECK_EQUAL( 5, value);
+}
+
 boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
 {
         boost::unit_test::test_suite * test =
@@ -120,6 +142,7 @@
         test->add( BOOST_TEST_CASE( & test_case_2) );
         test->add( BOOST_TEST_CASE( & test_case_3) );
         test->add( BOOST_TEST_CASE( & test_case_4) );
+ test->add( BOOST_TEST_CASE( & test_case_5) );
 
         return test;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk