Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r57824 - in sandbox/fiber: boost boost/fiber boost/fiber/detail libs/fiber/build libs/fiber/doc libs/fiber/examples libs/fiber/src libs/fiber/test
From: oliver.kowalke_at_[hidden]
Date: 2009-11-20 18:42:06


Author: olli
Date: 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
New Revision: 57824
URL: http://svn.boost.org/trac/boost/changeset/57824

Log:
- docu
- strategy -> interface
- round_robin as strategy

Added:
   sandbox/fiber/boost/fiber/detail/round_robin.hpp (contents, props changed)
   sandbox/fiber/boost/fiber/locks.hpp (contents, props changed)
   sandbox/fiber/libs/fiber/doc/Jamfile.v2 (contents, props changed)
   sandbox/fiber/libs/fiber/doc/acknowledgements.qbk (contents, props changed)
   sandbox/fiber/libs/fiber/doc/condition_variables.qbk (contents, props changed)
   sandbox/fiber/libs/fiber/doc/event_variables.qbk (contents, props changed)
   sandbox/fiber/libs/fiber/doc/fiber.qbk (contents, props changed)
   sandbox/fiber/libs/fiber/doc/fiber_ref.qbk (contents, props changed)
   sandbox/fiber/libs/fiber/doc/fifos.qbk (contents, props changed)
   sandbox/fiber/libs/fiber/doc/lockables.qbk (contents, props changed)
   sandbox/fiber/libs/fiber/doc/mutexes.qbk (contents, props changed)
   sandbox/fiber/libs/fiber/doc/overview.qbk (contents, props changed)
   sandbox/fiber/libs/fiber/doc/scheduler.qbk (contents, props changed)
   sandbox/fiber/libs/fiber/doc/todo.qbk (contents, props changed)
   sandbox/fiber/libs/fiber/src/round_robin.cpp (contents, props changed)
Removed:
   sandbox/fiber/boost/fiber/unique_lock.hpp
   sandbox/fiber/libs/fiber/examples/suspend.cpp
   sandbox/fiber/libs/fiber/src/strategy.cpp
   sandbox/fiber/libs/fiber/test/test_suspended.cpp
Text files modified:
   sandbox/fiber/boost/fiber.hpp | 2
   sandbox/fiber/boost/fiber/bounded_fifo.hpp | 8 +-
   sandbox/fiber/boost/fiber/condition.hpp | 2
   sandbox/fiber/boost/fiber/detail/fiber_state.hpp | 7 +-
   sandbox/fiber/boost/fiber/detail/strategy.hpp | 83 ++++++++++-----------------------------
   sandbox/fiber/boost/fiber/exceptions.hpp | 6 +-
   sandbox/fiber/boost/fiber/fiber.hpp | 9 +--
   sandbox/fiber/boost/fiber/interruption.hpp | 32 +++++++++++----
   sandbox/fiber/boost/fiber/mutex.hpp | 2
   sandbox/fiber/boost/fiber/scheduler.hpp | 8 ---
   sandbox/fiber/boost/fiber/unbounded_fifo.hpp | 2
   sandbox/fiber/boost/fiber/utility.hpp | 4 -
   sandbox/fiber/libs/fiber/build/Jamfile.v2 | 4
   sandbox/fiber/libs/fiber/examples/Jamfile.v2 | 1
   sandbox/fiber/libs/fiber/examples/interrupt.cpp | 2
   sandbox/fiber/libs/fiber/src/auto_reset_event.cpp | 4 +
   sandbox/fiber/libs/fiber/src/condition.cpp | 3 +
   sandbox/fiber/libs/fiber/src/count_down_event.cpp | 6 ++
   sandbox/fiber/libs/fiber/src/fiber.cpp | 14 ------
   sandbox/fiber/libs/fiber/src/manual_reset_event.cpp | 6 ++
   sandbox/fiber/libs/fiber/src/scheduler.cpp | 28 ------------
   sandbox/fiber/libs/fiber/test/Jamfile.v2 | 1
   sandbox/fiber/libs/fiber/test/test_interrupt.cpp | 6 +-
   23 files changed, 89 insertions(+), 151 deletions(-)

Modified: sandbox/fiber/boost/fiber.hpp
==============================================================================
--- sandbox/fiber/boost/fiber.hpp (original)
+++ sandbox/fiber/boost/fiber.hpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -14,11 +14,11 @@
 #include <boost/fiber/exceptions.hpp>
 #include <boost/fiber/fiber.hpp>
 #include <boost/fiber/interruption.hpp>
+#include <boost/fiber/locks.hpp>
 #include <boost/fiber/manual_reset_event.hpp>
 #include <boost/fiber/mutex.hpp>
 #include <boost/fiber/scheduler.hpp>
 #include <boost/fiber/unbounded_fifo.hpp>
-#include <boost/fiber/unique_lock.hpp>
 #include <boost/fiber/utility.hpp>
 
 #endif // BOOST_FIBER_H

Modified: sandbox/fiber/boost/fiber/bounded_fifo.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/bounded_fifo.hpp (original)
+++ sandbox/fiber/boost/fiber/bounded_fifo.hpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -19,8 +19,8 @@
 #include <boost/fiber/condition.hpp>
 #include <boost/fiber/detail/atomic.hpp>
 #include <boost/fiber/exceptions.hpp>
+#include <boost/fiber/locks.hpp>
 #include <boost/fiber/mutex.hpp>
-#include <boost/fiber/unique_lock.hpp>
 
 #include <boost/config/abi_prefix.hpp>
 
@@ -115,7 +115,7 @@
                 use_count_( 0)
         {
                 if ( hwm_ < lwm_)
- throw std::invalid_argument("invalid watermark");
+ throw invalid_watermark();
         }
 
         bounded_fifo( std::size_t const& wm) :
@@ -135,7 +135,7 @@
         void upper_bound_( std::size_t hwm)
         {
                 if ( hwm < lwm_)
- throw std::invalid_argument("invalid watermark");
+ throw invalid_watermark();
                 std::size_t tmp( hwm_);
                 hwm_ = hwm;
                 if ( hwm_ > tmp) not_full_cond_.notify_one();
@@ -147,7 +147,7 @@
         void lower_bound_( std::size_t lwm)
         {
                 if ( lwm > hwm_ )
- throw std::invalid_argument("invalid watermark");
+ throw invalid_watermark();
                 std::size_t tmp( lwm_);
                 lwm_ = lwm;
                 if ( lwm_ > tmp) not_full_cond_.notify_one();

Modified: sandbox/fiber/boost/fiber/condition.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/condition.hpp (original)
+++ sandbox/fiber/boost/fiber/condition.hpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -41,6 +41,8 @@
 public:
         condition();
 
+ ~condition();
+
         void notify_one();
 
         void notify_all();

Modified: sandbox/fiber/boost/fiber/detail/fiber_state.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/detail/fiber_state.hpp (original)
+++ sandbox/fiber/boost/fiber/detail/fiber_state.hpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -19,14 +19,13 @@
         STATE_NOT_STARTED = 1 << 1,
         STATE_READY = 1 << 2,
         STATE_RUNNING = 1 << 3,
- STATE_SUSPENDED = 1 << 4,
- STATE_WAIT_FOR_JOIN = 1 << 5,
- STATE_TERMINATED = 1 << 6
+ STATE_WAIT_FOR_JOIN = 1 << 4,
+ STATE_TERMINATED = 1 << 5
 };
 
 typedef char fiber_state_t;
 
-#define IS_ALIVE_BIT_MASK 0x3C
+#define IS_ALIVE_BIT_MASK 0x1C
 
 enum interrupt_t
 {

Added: sandbox/fiber/boost/fiber/detail/round_robin.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/detail/round_robin.hpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,114 @@
+
+// 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_DETAIL_ROUND_ROBIN_H
+#define BOOST_FIBERS_DETAIL_ROUND_ROBIN_H
+
+#include <cstddef>
+#include <list>
+#include <map>
+#include <queue>
+
+#include <boost/function.hpp>
+#include <boost/optional.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/fiber/detail/config.hpp>
+#include <boost/fiber/detail/fiber_state.hpp>
+#include <boost/fiber/detail/strategy.hpp>
+#include <boost/fiber/fiber.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+# if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable:4251 4275)
+# endif
+
+namespace boost {
+namespace fibers {
+namespace detail {
+
+class BOOST_FIBER_DECL round_robin : private noncopyable,
+ public strategy
+{
+private:
+ struct schedulable
+ {
+ fiber f;
+ std::list< fiber::id > joining_fibers;
+ optional< fiber::id > waiting_on;
+
+ schedulable() :
+ f(), joining_fibers(), waiting_on()
+ {}
+
+ schedulable( fiber f_) :
+ f( f_), joining_fibers(), waiting_on()
+ {}
+ };
+
+ typedef std::map< fiber::id, schedulable > container;
+ typedef std::list< fiber::id > runnable_queue;
+ typedef std::queue< fiber::id > terminated_queue;
+
+ fiber master_;
+ fiber active_;
+ container fibers_;
+ runnable_queue runnable_fibers_;
+ terminated_queue terminated_fibers_;
+
+public:
+ round_robin();
+
+ ~round_robin();
+
+ void add( fiber const&);
+
+ fiber::id get_id() const;
+
+ void yield();
+
+ void cancel();
+
+ void interrupt();
+
+ bool interruption_requested() const;
+
+ bool interruption_enabled() const;
+
+ fiber_interrupt_t & interrupt_flags();
+
+ int priority() const;
+
+ void priority( int);
+
+ void at_exit( callable_t);
+
+ void interrupt( fiber::id const&);
+
+ void cancel( fiber::id const&);
+
+ void join( fiber::id const&);
+
+ void reschedule( fiber::id const&);
+
+ bool run();
+
+ bool empty() const;
+
+ std::size_t size() const;
+};
+
+}}}
+
+# if defined(BOOST_MSVC)
+# pragma warning(pop)
+# endif
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBERS_DETAIL_ROUND_ROBIN_H

Modified: sandbox/fiber/boost/fiber/detail/strategy.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/detail/strategy.hpp (original)
+++ sandbox/fiber/boost/fiber/detail/strategy.hpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -8,16 +8,9 @@
 #define BOOST_FIBERS_DETAIL_STRATEGY_H
 
 #include <cstddef>
-#include <list>
-#include <map>
-#include <queue>
 
 #include <boost/function.hpp>
-#include <boost/optional.hpp>
-#include <boost/utility.hpp>
 
-#include <boost/fiber/detail/config.hpp>
-#include <boost/fiber/detail/fiber_state.hpp>
 #include <boost/fiber/fiber.hpp>
 
 #include <boost/config/abi_prefix.hpp>
@@ -31,81 +24,47 @@
 namespace fibers {
 namespace detail {
 
-class BOOST_FIBER_DECL strategy : private noncopyable
+struct BOOST_FIBER_DECL strategy
 {
-private:
- struct schedulable
- {
- fiber f;
- std::list< fiber::id > joining_fibers;
- optional< fiber::id > waiting_on;
+ typedef function< void() > callable_t;
 
- schedulable() :
- f(), joining_fibers(), waiting_on()
- {}
+ virtual ~strategy() {}
 
- schedulable( fiber f_) :
- f( f_), joining_fibers(), waiting_on()
- {}
- };
+ virtual void add( fiber const&) = 0;
 
- typedef std::map< fiber::id, schedulable > container;
- typedef std::list< fiber::id > runnable_queue;
- typedef std::queue< fiber::id > terminated_queue;
- typedef function< void() > callable_t;
+ virtual fiber::id get_id() const = 0;
 
- fiber master_;
- fiber active_;
- container fibers_;
- runnable_queue runnable_fibers_;
- terminated_queue terminated_fibers_;
+ virtual void yield() = 0;
 
-public:
- strategy();
+ virtual void cancel() = 0;
 
- ~strategy();
+ virtual void interrupt() = 0;
 
- void add( fiber);
+ virtual bool interruption_requested() const = 0;
 
- fiber::id get_id() const;
+ virtual bool interruption_enabled() const = 0;
 
- void yield();
+ virtual fiber_interrupt_t & interrupt_flags() = 0;
 
- void cancel();
+ virtual int priority() const = 0;
 
- void suspend();
+ virtual void priority( int) = 0;
 
- void interrupt();
+ virtual void at_exit( callable_t) = 0;
 
- bool interruption_requested();
+ virtual void interrupt( fiber::id const&) = 0;
 
- bool interruption_enabled();
+ virtual void cancel( fiber::id const&) = 0;
 
- fiber_interrupt_t & interrupt_flags();
+ virtual void join( fiber::id const&) = 0;
 
- int priority();
+ virtual void reschedule( fiber::id const&) = 0;
 
- void priority( int);
+ virtual bool run() = 0;
 
- void at_exit( callable_t);
+ virtual bool empty() const = 0;
 
- void interrupt( fiber::id const&);
-
- void cancel( fiber::id const&);
-
- void suspend( fiber::id const&);
-
- void resume( fiber::id const&);
-
- void join( fiber::id const&);
-
- void reschedule( fiber::id const&);
-
- bool run();
-
- bool empty();
-
- std::size_t size();
+ virtual std::size_t size() const = 0;
 };
 
 }}}

Modified: sandbox/fiber/boost/fiber/exceptions.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/exceptions.hpp (original)
+++ sandbox/fiber/boost/fiber/exceptions.hpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -36,11 +36,11 @@
         {}
 };
 
-class invalid_stacksize : public std::runtime_error
+class invalid_watermark : public std::runtime_error
 {
 public:
- invalid_stacksize() :
- std::runtime_error("invalid stacksize")
+ invalid_watermark() :
+ std::runtime_error("invalid watermark")
         {}
 };
 

Modified: sandbox/fiber/boost/fiber/fiber.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/fiber.hpp (original)
+++ sandbox/fiber/boost/fiber/fiber.hpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -32,7 +32,7 @@
 namespace fibers {
 namespace detail {
 
-class strategy;
+class round_robin;
 
 }
 
@@ -41,7 +41,7 @@
 class BOOST_FIBER_DECL fiber
 {
 private:
- friend class detail::strategy;
+ friend class detail::round_robin;
 
         struct dummy;
 
@@ -201,14 +201,11 @@
         void priority( int);
 
         void interrupt();
+
         bool interruption_requested() const;
 
         void cancel();
 
- void suspend();
-
- void resume();
-
         void join();
 };
 

Modified: sandbox/fiber/boost/fiber/interruption.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/interruption.hpp (original)
+++ sandbox/fiber/boost/fiber/interruption.hpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -20,9 +20,13 @@
 namespace boost {
 namespace fibers {
 
+class restore_interruption;
+
 class BOOST_FIBER_DECL disable_interruption : private noncopyable
 {
 private:
+ friend class restore_interruption;
+
         bool set_;
 
 public:
@@ -35,28 +39,38 @@
 
         ~disable_interruption()
         {
- if ( ! set_)
- scheduler::interrupt_flags() &= ~detail::INTERRUPTION_BLOCKED;
+ try
+ {
+ if ( ! set_)
+ scheduler::interrupt_flags() &= ~detail::INTERRUPTION_BLOCKED;
+ }
+ catch (...)
+ {}
         }
 };
 
 class BOOST_FIBER_DECL restore_interruption : private noncopyable
 {
 private:
- bool set_;
+ disable_interruption & disabler_;
 
 public:
- restore_interruption() :
- set_( ( scheduler::interrupt_flags() & detail::INTERRUPTION_BLOCKED) != 0)
+ explicit restore_interruption( disable_interruption & disabler) :
+ disabler_( disabler)
         {
- if ( set_)
+ if ( ! disabler_.set_)
                         scheduler::interrupt_flags() &= ~detail::INTERRUPTION_BLOCKED;
         }
 
         ~restore_interruption()
- {
- if ( set_)
- scheduler::interrupt_flags() |= detail::INTERRUPTION_BLOCKED;
+ {
+ try
+ {
+ if ( ! disabler_.set_)
+ scheduler::interrupt_flags() |= detail::INTERRUPTION_BLOCKED;
+ }
+ catch (...)
+ {}
         }
 };
 

Added: sandbox/fiber/boost/fiber/locks.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/locks.hpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,241 @@
+
+// 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)
+//
+// based on boost::interprocess::sync::scoped_lock
+
+#ifndef BOOST_FIBERS_LOCK_H
+#define BOOST_FIBERS_LOCK_H
+
+#include <algorithm>
+
+#include <boost/config.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/thread_time.hpp>
+
+#include <boost/fiber/detail/move.hpp>
+
+#include <boost/fiber/exceptions.hpp>
+
+namespace boost {
+namespace fibers {
+
+template< typename Mutex >
+class lock_guard
+{
+private:
+ Mutex & mtx_;
+
+ explicit lock_guard( lock_guard &);
+ lock_guard & operator=( lock_guard &);
+
+public:
+ explicit lock_guard( Mutex & mtx) :
+ mtx_( mtx)
+ { mtx_.lock(); }
+
+ lock_guard( Mutex & mtx, adopt_lock_t) :
+ mtx_( mtx)
+ {}
+
+ ~lock_guard()
+ { mtx_.unlock(); }
+};
+
+template< typename Mutex >
+class unique_lock
+{
+private:
+ typedef unique_lock< Mutex > lock_t;
+ typedef bool unique_lock::*unspecified_bool_type;
+
+ Mutex * mtx_;
+ bool locked_;
+
+ unique_lock( unique_lock &);
+ unique_lock & operator=( unique_lock &);
+
+public:
+ unique_lock() :
+ mtx_( 0),
+ locked_( false)
+ {}
+
+ explicit unique_lock( Mutex & mtx) :
+ mtx_( & mtx),
+ locked_( false)
+ {
+ mtx_->lock();
+ locked_ = true;
+ }
+
+ unique_lock( Mutex & mtx, adopt_lock_t) :
+ mtx_( & mtx),
+ locked_( true)
+ {}
+
+ unique_lock( Mutex & mtx, defer_lock_t) :
+ mtx_( & mtx),
+ locked_( false)
+ {}
+
+ unique_lock( Mutex & mtx, try_to_lock_t) :
+ mtx_( & mtx),
+ locked_( mtx_->try_lock() )
+ {}
+
+ unique_lock( Mutex & mtx, system_time const& abs_time) :
+ mtx_( & mtx),
+ locked_( mtx_->timed_lock( abs_time) )
+ {}
+
+ template< typename TimeDuration >
+ unique_lock( Mutex & mtx, TimeDuration const& rel_time) :
+ mtx_( & mtx),
+ locked_( mtx_->timed_lock( rel_time) )
+ {}
+
+#ifdef BOOST_HAS_RVALUE_REFS
+ unique_lock( unique_lock && other) :
+ mtx_( other.mtx_),
+ locked_( other.locked_)
+ {
+ other.locked_ = false;
+ other.mtx_ = 0;
+ }
+
+ unique_lock< Mutex > && move()
+ { return static_cast< unique_lock< Mutex > && >( * this); }
+
+ unique_lock & operator=( unique_lock< Mutex > && other)
+ {
+ unique_lock tmp( other);
+ swap( tmp);
+ return * this;
+ }
+
+ void swap( unique_lock && other)
+ {
+ std::swap( mtx_, other.mtx_);
+ std::swap( locked_, other.locked_);
+ }
+#else
+ unique_lock( detail::thread_move_t< unique_lock< Mutex > > other) :
+ mtx_( other->mtx_),
+ locked_( other->locked_)
+ {
+ other->locked_ = false;
+ other->mtx_ = 0;
+ }
+
+ operator detail::thread_move_t< unique_lock< Mutex > >()
+ { return move(); }
+
+ detail::thread_move_t< unique_lock< Mutex > > move()
+ { return detail::thread_move_t< unique_lock< Mutex > >( * this); }
+
+ unique_lock & operator=( detail::thread_move_t< unique_lock< Mutex > > other)
+ {
+ unique_lock tmp( other);
+ swap( tmp);
+ return * this;
+ }
+
+ void swap( detail::thread_move_t< unique_lock< Mutex > > other)
+ {
+ std::swap( mtx_, other->mtx_);
+ std::swap( locked_, other->locked_);
+ }
+#endif
+
+ ~unique_lock()
+ {
+ try
+ { if ( locked_ && mtx_) mtx_->unlock(); }
+ catch (...) {}
+ }
+
+ void lock()
+ {
+ if ( ! mtx_ || locked_)
+ throw lock_error();
+ mtx_->lock();
+ locked_ = true;
+ }
+
+ bool try_lock()
+ {
+ if ( ! mtx_ || locked_)
+ throw lock_error();
+ locked_ = mtx_->try_lock();
+ return locked_;
+ }
+
+ bool timed_lock( system_time const& abs_time)
+ {
+ if ( ! mtx_ || locked_)
+ throw lock_error();
+ locked_ = mtx_->timed_lock( abs_time);
+ return locked_;
+ }
+
+ template< typename TimeDuration >
+ bool timed_lock( TimeDuration const& rel_time)
+ { return timed_lock( get_system_time() + rel_time); }
+
+ void unlock()
+ {
+ if ( ! mtx_ || ! locked_)
+ throw lock_error();
+ mtx_->unlock();
+ locked_ = false;
+ }
+
+ bool owns_lock() const
+ { return locked_ && mtx_; }
+
+ operator unspecified_bool_type() const
+ { return locked_ ? & lock_t::locked_ : 0; }
+
+ bool operator!() const
+ { return ! locked_; }
+
+ Mutex * mutex() const
+ { return mtx_; }
+
+ Mutex * release()
+ {
+ Mutex * mtx = mtx_;
+ mtx_ = 0;
+ locked_ = false;
+ return mtx;
+ }
+
+ void swap( unique_lock & other)
+ {
+ std::swap( mtx_, other.mtx_);
+ std::swap( locked_, other.locked_);
+ }
+};
+
+#ifdef BOOST_HAS_RVALUE_REFS
+ template< typename Mutex >
+ void swap( unique_lock< Mutex > && lhs, unique_lock< Mutex > && rhs)
+ { lhs.swap( rhs); }
+#else
+ template< typename Mutex >
+ void swap( unique_lock< Mutex > & lhs, unique_lock< Mutex > & rhs)
+ { lhs.swap(rhs); }
+#endif
+
+#ifdef BOOST_HAS_RVALUE_REFS
+ template< typename Mutex >
+ inline unique_lock< Mutex > && move( unique_lock< Mutex > && ul)
+ { return ul; }
+#endif
+
+}}
+
+#endif // BOOST_FIBERS_LOCK_H

Modified: sandbox/fiber/boost/fiber/mutex.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/mutex.hpp (original)
+++ sandbox/fiber/boost/fiber/mutex.hpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -13,7 +13,7 @@
 #include <boost/thread/thread_time.hpp>
 #include <boost/utility.hpp>
 
-#include <boost/fiber/unique_lock.hpp>
+#include <boost/fiber/locks.hpp>
 
 namespace boost {
 namespace fibers {

Modified: sandbox/fiber/boost/fiber/scheduler.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/scheduler.hpp (original)
+++ sandbox/fiber/boost/fiber/scheduler.hpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -35,7 +35,6 @@
 boost::fiber::id get_id();
 void yield();
 void cancel();
-void suspend();
 int priority();
 void priority( int);
 void interruption_point();
@@ -60,7 +59,6 @@
         friend fiber::id this_fiber::get_id();
         friend void this_fiber::yield();
         friend void this_fiber::cancel();
- friend void this_fiber::suspend();
         friend int this_fiber::priority();
         friend void this_fiber::priority( int);
         friend void this_fiber::interruption_point();
@@ -95,8 +93,6 @@
 
         static void cancel();
 
- static void suspend();
-
         static int priority();
 
         static void priority( int);
@@ -109,10 +105,6 @@
 
         static void cancel( fiber::id const&);
 
- static void suspend( fiber::id const&);
-
- static void resume( fiber::id const&);
-
         static void join( fiber::id const&);
 
         static void reschedule( fiber::id const&);

Modified: sandbox/fiber/boost/fiber/unbounded_fifo.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/unbounded_fifo.hpp (original)
+++ sandbox/fiber/boost/fiber/unbounded_fifo.hpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -19,8 +19,8 @@
 #include <boost/fiber/condition.hpp>
 #include <boost/fiber/detail/atomic.hpp>
 #include <boost/fiber/exceptions.hpp>
+#include <boost/fiber/locks.hpp>
 #include <boost/fiber/mutex.hpp>
-#include <boost/fiber/unique_lock.hpp>
 
 #include <boost/config/abi_prefix.hpp>
 

Deleted: sandbox/fiber/boost/fiber/unique_lock.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/unique_lock.hpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
+++ (empty file)
@@ -1,147 +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)
-//
-// based on boost::interprocess::sync::scoped_lock
-
-#ifndef BOOST_FIBERS_UNIQUE_LOCK_H
-#define BOOST_FIBERS_UNIQUE_LOCK_H
-
-#include <algorithm>
-
-#include <boost/thread/locks.hpp>
-#include <boost/thread/thread_time.hpp>
-
-#include <boost/fiber/exceptions.hpp>
-
-namespace boost {
-namespace fibers {
-
-template< typename Mutex >
-class unique_lock
-{
-private:
- typedef unique_lock< Mutex > lock_t;
- typedef bool unique_lock::*unspecified_bool_type;
-
- Mutex * mtx_;
- bool locked_;
-
- unique_lock( unique_lock &);
- unique_lock & operator=( unique_lock &);
-
-public:
- unique_lock() :
- mtx_( 0),
- locked_( false)
- {}
-
- explicit unique_lock( Mutex & mtx) :
- mtx_( & mtx),
- locked_( false)
- {
- mtx_->lock();
- locked_ = true;
- }
-
- unique_lock( Mutex & mtx, adopt_lock_t) :
- mtx_( & mtx),
- locked_( true)
- {}
-
- unique_lock( Mutex & mtx, defer_lock_t) :
- mtx_( & mtx),
- locked_( false)
- {}
-
- unique_lock( Mutex & mtx, try_to_lock_t) :
- mtx_( & mtx),
- locked_( mtx_->try_lock() )
- {}
-
- unique_lock( Mutex & mtx, system_time const& abs_time) :
- mtx_( & mtx),
- locked_( mtx_->timed_lock( abs_time) )
- {}
-
- template< typename TimeDuration >
- unique_lock( Mutex & mtx, TimeDuration const& rel_time) :
- mtx_( & mtx),
- locked_( mtx_->timed_lock( rel_time) )
- {}
-
- ~unique_lock()
- {
- try
- { if ( locked_ && mtx_) mtx_->unlock(); }
- catch (...) {}
- }
-
- void lock()
- {
- if ( ! mtx_ || locked_)
- throw lock_error();
- mtx_->lock();
- locked_ = true;
- }
-
- bool try_lock()
- {
- if ( ! mtx_ || locked_)
- throw lock_error();
- locked_ = mtx_->try_lock();
- return locked_;
- }
-
- bool timed_lock( system_time const& abs_time)
- {
- if ( ! mtx_ || locked_)
- throw lock_error();
- locked_ = mtx_->timed_lock( abs_time);
- return locked_;
- }
-
- template< typename TimeDuration >
- bool timed_lock( TimeDuration const& rel_time)
- { return timed_lock( get_system_time() + rel_time); }
-
- void unlock()
- {
- if ( ! mtx_ || ! locked_)
- throw lock_error();
- mtx_->unlock();
- locked_ = false;
- }
-
- bool owns_lock() const
- { return locked_ && mtx_; }
-
- operator unspecified_bool_type() const
- { return locked_ ? & lock_t::locked_ : 0; }
-
- bool operator!() const
- { return ! locked_; }
-
- Mutex * mutex() const
- { return mtx_; }
-
- Mutex * release()
- {
- Mutex * mtx = mtx_;
- mtx_ = 0;
- locked_ = false;
- return mtx;
- }
-
- void swap( unique_lock & other)
- {
- std::swap( mtx_, other.mtx_);
- std::swap( locked_, other.locked_);
- }
-};
-
-}}
-
-#endif // BOOST_FIBERS_UNIQUE_LOCK_H

Modified: sandbox/fiber/boost/fiber/utility.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/utility.hpp (original)
+++ sandbox/fiber/boost/fiber/utility.hpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -36,10 +36,6 @@
 { fibers::scheduler::cancel(); }
 
 inline
-void suspend()
-{ fibers::scheduler::suspend(); }
-
-inline
 int priority()
 { return fibers::scheduler::priority(); }
 

Modified: sandbox/fiber/libs/fiber/build/Jamfile.v2
==============================================================================
--- sandbox/fiber/libs/fiber/build/Jamfile.v2 (original)
+++ sandbox/fiber/libs/fiber/build/Jamfile.v2 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -49,8 +49,8 @@
         fiber_windows.cpp
         manual_reset_event.cpp
         mutex.cpp
+ round_robin.cpp
         scheduler.cpp
- strategy.cpp
     : ## requirements ##
       <fiberapi>win32
     ;
@@ -65,8 +65,8 @@
         fiber_posix.cpp
         manual_reset_event.cpp
         mutex.cpp
+ round_robin.cpp
         scheduler.cpp
- strategy.cpp
     : ## requirements ##
       <fiberapi>posix
     ;

Added: sandbox/fiber/libs/fiber/doc/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/doc/Jamfile.v2 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,33 @@
+# (C) Copyright 2008 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)
+
+path-constant boost-images : ../../../doc/src/images ;
+
+xml fiber : fiber.qbk ;
+
+boostbook standalone
+ :
+ fiber
+ :
+ # HTML options first:
+ # Use graphics not text for navigation:
+ <xsl:param>navig.graphics=1
+ # How far down we chunk nested sections, basically all of them:
+ <xsl:param>chunk.section.depth=3
+ # Don't put the first section on the same page as the TOC:
+ <xsl:param>chunk.first.sections=1
+ # How far down sections get TOC's
+ <xsl:param>toc.section.depth=10
+ # Max depth in each TOC:
+ <xsl:param>toc.max.depth=3
+ # How far down we go with TOC's
+ <xsl:param>generate.section.toc.level=10
+ # Path for links to Boost:
+ <xsl:param>boost.root=../../../..
+ # Path for libraries index:
+ <xsl:param>boost.libraries=../../../../libs/libraries.htm
+ # Use the main Boost stylesheet:
+ <xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
+ ;

Added: sandbox/fiber/libs/fiber/doc/acknowledgements.qbk
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/doc/acknowledgements.qbk 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,12 @@
+[/
+ 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
+
+ Based on documentation from Boost.Thread.
+]
+
+[section:acknowledgements Acknowledgments]
+
+[endsect]

Added: sandbox/fiber/libs/fiber/doc/condition_variables.qbk
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/doc/condition_variables.qbk 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,151 @@
+[/
+ (C) Copyright 2007-8 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).
+]
+
+[section:condvar_ref Condition Variables]
+
+[heading Synopsis]
+
+The class `condition` provides a mechanism for one fiber to wait for notification
+`condition` or `condition_any`. When the fiber is woken from
+the wait, then it checks to see if the appropriate condition is now true, and
+continues if so. If the condition is not true, then the fiber then calls `wait`
+again to resume waiting. In the simplest case, this condition is just a boolean
+variable:
+
+ boost::fibers::condition cond;
+ boost::fibers::mutex mtx;
+ bool data_ready;
+
+ void process_data();
+
+ void wait_for_data_to_process()
+ {
+ boost::fibers::unique_lock< boost::fibers::mutex > lk( mtx);
+ while ( ! data_ready)
+ {
+ cond.wait( lk);
+ }
+ process_data();
+ }
+
+Notice that the `lk` is passed to `wait`: `wait` will atomically add the
+fiber to the set of fibers waiting on the condition variable, and unlock the
+mutex. When the fiber is woken, the mutex will be locked again before the call
+to `wait` returns. This allows other fibers to acquire the mutex in order to
+update the shared data, and ensures that the data associated with the condition
+is correctly synchronized.
+
+In the mean time, another fiber sets the condition to `true`, and then calls
+either `notify_one` or `notify_all` on the condition variable to wake one
+waiting fiber or all the waiting fibers respectively.
+
+ void retrieve_data();
+ void prepare_data();
+
+ void prepare_data_for_processing()
+ {
+ retrieve_data();
+ prepare_data();
+ {
+ boost::lock_guard< boost::fibers::mutex > lk( mtx);
+ data_ready = true;
+ }
+ cond.notify_one();
+ }
+
+Note that the same mutex is locked before the shared data is updated, but that
+the mutex does not have to be locked across the call to `notify_one`.
+
+[section:condition Class `condition`]
+
+ #include <boost/fiber/condition.hpp>
+
+ class condition
+ {
+ public:
+ condition();
+ ~condition();
+
+ void notify_one();
+ void notify_all();
+
+ void wait( boost::fibers::unique_lock< boost::fibers::mutex > & lk);
+
+ template< typename predicate_type >
+ void wait( boost::fibers::unique_lock< boost::fibers::mutex > & lk,predicate_type predicate);
+ };
+
+[section:constructor `condition()`]
+[variablelist
+[[Effects:] [Constructs an object of class `condition`.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:destructor `~condition()`]
+[variablelist
+[[Precondition:] [All fibers waiting on `*this` have been notified by a call to
+`notify_one` or `notify_all` (though the respective calls to `wait` need not have
+returned).]]
+[[Effects:] [Destroys the object.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:notify_one `void notify_one()`]
+[variablelist
+[[Effects:] [If any fibers are currently __blocked__ waiting on `*this` in a call
+to `wait`, unblocks one of those fibers.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:notify_all `void notify_all()`]
+[variablelist
+[[Effects:] [If any fibers are currently __blocked__ waiting on `*this` in a call
+to `wait`, unblocks all of those fibers.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:wait `void wait( boost::fibers::unique_lock< boost::fibers::mutex> & lk)`]
+[variablelist
+[[Precondition:] [`lock` is locked by the current fiber, and either no other
+fiber is currently waiting on `*this`, or the execution of the `mutex()` member
+function on the `lk` objects supplied in the calls to `wait` in all the fibers
+currently waiting on `*this` would return the same value as `lock->mutex()` for
+this call to `wait`.]]
+[[Effects:] [Atomically call `lock.unlock()` and blocks the current fiber. The
+fiber will unblock when notified by a call to `this->notify_one()` or
+`this->notify_all()`, or spuriously. When the fiber is unblocked (for whatever
+reason), the lock is reacquired by invoking `lock.lock()` before the call to
+`wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
+function exits with an exception.]]
+[[Postcondition:] [`lock` is locked by the current fiber.]]
+[[Throws:] [__fiber_resource_error__ if an error
+occurs. __fiber_interrupted__ if the wait was interrupted by a call to
+__interrupt__ on the __fiber__ object associated with the current fiber of execution.]]
+
+]
+[endsect]
+
+[section:wait_predicate `template< typename predicate_type >
+ void wait( boost::fibers::unique_lock< boost::fibers::mutex > & lock, predicate_type pred)`]
+[variablelist
+[[Effects:] [As-if ``
+while ( ! pred())
+{
+ wait( lock);
+}
+``]]
+
+]
+[endsect]
+
+[endsect]
+
+[endsect]

Added: sandbox/fiber/libs/fiber/doc/event_variables.qbk
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/doc/event_variables.qbk 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,314 @@
+[/
+ (C) Copyright 2007-8 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).
+]
+
+[section:eventvar_ref Event Variables]
+
+[heading Synopsis]
+
+__boost_fiber__ provides event variables to facilitate coordination between fibers.
+A event-variable has two states `set` (`signaled`) or `reset` (`nonsignaled`).
+
+ boost::fibers::auto_reset_event ev;
+
+ void process_data();
+
+ void wait_for_data_to_process()
+ {
+ ev.wait();
+ process_data();
+ }
+
+`wait` will atomically add the fiber to the set of fibers waiting on the event
+variable. When the fiber is woken, the event variable will be reset again.
+
+In the mean time, another fiber signals the event variable by calling
+`set` on the event variable to wake one waiting fiber.
+
+ void retrieve_data();
+ void prepare_data();
+
+ void prepare_data_for_processing()
+ {
+ retrieve_data();
+ prepare_data();
+ ev.set();
+ }
+
+
+[section:auto_reset_event Class `auto_reset_event`]
+
+ #include <boost/fiber/auto_reset_event.hpp>
+
+ class auto_reset_event : private boost::noncopyable
+ {
+ public:
+ explicit auto_reset_event( bool isset = false);
+
+ ~auto_reset_event();
+
+ void set();
+
+ void wait();
+
+ bool try_wait();
+ };
+
+[section:constructor `auto_reset_event()`]
+
+ explicit auto_reset_event( bool isset = false);
+
+[variablelist
+[[Effects:] [Constructs an object of class `auto_reset_event`. If isset is `true`
+the variable is set.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:destructor `~auto_reset_event()`]
+
+ ~auto_reset_event();
+
+[variablelist
+[[Precondition:] [All fibers waiting on `*this` have been notified by a call to
+`set` (though the respective calls to `wait` need not have returned).]]
+[[Effects:] [Destroys the object.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:set `void set()`]
+
+ void set();
+
+[variablelist
+[[Effects:] [If any fibers are currently __blocked__ waiting on `*this` in a call
+to `wait`, unblocks one of those fibers.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:wait `void wait()`]
+
+ void wait();
+
+[variablelist
+[[Effects:] [Blocks the current fiber. The fiber will unblock when notified by a call
+to `this->set()`. When the fiber is unblocked, the variable is reset before `wait`
+returns.]]
+[[Throws:] [__fiber_interrupted__ if the wait was interrupted by a call to
+__interrupt__ on the __fiber__ object associated with the current fiber of execution.]]
+]
+[endsect]
+
+[section:try_wait `bool try_wait()`]
+
+ bool try_wait();
+
+[variablelist
+[[Effects:] [Returns `true` if the event variable is set otherwise `false`.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[endsect]
+
+
+[section:manual_reset_event Class `manual_reset_event`]
+
+ #include <boost/fiber/manual_reset_event.hpp>
+
+ class manual_reset_event : private boost::noncopyable
+ {
+ public:
+ explicit manual_reset_event( bool isset = false);
+
+ ~manual_reset_event();
+
+ void set();
+
+ void reset();
+
+ void wait();
+
+ bool try_wait();
+ };
+
+[section:constructor `manual_reset_event()`]
+
+ explicit manual_reset_event( bool isset = false);
+
+[variablelist
+[[Effects:] [Constructs an object of class `manual_reset_event`. If isset is `true`
+the variable is set.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:destructor `~manual_reset_event()`]
+
+ ~manual_reset_event();
+
+[variablelist
+[[Precondition:] [All fibers waiting on `*this` have been notified by a call to
+`set` (though the respective calls to `wait` need not have returned).]]
+[[Effects:] [Destroys the object.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:set `void set()`]
+
+ void set();
+
+[variablelist
+[[Effects:] [If any fibers are currently __blocked__ waiting on `*this` in a call
+to `wait`, unblocks those fibers. The variable remains signaled until `this->reset()`
+gets called.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:reset `void reset()`]
+
+ void reset();
+
+[variablelist
+[[Effects:] [The event variable gets nonsignaled and fibers calling `this->wait()`
+will block.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:wait `void wait()`]
+
+ void wait();
+
+[variablelist
+[[Effects:] [Blocks the current fiber. The fiber will unblock when notified by a call
+to `this->set()`. When the fiber is unblocked, the variable remains set.]]
+[[Throws:] [__fiber_interrupted__ if the wait was interrupted by a call to
+__interrupt__ on the __fiber__ object associated with the current fiber of execution.]]
+]
+[endsect]
+
+[section:trywait `boo try_wait()`]
+
+ bool try_wait();
+
+[variablelist
+[[Effects:] [Returns `true` if the event variable is set otherwise `false`.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[endsect]
+
+
+[section:count_down_event Class `count_down_event`]
+
+ #include <boost/fiber/count_down_event.hpp>
+
+ class count_down_event : private boost::noncopyable
+ {
+ public:
+ explicit count_down_event( uint32_t);
+
+ ~count_down_event();
+
+ uint32_t initial() const;
+
+ uint32_t current() const;
+
+ bool is_set() const;
+
+ void set();
+
+ void wait();
+
+ bool wait( system_time const&);
+ };
+
+[section:constructor `count_down_event( uint32_t)`]
+
+ explicit count_down_event( uint32_t initial);
+
+[variablelist
+[[Effects:] [Constructs an object of class `count_down_event` with initial value.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:destructor `~count_down_event()`]
+
+ ~count_down_event();
+
+[variablelist
+[[Precondition:] [All fibers waiting on `*this` have been notified by a call to
+`set` (though the respective calls to `wait` need not have returned).]]
+[[Effects:] [Destroys the object.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:initial `uint32_t initial()`]
+
+ uint32_t initial();
+
+[variablelist
+[[Effects:] [Returns the initial value the event variable was initialized with.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:current `uint32_t current()`]
+
+ uint32_t current();
+
+[variablelist
+[[Effects:] [Returns the value the variable currently holds.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:is_set `bool is_set()`]
+
+ bool is_set();
+
+[variablelist
+[[Effects:] [Returns `true` if the varaible has reached zero.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:set `void set()`]
+
+ void set();
+
+[variablelist
+[[Effects:] [Decrements the current count. If the count reaches zero and any fibers are
+currently __blocked__ waiting on `*this` in a call to `wait`, unblocks those fibers.
+The variable remains signaled.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:wait `void wait()`]
+
+ void wait();
+
+[variablelist
+[[Effects:] [Blocks the current fiber. The fiber will unblock when notified by a call
+to `this->set()` and the count of the event variable reaches zero. When the fiber is
+unblocked, the variable remains set.]]
+[[Throws:] [__fiber_interrupted__ if the wait was interrupted by a call to
+__interrupt__ on the __fiber__ object associated with the current fiber of execution.]]
+]
+[endsect]
+
+[endsect]
+
+[endsect]

Added: sandbox/fiber/libs/fiber/doc/fiber.qbk
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/doc/fiber.qbk 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,91 @@
+[/
+ (C) Copyright 2007-8 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).
+]
+
+[article Fiber
+ [quickbook 1.4]
+ [authors [Kowalke, Oliver]]
+ [copyright 2009 Oliver Kowalke]
+ [purpose C++ Library for launching fibers and synchronizing data between them]
+ [category text]
+ [license
+ 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])
+ ]
+]
+
+[def __boost_fiber__ [*Boost.Fiber]]
+[def __boost_task__ [*Boost.Task]]
+[def __boost_thread__ [*Boost.Thread]]
+
+[def __blocked__ ['blocked]]
+[def __fiber__ ['fiber]]
+[def __interruption_points__ [link interruption_points ['interruption points]]]
+[def __not_a_fiber__ ['not-a-fiber]]
+[def __scheduler__ ['scheduler]]
+
+[template lockable_concept_link[link_text] [link fiber.synchronization.mutex_concepts.lockable [link_text]]]
+[template lock_ref_link[link_text] [link fiber.synchronization.mutex_concepts.lockable.lock [link_text]]]
+[template lock_multiple_ref_link[link_text] [link fiber.synchronization.lock_functions.lock_multiple [link_text]]]
+[template try_lock_multiple_ref_link[link_text] [link fiber.synchronization.lock_functions.try_lock_multiple [link_text]]]
+[template unlock_ref_link[link_text] [link fiber.synchronization.mutex_concepts.lockable.unlock [link_text]]]
+[template try_lock_ref_link[link_text] [link fiber.synchronization.mutex_concepts.lockable.try_lock [link_text]]]
+[template owns_lock_ref_link[link_text] [link fiber.synchronization.locks.unique_lock.owns_lock [link_text]]]
+[template mutex_func_ref_link[link_text] [link fiber.synchronization.locks.unique_lock.mutex [link_text]]]
+[template unique_lock_link[link_text] [link fiber.synchronization.locks.unique_lock [link_text]]]
+[template join_link[link_text] [link fiber.fiber_management.fiber.join [link_text]]]
+[template cond_wait_link[link_text] [link fiber.synchronization.condvar_ref.condition_variable.wait [link_text]]]
+[template cond_any_wait_link[link_text] [link fiber.synchronization.condvar_ref.condition_variable_any.wait [link_text]]]
+
+
+[def __lockable_concept__ [lockable_concept_link `Lockable` concept]]
+[def __lockable_concept_type__ [lockable_concept_link `Lockable`]]
+[def __lock_multiple_ref__ [lock_multiple_ref_link `lock()`]]
+[def __lock_ref__ [lock_ref_link `lock()`]]
+[def __mutex_func_ref__ [mutex_func_ref_link `mutex()`]]
+[def __mutex__ [link fiber.synchronization.mutex_types.mutex `boost::fibers::mutex`]]
+[def __owns_lock_ref__ [owns_lock_ref_link `owns_lock()`]]
+[def __try_lock_multiple_ref__ [try_lock_multiple_ref_link `try_lock()`]]
+[def __try_lock_ref__ [try_lock_ref_link `try_lock()`]]
+[def __unlock_ref__ [unlock_ref_link `unlock()`]]
+
+
+[def __lock_guard__ [link fiber.synchronization.locks.lock_guard `boost::lock_guard`]]
+[def __unique_lock__ [unique_lock_link `boost::fiber::unique_lock`]]
+
+[def __fiber__ [link fiber.fiber_management.fiber `boost::fiber`]]
+[def __fiber_id__ [link fiber.fiber_management.fiber.id `boost::fiber::id`]]
+[def __join__ [join_link `join()`]]
+[def __interrupt__ [link fiber.fiber_management.fiber.interrupt `interrupt()`]]
+
+[def __interruption_enabled__ [link fiber.fiber_management.this_fiber.interruption_enabled `boost::this_fiber::interruption_enabled()`]]
+[def __interruption_requested__ [link fiber.fiber_management.this_fiber.interruption_requested `boost::this_fiber::interruption_requested()`]]
+[def __interruption_point__ [link fiber.fiber_management.this_fiber.interruption_point `boost::this_fiber::interruption_point()`]]
+[def __disable_interruption__ [link fiber.fiber_management.this_fiber.disable_interruption `boost::this_fiber::disable_interruption`]]
+[def __restore_interruption__ [link fiber.fiber_management.this_fiber.restore_interruption `boost::this_fiber::restore_interruption`]]
+
+[def __fiber_interrupted__ `boost::fibers::fiber_interrupted`]
+[def __fiber_error__ `boost::fibers::fiber_error`]
+[def __fiber_moved__ `boost::fibers::fiber_moved`]
+[def __system_error__ `boost::system::system_error`]
+
+[def __cond_wait__ [cond_wait_link `wait()`]]
+[def __cond_any_wait__ [cond_any_wait_link `wait()`]]
+
+
+[include overview.qbk]
+[include fiber_ref.qbk]
+[include scheduler.qbk]
+[section:synchronization Synchronization]
+[include lockables.qbk]
+[include mutexes.qbk]
+[include condition_variables.qbk]
+[include event_variables.qbk]
+[include fifos.qbk]
+[include todo.qbk]
+[endsect]
+[include acknowledgements.qbk]

Added: sandbox/fiber/libs/fiber/doc/fiber_ref.qbk
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/doc/fiber_ref.qbk 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,795 @@
+[/
+ (C) Copyright 2007-8 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).
+]
+
+[section:fiber_management Fiber Management]
+
+
+[heading Synopsis]
+
+Each __fiber__ class represents a user-space context of execution which will be launched and managed by the
+__scheduler__ class. Objects of type __fiber__ are copy- and moveable.
+
+ boost::fiber f; // not-a-fiber
+
+ void f()
+ {
+ boost::fiber f1=boost::fibers::make_fiber( some_fn);
+ boost::fiber f2=boost::fibers::make_fiber( another_fn);
+
+ boost::fibers::scheduler s;
+ s.submit( f1); // f1 gets copied
+ s.submit( boost::move( f2) ); // f2 gets moved
+
+ std::cout << f1.get_id() << std::endl;
+ std::cout << f2.get_id() << std::endl;
+ }
+
+
+[heading Launching fibers]
+
+A new fiber is launched by passing an object of a callable type that can be invoked with no parameters to the
+constructor and submiting the fiber (copy- or move-op.) to an instance of __scheduler__. The object is then copied
+into internal storage, and invoked on the newly-created fiber. If the object must not (or cannot) be copied, then
+`boost::ref` can be used to pass in a reference to the function object. In this case, the user of __boost_fiber__
+must ensure that the referred-to object outlives the newly-created fiber.
+
+ struct callable
+ { void operator()(); };
+
+ boost::fiber copies_are_safe()
+ {
+ callable x;
+ return boost::fiber( x);
+ } // x is destroyed, but the newly-created fiber has a copy, so this is OK
+
+ boost::fiber oops()
+ {
+ callable x;
+ return boost::fiber( boost::ref( x) );
+ } // x is destroyed, but the newly-created fiber still has a reference
+ // this leads to undefined behaviour
+
+If you wish to construct an instance of __fiber__ with a function or callable object that requires arguments to be
+supplied, this can be done by passing additional arguments to the __fiber__ constructor:
+
+ void find_the_question( int the_answer);
+
+ boost::fiber deep_thought_2( find_the_question, 42);
+
+The arguments are ['copied] into the internal fiber structure: if a reference is required, use `boost::ref`, just as
+for references to callable functions.
+
+For convinience `boost::fibers::make_fiber()` is provided:
+
+ boost::fiber f = boost::fibers::make_fiber( new_fn, arg1, arg2, arg3);
+
+Another alternative is to use __scheduler_make_fiber__ which creates and stores the new fiber inside the scheduler.
+
+ boost::fibers::scheduler sched;
+ sched.make_fiber( new_fn, arg1, arg2, arg3);
+
+
+[heading Exceptions in fiber functions]
+
+Exceptions thrown by the function or callable object passed to the __fiber__ constructor are consumed by the
+framework (if it required to know whichexceptions was thrown __boost_task__ should be used together with
+__boost_fiber__).
+
+
+[heading Joining]
+
+In order to wait for a fiber to finish, the __join__ member functions of the __fiber__ object can be
+used. __join__ will block the calling fiber until the fiber represented by the __fiber__ object has completed.
+If the fiber has already completed, or the __fiber__ object represents __not_a_fiber__, then __join__ returns
+immediately.
+
+ void some_fn()
+ {}
+
+ void joining_fiber_fn( boost::fiber f)
+ { f.join(); }
+
+ boost:.fibers::scheduler sched;
+ boost::fiber f( some_fn);
+ sched.submit_fiber( f);
+ sched.make_fiber( joining_fiber, f);
+ for (;;)
+ {
+ while ( sched.run() );
+ if ( sched.empty() ) break;
+ }
+
+
+[heading Interruption]
+
+A running fiber can be ['interrupted] by invoking the __interrupt__ member function. When the interrupted fiber
+next executes one of the specified __interruption_points__ (or if it is currently __blocked__ whilst executing one)
+with interruption enabled, then a __fiber_interrupted__ exception will be thrown in the interrupted fiber. If not
+caught, this will cause the execution of the interrupted fiber to terminate.
+
+If a fiber wishes to avoid being interrupted, it can create an instance of __disable_interruption__. Objects of this
+class disable interruption for the fiber that created them on construction, and restore the interruption state to
+whatever it was before on destruction:
+
+ void f()
+ {
+ // interruption enabled here
+ {
+ boost::this_fiber::disable_interruption disabler1;
+ // interruption disabled
+ {
+ boost::this_fiber::disable_interruption disabler2;
+ // interruption still disabled
+ } // disabler2 destroyed, interruption state restored
+ // interruption still disabled
+ } // disabler1 destroyed, interruption state restored
+ // interruption now enabled
+ }
+
+The effects of an instance of __disable_interruption__ can be temporarily reversed by constructing an instance of
+__restore_interruption__, passing in the __disable_interruption__ object in question. This will restore the
+interruption state to what it was when the __disable_interruption__ object was constructed, and then disable
+interruption again when the __restore_interruption__ object is destroyed.
+
+ void g()
+ {
+ // interruption enabled here
+ {
+ boost::this_fiber::disable_interruption disabler;
+ // interruption disabled
+ {
+ boost::this_fiber::restore_interruption restorer( disabler);
+ // interruption now enabled
+ } // restorer destroyed, interruption disable again
+ } // disabler destroyed, interruption state restored
+ // interruption now enabled
+ }
+
+At any point, the interruption state for the current fiber can be queried by calling __interruption_enabled__.
+
+[#interruption_points]
+
+
+[heading Predefined Interruption Points]
+
+The following functions are ['interruption points], which will throw __fiber_interrupted__ if interruption is
+enabled for the current fiber, and interruption is requested for the current fiber:
+
+* [join_link `boost::fiber::join()`]
+* [cond_wait_link `boost::fibers::condition::wait()`]
+* [auto_reset_wait_link `boost::fibers::auto_reset_event::wait()`]
+* [manual_reset_wait_link `boost::fibers::manual_reset_event::wait()`]
+* [count_down_wait_link `boost::fibers::count_down_event::wait()`]
+* __interruption_point__
+
+
+[heading Fiber IDs]
+
+Objects of class __fiber_id__ can be used to identify fibers. Each running fiber has a unique ID
+obtainable from the corresponding __fiber__ by calling the `get_id()` member function, or by calling
+`boost::this_fiber::get_id()` from within the fiber. Objects of class __fiber_id__ can be copied, and used as
+keys in associative containers: the full range of comparison operators is provided. Fiber IDs can also be written
+to an output stream using the stream insertion operator, though the output format is unspecified.
+
+Each instance of __fiber_id__ either refers to some fiber, or __not_a_fiber__. Instances that refer to __not_a_fiber__
+compare equal to each other, but not equal to any instances that refer to an actual fiber.
+The comparison operators on __fiber_id__ yield a total order for every non-equal fiber ID.
+
+
+[section:fiber Class `fiber`]
+
+ #include <boost/fiber/fiber.hpp>
+
+ class fiber
+ {
+ public:
+ fiber();
+ ~fiber();
+
+ template< typename Fn >
+ explicit fiber( Fn fn);
+
+ template< typename Fn >
+ explicit fiber( std::size_t stack_size, Fn fn);
+
+ template< typename Fn, typename A1, typename A2,...>
+ fiber( Fn fn, A1 a1, A2 a2,...);
+
+ template< typename Fn, typename A1, typename A2,...>
+ fiber( std::size_t stack_size, Fn fn, A1 a1, A2 a2,...);
+
+ template< typename Fn >
+ fiber( detail::fiber_move_t< Fn > f);
+
+ // move support
+ fiber( detail::fiber_move_t< fiber > x);
+ fiber & operator=( detail::fiber_move_t< fiber > x);
+ operator detail::fiber_move_t< fiber >();
+ detail::fiber_move_t< fiber > move();
+
+ operator ``['unspecified-bool-type]``() const;
+
+ bool operator!() const;
+
+ void swap( fiber & other);
+
+ id get_id() const;
+
+ bool operator==( fiber const&) const;
+ bool operator!=( fiber const&) const;
+
+ bool is_alive() const;
+
+ int priority() const;
+
+ void priority( int);
+
+ void interrupt();
+ bool interruption_requested() const;
+
+ void cancel();
+
+ void join();
+ };
+
+ void swap( fiber & lhs, fiber & rhs);
+
+ template< typename Fn >
+ fiber make_fiber( Fn fn);
+
+ template< typename Fn >
+ fiber make_fiber( std::size_t stack_size, Fn fn);
+
+ template< typename Fn, typename A1, typename A2,... >
+ fiber make_fiber( Fn fn, A1 a1, A2 a2,...);
+
+ template< typename Fn, typename A1, typename A2,... >
+ fiber make_fiber( std::size_t stack_size, Fn fn, A1 a1, A2 a2,...);
+
+
+[section:default_constructor Default Constructor]
+
+ fiber();
+
+[variablelist
+[[Effects:] [Constructs a __fiber__ instance that refers to __not_a_fiber__.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:callable_constructor Fiber Constructor]
+
+ template< typename Callable >
+ fiber( Callable fn);
+
+ template< typename Callable >
+ fiber( std::size_t stack_size, Callable fn);
+
+[variablelist
+[[Preconditions:] [`Callable` must by copyable.]]
+[[Effects:] [`fn` is copied into storage managed internally by the fiber library, and that copy is invoked on a
+newly-created fiber. Second version sets the stack-size of the fiber.]]
+[[Postconditions:] [`*this` refers to the newly created fiber.]]
+[[Throws:] [__system_error__ if system call failed.]]
+]
+[endsect]
+
+[section:multiple_argument_constructor Fiber Constructor with arguments]
+
+ template< typename Fn, typename A1, typename A2,...>
+ fiber( Fn fn,A1 a1,A2 a2,...);
+
+ template< typename Fn, typename A1, typename A2,...>
+ fiber( std::size_t stack_size, Fn fn,A1 a1,A2 a2,...);
+
+[variablelist
+[[Preconditions:] [`Fn` and each `A`n must by copyable or movable.]]
+[[Effects:] [As if [link
+fiber.fiber_management.fiber.callable_constructor
+`fiber( boost::bind( fn, a1, a2,...) )`. Consequently, `fn` and each `a`n
+are copied into internal storage for access by the new fiber.
+Second version additionaly sets the stack-size used by the fiber.]]]
+[[Postconditions:] [`*this` refers to the newly created fiber.]]
+[[Throws:] [__system_error__ if system call failed.]]
+[[Note:] [Currently up to nine additional arguments `a1` to `a9` can be specified in addition to the function `fn`.]]
+]
+[endsect]
+
+[section:destructor Fiber Destructor]
+
+ ~fiber();
+
+[variablelist
+[[Effects:] [Destroys `*this`.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:get_id Member function `get_id()`]
+
+ fiber::id get_id() const;
+
+[variablelist
+[[Returns:] [If `*this` refers to a fiber, an instance of __fiber_id__ that represents that fiber. Otherwise returns
+a default-constructed __fiber_id__.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:join Member function `join()`]
+
+ void join();
+
+[variablelist
+[[Effects:] [Waits for that fiber to complete.]]
+[[Throws:] [__fiber_interrupted__ if the current fiber is interrupted and __system_error__
+if system call failed.]]
+[[Notes:] [`join()` is one of the predefined __interruption_points__.]]
+]
+[endsect]
+
+[section:interrupt Member function `interrupt()`]
+
+ void interrupt();
+
+[variablelist
+[[Effects:] [If `*this` refers to a fiber, request that the fiber will be interrupted the next time it enters one of
+the predefined __interruption_points__ with interruption enabled, or if it is currently __blocked__ in a call to one
+of the predefined __interruption_points__ with interruption enabled .]]
+[[Throws:] [__fiber_moved__ if not a fiber of execution.]]
+]
+[endsect]
+
+[section:interruption_requested Member function `interruption_requested()`]
+
+ bool interruption_requested();
+
+[variablelist
+[[Effects:] [If `*this` refers to a fiber, the function returns if the interruption of the fiber was already
+requested.]]
+[[Throws:] [__fiber_moved__ if `*this` is not a fiber of execution.]]
+]
+[endsect]
+
+[section:cancel Member function `cancel()`]
+
+ void cancel();
+
+[variablelist
+[[Effects:] [If `*this` refers to a fiber, request that the fiber will be canceled the next time it yields its
+execution.]]
+[[Throws:] [__system_error__ if system call fails. __fiber__moved__ if `*this` is not a fiber of execution.]]
+]
+[endsect]
+
+[section:is_alive Member function `is_alive()`]
+
+ bool is_alive();
+
+[variablelist
+[[Effects:] [If `*this` refers to a fiber, the function returns false if the fiber is terminated or not started
+Otherwise it returns true.]]
+[[Throws:] [__fiber_moved__ if `*this` is not a fiber of execution.]]
+]
+[endsect]
+
+[section:unspec_operator `operator unspecified-bool-type() const`]
+
+ operator ``['unspecified-bool-type]``() const;
+
+[variablelist
+[[Returns:] [If `*this` refers to a fiber, the function returns true. Otherwise false.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:not_operator `operator!`]
+
+ bool operator!() const;
+
+[variablelist
+[[Returns:] [If `*this` refers not to a fiber, the function returns true. Otherwise false.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:equals `operator==`]
+
+ bool operator==(const fiber& other) const;
+
+[variablelist
+[[Returns:] [`get_id()==other.get_id()`]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:not_equals `operator!=`]
+
+ bool operator!=(const fiber& other) const;
+
+[variablelist
+[[Returns:] [`get_id()!=other.get_id()`]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:swap Member function `swap()`]
+
+ void swap(fiber& other);
+
+[variablelist
+[[Effects:] [Exchanges the fibers associated with `*this` and `other`, so `*this` is associated with the fiber
+associated with `other` prior to the call, and vice-versa.]]
+[[Postconditions:] [`this->get_id()` returns the same value as `other.get_id()` prior to the call. `other.get_id()`
+returns the same value as `this->get_id()` prior to the call.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:non_member_swap Non-member function `swap()`]
+
+ #include <boost/fiber/fiber.hpp>
+
+ void swap( fiber & lhs, fiber & rhs);
+
+[variablelist
+[[Effects:] [[link fiber.fiber_management.fiber.swap `lhs.swap( rhs)`].]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:non_member_make_fiber Non-member template function `make_fiber()`]
+
+ #include <boost/fiber/fiber.hpp>
+
+ template< typename Fn >
+ fiber make_fiber( Fn fn);
+
+ template< typename Fn >
+ fiber make_fiber( std::size_t stack_size, Fn fn);
+
+ template< typename Fn, typename A1, typename A2,... >
+ fiber make_fiber( Fn fn, A1 a1, A2 a2,...);
+
+ template< typename Fn, typename A1, typename A2,... >
+ fiber make_fiber( std::size_t stack_size, Fn fn, A1 a1, A2 a2,...);
+
+[variablelist
+[[Effects:] [Creates a fiber.]]
+]
+[endsect]
+
+[section:id Class `boost::fiber::id`]
+
+ #include <boost/fiber/fiber.hpp>
+
+ class fiber::id
+ {
+ public:
+ id();
+
+ bool operator==( id const& x) const;
+ bool operator!=( id const& x) const;
+ bool operator<( id const& x) const;
+ bool operator>( id const& x) const;
+ bool operator<=( id const& x) const;
+ bool operator>=( id const& x) const;
+
+ template< typename charT, typename traitsT >
+ friend std::basic_ostream< charT, traitsT > &
+ operator<<( std::basic_ostream< charT, traitsT > & os, id const& x);
+ };
+
+[section:constructor Default constructor]
+
+ id();
+
+[variablelist
+[[Effects:] [Constructs a __fiber_id__ instance that represents __not_a_fiber__.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:is_equal `operator==`]
+
+ bool operator==( id const& x) const;
+
+[variablelist
+[[Returns:] [`true` if `*this` and `x` both represent the same fiber, or both represent __not_a_fiber__, `false`
+otherwise.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:not_equal `operator!=`]
+
+ bool operator!=( id const& x) const;
+
+[variablelist
+[[Returns:] [`true` if `*this` and `x` represent different fibers, or one represents a fiber, and
+the other represent __not_a_fiber__, `false` otherwise.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:less_than `operator<`]
+
+ bool operator<( id const& x) const;
+
+[variablelist
+[[Returns:] [`true` if `*this!=x` is `true` and the implementation-defined total order of __fiber_id__ values places
+`*this` before `y`, `false` otherwise.]]
+[[Throws:] [Nothing.]]
+[[Note:] [A __fiber_id__ instance representing __not_a_fiber__ will always compare less than an instance representing
+a fiber of execution.]]
+]
+[endsect]
+
+
+[section:greater_than `operator>`]
+
+ bool operator>( id const& x) const;
+
+[variablelist
+[[Returns:] [`x<*this`]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:less_than_or_equal `operator>=`]
+
+ bool operator<=( id const& x) const;
+
+[variablelist
+[[Returns:] [`!(x<*this)`]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:greater_than_or_equal `operator>=`]
+
+ bool operator>=( id const& x) const;
+
+[variablelist
+[[Returns:] [`!(*this<x)`]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:stream_out Friend `operator<<`]
+
+ template< typename charT, typename traitsT >
+ friend std::basic_ostream< charT, traitsT > &
+ operator<<( std::basic_ostream< charT, traitsT > & os, id const& x);
+
+[variablelist
+[[Effects:] [Writes a representation of the __fiber_id__ instance `x` to the stream `os`, such that the representation of two
+instances of __fiber_id__ `a` and `b` is the same if `a==b`, and different if `a!=b`.]]
+[[Returns:] [`os`]]
+]
+[endsect]
+
+[endsect]
+
+[endsect]
+
+
+[section:this_fiber Namespace `this_fiber`]
+
+[section:runs_as_fiber Non-member function `runs_as_fiber()`]
+
+ #include <boost/fiber/utility.hpp>
+
+ namespace this_fiber
+ {
+ bool runs_as_fiber();
+ }
+
+[variablelist
+[[Returns:] [Returns `true` if current execution context is a fiber.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:get_id Non-member function `get_id()`]
+
+ #include <boost/fiber/utility.hpp>
+
+ namespace this_fiber
+ {
+ fiber::id get_id();
+ }
+
+[variablelist
+[[Returns:] [An instance of __fiber_id__ that represents that currently executing fiber.]]
+[[Throws:] [__fiber_error__ if the execution context is not a fiber.]]
+]
+[endsect]
+
+[section:interruption_point Non-member function `interruption_point()`]
+
+ #include <boost/fiber/utility.hpp>
+
+ namespace this_fiber
+ {
+ void interruption_point();
+ }
+
+[variablelist
+[[Effects:] [Check to see if the current fiber has been interrupted.]]
+[[Throws:] [__fiber_interrupted__ if __interruption_enabled__ and __interruption_requested__ both return `true` and
+__fiber_error__ if the execution context is not a fiber.]]
+]
+[endsect]
+
+[section:interruption_requested Non-member function `interruption_requested()`]
+
+ #include <boost/fiber/utility.hpp>
+
+ namespace this_fiber
+ {
+ bool interruption_requested();
+ }
+
+[variablelist
+[[Returns:] [`true` if interruption has been requested for the current fiber, `false` otherwise.]]
+[[Throws:] [__fiber_error__ if the execution context is not a fiber.]]
+]
+[endsect]
+
+[section:interruption_enabled Non-member function `interruption_enabled()`]
+
+ #include <boost/fiber/utility.hpp>
+
+ namespace this_fiber
+ {
+ bool interruption_enabled();
+ }
+
+[variablelist
+[[Returns:] [`true` if interruption has been enabled for the current fiber, `false` otherwise.]]
+[[Throws:] [__fiber_error__ if the execution context is not a fiber.]]
+]
+[endsect]
+
+[section:yield Non-member function `yield()`]
+
+ #include <boost/fiber/utility.hppV>
+
+ namespace this_fiber
+ {
+ void yield();
+ }
+
+[variablelist
+[[Effects:] [Cooperativly allows other fibers to run.]]
+[[Throws:] [__fiber_error__ if the execution context is not a fiber.]]
+]
+[endsect]
+
+[section:cancel Non-member function `cancel()`]
+
+ #include <boost/fiber/utility.hpp>
+
+ namespace this_fiber
+ {
+ void cancel();
+ }
+
+[variablelist
+[[Effects:] [Fiber gets canceled after calling `yield`.]]
+[[Throws:] [__fiber_error__ if the execution context is not a fiber.]]
+]
+[endsect]
+
+[section:disable_interruption Class `disable_interruption`]
+
+ #include <boost/fiber/interruption.hpp>
+
+ namespace this_fiber
+ {
+ class disable_interruption
+ {
+ public:
+ disable_interruption();
+ ~disable_interruption();
+ };
+ }
+
+`boost::this_fiber::disable_interruption` disables interruption for the current fiber on construction, and restores
+the prior interruption state on destruction. Instances of `disable_interruption` cannot be copied or moved.
+
+[section:constructor Constructor]
+
+ disable_interruption();
+
+[variablelist
+[[Effects:] [Stores the current state of __interruption_enabled__ and disables interruption for the current fiber.]]
+[[Postconditions:] [__interruption_enabled__ returns `false` for the current fiber.]]
+[[Throws:] [__fiber_error__ if the execution context is not a fiber.]]
+]
+[endsect]
+
+[section:destructor Destructor]
+
+ ~disable_interruption();
+
+[variablelist
+[[Preconditions:] [Must be called from the same fiber from which `*this` was constructed.]]
+[[Effects:] [Restores the current state of __interruption_enabled__ for the current fiber to that prior to the
+construction of `*this`.]]
+[[Postconditions:] [__interruption_enabled__ for the current fiber returns the value stored in the constructor of
+`*this`.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[endsect]
+
+[section:restore_interruption Class `restore_interruption`]
+
+ #include <boost/fiber/interruption.hpp>
+
+ namespace this_fiber
+ {
+ class restore_interruption
+ {
+ public:
+ explicit restore_interruption( disable_interruption & disabler);
+ ~restore_interruption();
+ };
+ }
+
+On construction of an instance of `boost::this_fiber::restore_interruption`, the interruption state for the current
+fiber is restored to the interruption state stored by the constructor of the supplied instance of
+__disable_interruption__. When the instance is destroyed, interruption is again disabled. Instances of
+`restore_interruption` cannot be copied or moved.
+
+[section:constructor Constructor]
+
+ explicit restore_interruption( disable_interruption & disabler);
+
+[variablelist
+[[Preconditions:] [Must be called from the same fiber from which `disabler` was constructed.]]
+[[Effects:] [Restores the current state of __interruption_enabled__ for the current fiber to that prior to the
+construction of `disabler`.]]
+[[Postconditions:] [__interruption_enabled__ for the current fiber returns the value stored in the constructor of
+`disabler`.]]
+[[Throws:] [__fiber_error__ if the execution context is not a fiber.]]
+]
+[endsect]
+
+[section:destructor Destructor]
+
+ ~restore_interruption();
+
+[variablelist
+[[Preconditions:] [Must be called from the same fiber from which `*this` was constructed.]]
+[[Effects:] [Disables interruption for the current fiber.]]
+[[Postconditions:] [__interruption_enabled__ for the current fiber returns `false`.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[endsect]
+
+[section:atfiberexit Non-member function template `at_fiber_exit()`]
+
+ #include <boost/fiber/utility.hpp>
+
+ template< typename Callable >
+ void at_fiber_exit( Callable ca);
+
+[variablelist
+[[Effects:] [A copy of `ca`. This copy is invoked when the current fiber exits (even if the fiber has been
+interrupted).]]
+[[Postconditions:] [A copy of `ca` has been saved for invocation on fiber exit.]]
+[[Throws:] [__fiber_error__ if the execution context is not a fiber.]]
+]
+[endsect]
+
+[endsect]

Added: sandbox/fiber/libs/fiber/doc/fifos.qbk
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/doc/fifos.qbk 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,221 @@
+[/
+ 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
+]
+
+[section:fifos (Un)Bounded fifos]
+
+__boost_fiber__ provides a bounded and a unbounded fifo suitable to synchonize fibers via message passing.
+Both classes implement methods in order to be used by boost::intrusive_ptr.
+
+ typedef boost::intrusive_ptr< boost::fibers::unbounded_fifo< int > > fifo_t;
+
+ void send( fifo_t fifo)
+ {
+ for ( int i = 0; i < 5; ++i)
+ fifo.put( i);
+ fifo.deactivate();
+ }
+
+ void recv( fifo_t fifo)
+ {
+ boost::optional< int > value;
+ while ( fifo.take( value) )
+ { std::cout << "received " << * value << std::endl; }
+ }
+
+ boost::fibers::scheduler sched;
+ fifo_t fifo( new boost::fibers::unbounded_fifo< int >() );
+ sched.make_fiber( send, fifo);
+ sched.make_fiber( recv, fifo);
+
+ for (;;)
+ {
+ while ( sched.run() );
+ if ( sched.empty() ) break;
+ }
+
+
+[section:unbounded_fifo Template `unbounded_fifo`]
+
+ #include <boost/fiber/unbounded_fifo.hpp>
+
+template< typename T >
+class unbounded_fifo : private noncopyable
+{
+public:
+ unbounded_fifo();
+
+ void deactivate();
+
+ bool empty();
+
+ void put( T const& t);
+
+ bool take( boost::optional< T > & va);
+
+ bool try_take( boost::optional< T > & va);
+};
+
+[section:constructor `unbounded_fifo()`]
+
+ unbounded_fifo();
+
+[variablelist
+[[Effects:] [Constructs an object of class `unbounded_fifo`.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:deactivate `void deactivate()`]
+
+ void deactivate();
+
+[variablelist
+[[Effects:] [Deactivates the fifo. No values can be put after calling `this->deactivate`. Fibers blocked in
+`this->take()` will be return.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:empty `bool empty()`]
+
+ bool empty();
+
+[variablelist
+[[Effects:] [Returns `true` if the fifo currently contains no data.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:put `void put( T const& t)`]
+
+ void put( T const& t);
+
+[variablelist
+[[Effects:] [Enqueues the value in the fifo and wakes up a fiber waiting for new data available from the
+fifo.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:take `bool take( boost::optional< T > & va)`]
+
+ bool take( boost::optional< T > & va);
+
+[variablelist
+[[Effects:] [Dequeues a value from the fifo. If no data is available from the fifo the fiber gets suspended until
+new data are enqueued (return value `true` and va contains dequeued value) or the fifo gets deactiveted and
+the function returns `false`.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:try_take `bool try_take( boost::optional< T > & va)`]
+
+ bool try_take( boost::optional< T > & va);
+
+[variablelist
+[[Effects:] [Dequeues a value from the fifo. If no data is available from the fifo the function returns `false`.
+Otherwise it returns `true` and `va` contains the dequed value.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[endsect]
+
+
+[section:bounded_fifo Template `bounded_fifo`]
+
+ #include <boost/fiber/bounded_fifo.hpp>
+
+template< typename T >
+class bounded_fifo : private noncopyable
+{
+public:
+ unbounded_fifo( std::size_t wm);
+
+ unbounded_fifo( std::size_t hwm, std::size_t lwm);
+
+ void deactivate();
+
+ bool empty();
+
+ void put( T const& t);
+
+ bool take( boost::optional< T > & va);
+
+ bool try_take( boost::optional< T > & va);
+};
+
+[section:constructor `bounded_fifo()`]
+
+ bounded_fifo( std::size_t wm);
+
+[variablelist
+[[Effects:] [Constructs an object of class `bounded_fifo` which will contain a maximum of `wm` items.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:deactivate `void deactivate()`]
+
+ void deactivate();
+
+[variablelist
+[[Effects:] [Deactivates the fifo. No values can be put after calling `this->deactivate`. Fibers blocked in
+`this->take()` will be return.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:empty `bool empty()`]
+
+ bool empty();
+
+[variablelist
+[[Effects:] [Returns `true` if the fifo currently contains no data.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:put `void put( T const& t)`]
+
+ void put( T const& t);
+
+[variablelist
+[[Effects:] [Enqueues the value in the fifo and wakes up a fiber waiting for new data available from the
+fifo. If the watermark has reached the fiber putting the value will be supended until at least one item
+was dequeued.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:take `bool take( boost::optional< T > & va)`]
+
+ bool take( boost::optional< T > & va);
+
+[variablelist
+[[Effects:] [Dequeues a value from the fifo. If no data is available from the fifo the fiber gets suspended until
+new data are enqueued (return value `true` and va contains dequeued value) or the fifo gets deactiveted and
+the function returns `false`.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:try_take `bool try_take( boost::optional< T > & va)`]
+
+ bool try_take( boost::optional< T > & va);
+
+[variablelist
+[[Effects:] [Dequeues a value from the fifo. If no data is available from the fifo the function returns `false`.
+Otherwise it returns `true` and `va` contains the dequed value.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[endsect]
+
+[endsect]

Added: sandbox/fiber/libs/fiber/doc/lockables.qbk
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/doc/lockables.qbk 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,280 @@
+[/
+ (C) Copyright 2007-8 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).
+]
+
+[section:mutex_concepts Mutex Concepts]
+
+A mutex object facilitates protection against data races and allows synchronization of data between fibers. A fiber
+obtains ownership of a mutex object by calling one of the lock functions and relinquishes ownership by calling the
+corresponding unlock function.
+
+__boost_fiber__ supports one basic concept for lockable objects: __lockable_concept_type__.
+
+[section:lockable `Lockable` Concept]
+
+The __lockable_concept__ models exclusive ownership. A type that implements the __lockable_concept__ shall provide
+the following member functions:
+
+* [lock_ref_link `void lock();`]
+* [try_lock_ref_link `bool try_lock();`]
+* [unlock_ref_link `void unlock();`]
+
+Lock ownership acquired through a call to __lock_ref__ or __try_lock_ref__ must be released through a call to
+__unlock_ref__.
+
+[section:lock `void lock()`]
+[variablelist
+[[Effects:] [The current fiber blocks until ownership can be obtained for the current fiber.]]
+[[Postcondition:] [The current fiber owns `*this`.]]
+[[Throws:] [__lock_error__ if an error occurs.]]
+]
+[endsect]
+
+[section:try_lock `bool try_lock()`]
+[variablelist
+[[Effects:] [Attempt to obtain ownership for the current fiber without blocking.]]
+[[Returns:] [`true` if ownership was obtained for the current fiber, `false` otherwise.]]
+[[Postcondition:] [If the call returns `true`, the current fiber owns the `*this`.]]
+[[Throws:] [__lock_error__ if an error occurs.]]
+]
+[endsect]
+
+[section:unlock `void unlock()`]
+[variablelist
+[[Precondition:] [The current fiber owns `*this`.]]
+[[Effects:] [Releases ownership by the current fiber.]]
+[[Postcondition:] [The current fiber no longer owns `*this`.]]
+[[Throws:] [Nothing]]
+]
+[endsect]
+
+[endsect]
+
+
+[section:locks Lock Types]
+
+[section:lock_guard Class template `lock_guard`]
+
+ #include <boost/fiber/locks.hpp>
+
+ template< typename Lockable >
+ class lock_guard
+ {
+ public:
+ explicit lock_guard( Lockable & m_);
+ lock_guard( Lockable & m_, boost::adopt_lock_t);
+
+ ~lock_guard();
+ };
+
+__lock_guard__ is very simple: on construction it
+acquires ownership of the implementation of the __lockable_concept__ supplied as
+the constructor parameter. On destruction, the ownership is released. This
+provides simple RAII-style locking of a __lockable_concept_type__ object, to facilitate exception-safe
+locking and unlocking. In addition, the [link
+fiber.synchronization.locks.lock_guard.constructor_adopt `lock_guard( Lockable &
+m, boost::adopt_lock_t)` constructor] allows the __lock_guard__ object to
+take ownership of a lock already held by the current fiber.
+
+[section:constructor `lock_guard( Lockable & m)`]
+[variablelist
+[[Effects:] [Stores a reference to `m`. Invokes [lock_ref_link `m.lock()`].]]
+[[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
+]
+[endsect]
+
+[section:constructor_adopt `lock_guard( Lockable & m, boost::adopt_lock_t)`]
+[variablelist
+[[Precondition:] [The current fiber owns a lock on `m` equivalent to one
+obtained by a call to [lock_ref_link `m.lock()`].]]
+[[Effects:] [Stores a reference to `m`. Takes ownership of the lock state of
+`m`.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:destructor `~lock_guard()`]
+[variablelist
+[[Effects:] [Invokes [unlock_ref_link `m.unlock()`] on the __lockable_concept_type__
+object passed to the constructor.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[endsect]
+
+
+[section:unique_lock Class template `unique_lock`]
+
+ #include <boost/fiber/locks.hpp>
+
+ template< typename Lockable >
+ class unique_lock
+ {
+ public:
+ unique_lock();
+ explicit unique_lock( Lockable & m_);
+ unique_lock( Lockable & m_, adopt_lock_t);
+ unique_lock( Lockable & m_, defer_lock_t);
+ unique_lock( Lockable & m_, try_to_lock_t);
+ unique_lock( Lockable & m_, system_time const& target_time);
+
+ ~unique_lock();
+
+ unique_lock( detail::fiber_move_t< unique_lock< Lockable > > other);
+ unique_lock( detail::fiber_move_t< upgrade_lock< Lockable > > other);
+
+ operator detail::fiber_move_t< unique_lock< Lockable > >();
+ detail::fiber_move_t< unique_lock< Lockable > > move();
+ unique_lock& operator=( detail::fiber_move_t< unique_lock< Lockable > > other);
+ unique_lock& operator=( detail::fiber_move_t< upgrade_lock< Lockable > > other);
+
+ void swap( unique_lock & other);
+ void swap( detail::fiber_move_t< unique_lock< Lockable > > other);
+
+ void lock();
+ bool try_lock();
+
+ void unlock();
+
+ bool owns_lock() const;
+ operator ``['unspecified-bool-type]``() const;
+ bool operator!() const;
+
+ Lockable * mutex() const;
+ Lockable * release();
+ };
+
+__unique_lock__ is more complex than __lock_guard__: not only does it provide for RAII-style locking, it also allows
+for deferring acquiring the lock until the __lock_ref__ member function is called explicitly, or trying to acquire
+the lock in a non-blocking fashion, or with a timeout. Consequently, __unlock_ref__ is only called in the destructor
+if the lock object has locked the __lockable_concept_type__ object, or otherwise adopted a lock on the
+__lockable_concept_type__ object.
+
+Specializations of __unique_lock__ model the __timed_lockable_concept__ if the supplied __lockable_concept_type__
+type itself models __timed_lockable_concept__ (e.g. `boost::unique_lock<boost::timed_mutex>`), or the
+__lockable_concept__ otherwise (e.g. `boost::unique_lock<boost::mutex>`).
+
+An instance of __unique_lock__ is said to ['own] the lock state of a __lockable_concept_type__ `m` if
+__mutex_func_ref__ returns a pointer to `m` and __owns_lock_ref__ returns `true`. If an object that ['owns] the lock
+state of a __lockable_concept_type__ object is destroyed, then the destructor will invoke [unlock_ref_link
+`mutex()->unlock()`].
+
+The member functions of __unique_lock__ are not fiber-safe. In particular, __unique_lock__ is intended to model the
+ownership of a __lockable_concept_type__ object by a particular fiber, and the member functions that release
+ownership of the lock state (including the destructor) must be called by the same fiber that acquired ownership of
+the lock state.
+
+[section:defaultconstructor `unique_lock()`]
+
+[variablelist
+[[Effects:] [Creates a lock object with no associated mutex.]]
+[[Postcondition:] [__owns_lock_ref__ returns `false`. __mutex_func_ref__ returns `NULL`.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:constructor `unique_lock(Lockable & m)`]
+
+[variablelist
+[[Effects:] [Stores a reference to `m`. Invokes [lock_ref_link `m.lock()`].]]
+[[Postcondition:] [__owns_lock_ref__ returns `true`. __mutex_func_ref__ returns `&m`.]]
+[[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
+]
+[endsect]
+
+[section:constructor_adopt `unique_lock(Lockable & m,boost::adopt_lock_t)`]
+
+[variablelist
+[[Precondition:] [The current fiber owns an exclusive lock on `m`.]]
+[[Effects:] [Stores a reference to `m`. Takes ownership of the lock state of `m`.]]
+[[Postcondition:] [__owns_lock_ref__ returns `true`. __mutex_func_ref__ returns `&m`.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:constructor_defer `unique_lock(Lockable & m,boost::defer_lock_t)`]
+
+[variablelist
+[[Effects:] [Stores a reference to `m`.]]
+[[Postcondition:] [__owns_lock_ref__ returns `false`. __mutex_func_ref__ returns `&m`.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:constructor_try `unique_lock(Lockable & m,boost::try_to_lock_t)`]
+
+[variablelist
+[[Effects:] [Stores a reference to `m`. Invokes [try_lock_ref_link
+`m.try_lock()`], and takes ownership of the lock state if the call returns
+`true`.]]
+[[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __try_lock_ref__
+returned `true`, then __owns_lock_ref__ returns `true`, otherwise __owns_lock_ref__
+returns `false`.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:destructor `~unique_lock()`]
+
+[variablelist
+[[Effects:] [Invokes __mutex_func_ref__`->`[unlock_ref_link `unlock()`] if
+__owns_lock_ref__ returns `true`.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:owns_lock `bool owns_lock() const`]
+
+[variablelist
+[[Returns:] [`true` if the `*this` owns the lock on the __lockable_concept_type__
+object associated with `*this`.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:mutex `Lockable* mutex() const`]
+
+[variablelist
+[[Returns:] [A pointer to the __lockable_concept_type__ object associated with
+`*this`, or `NULL` if there is no such object.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:bool_conversion `operator unspecified-bool-type() const`]
+
+[variablelist
+[[Returns:] [If __owns_lock_ref__ would return `true`, a value that evaluates to
+`true` in boolean contexts, otherwise a value that evaluates to `false` in
+boolean contexts.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:operator_not `bool operator!() const`]
+
+[variablelist
+[[Returns:] [`!` __owns_lock_ref__.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:release `Lockable* release()`]
+
+[variablelist
+[[Effects:] [The association between `*this` and the __lockable_concept_type__ object is removed, without affecting
+the lock state of the __lockable_concept_type__ object. If __owns_lock_ref__ would have returned `true`, it is the
+responsibility of the calling code to ensure that the __lockable_concept_type__ is correctly unlocked.]]
+[[Returns:] [A pointer to the __lockable_concept_type__ object associated with `*this` at the point of the call, or
+`NULL` if there is no such object.]]
+[[Throws:] [Nothing.]]
+[[Postcondition:] [`*this` is no longer associated with any __lockable_concept_type__ object. __mutex_func_ref__
+returns `NULL` and __owns_lock_ref__ returns `false`.]]
+]
+[endsect]
+
+[endsect]

Added: sandbox/fiber/libs/fiber/doc/mutexes.qbk
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/doc/mutexes.qbk 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,33 @@
+[/
+ (C) Copyright 2007-8 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).
+]
+
+[section:mutex_types Mutex Types]
+
+[section:mutex Class `mutex`]
+
+ #include <boost/fibers/mutex.hpp>
+
+ class mutex : private boost::noncopyable
+ {
+ public:
+ mutex();
+ ~mutex();
+
+ void lock();
+ bool try_lock();
+ void unlock();
+
+ typedef unique_lock<mutex> scoped_lock;
+ };
+
+__mutex__ implements the __lockable_concept__ to provide an exclusive-ownership mutex. At most one fiber can own the
+lock on a given instance of __mutex__ at any time. Multiple concurrent calls to __lock_ref__, __try_lock_ref__ and
+__unlock_ref__ shall be permitted.
+
+[endsect]
+
+[endsect]

Added: sandbox/fiber/libs/fiber/doc/overview.qbk
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/doc/overview.qbk 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,60 @@
+[/
+ (C) Copyright 2007-8 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).
+]
+
+[section:overview Overview]
+
+__boost_fiber__ provides an framework utilizing lightweight threads of execution also known
+as user-level/user-space threads or fibers (Win32 API). The API of the library is
+modeled after __boost_thread__ and contains classes, functions to manage fibers and to synchronize
+data between the fibers.
+
+A fiber owns a user-space stack, a context (processor register state) and is a lighter scheduling
+item which is scheduled cooperatively (threads are preemptively scheduled) - the running fiber
+decides explicitly when its yields to allow another fiber to run (fiber switching).
+Fibers are less expensive than threads because the kernel doesn't know anything about fibers -
+no kernel transitions are required for scheduling (done in the user-space). A context switch
+between threads costs usally thousends of CPU cycles on x86 compared to a fiber switch with few
+hundreds of cycles.
+A fiber can only run on a single thread at any point in time but may be migrated between threads.
+Because a thread can run many different fibers during its life cycle the name __fiber__ was choosen.
+
+Beside fibers conceptualy equivalent constructs are coroutines. A coroutine can be seen as a
+language-level construct while a fiber is a system-level construct.
+
+In order to use the classes and functions described here, you can either include the specific
+headers specified by the descriptions of each class or function, or include the master library
+header:
+
+ #include <boost/fiber.hpp>
+
+which includes all the other headers in turn. The classes and functions reside in namespaces
+`boost::fibers` and `boost::this_fiber`.
+
+[warning This library is NOT an official Boost library]
+
+[note Please note that __boost_fiber__ is not optimized yet.]
+
+
+[heading Tested Platforms]
+
+__boost_fiber__ has been tested on the following platforms and compilers:
+
+* Debian GNU/Linux 2.6.31.6 (x86_64), GCC 4.3.4
+* Ubuntu GNU/Linux 2.6.28.11 (x86), GCC 4.3.3
+* FreeBSD 7.2 (x86), GCC 4.2.1
+* OpenSolaris 2009.06 (x86_64), GCC 4.3.2
+* Windows XP Professional (x86), MSVC 9.0
+
+
+[heading How to build and install]
+
+* download the sources from
+[@http://www.boost-consulting.com/vault/index.php?directory=Concurrent%20Programming Boost Vault]
+* extract the archive into the boost-source directory
+* call [''bjam toolset=<compiler-name> --with-fiber install'] in order to build and install the library
+
+[endsect]

Added: sandbox/fiber/libs/fiber/doc/scheduler.qbk
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/doc/scheduler.qbk 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,123 @@
+[/
+ 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
+
+ Based on documentation from Boost.Thread.
+]
+
+[section:scheduler_ref Scheduler]
+
+[heading Synopsis]
+
+The class `scheduler` is responsible for managing and scheduling of fibers passed to it. The fibers are
+thread-affine, e.g. the fibers remain local for the thread passing the fiber to the scheduler.
+(Maybe futher version of __boost_fiber__ will support explicit migration of fibers between threads.)
+
+Usally `scheduler` will be invoked until all fibers have finished.
+
+ boost::fibers::scheduler sched;
+
+ sched.make_fiber( some_fn);
+
+ for (;;)
+ {
+ while ( sched.run() );
+ if ( sched.empty() ) break;
+ }
+
+
+[section:scheduler Class `scheduler`]
+
+ #include <boost/fiber/scheduler.hpp>
+
+ class scheduler
+ {
+ public:
+ bool run();
+
+ bool empty();
+
+ std::size_t size();
+
+ void submit_fiber( fiber);
+
+ template< typename Fn >
+ void make_fiber( Fn fn);
+
+ template< typename Fn >
+ void make_fiber( std::size_t stack_size, Fn fn);
+
+ template< typename Fn, typename A1, typename A2,... >
+ void make_fiber( Fn fn, A0 a0, A1 a1,...);
+
+ template< typename Fn, typename A1, typename A2,... >
+ void make_fiber( std::size_t stack_size, Fn fn, A1 a1, A2 a2,...);
+ };
+
+
+[section:run `run()`]
+
+ bool run();
+
+[variablelist
+[[Effects:] [Executes a fiber from the internal storage and removes terminated fibers. The fnction returns
+`true` if a fiber could be executed or a terminated fiber could be removed - otherwise `false`.]]
+[[Throws:] [__system_error__ if a system call failed.]]
+]
+[endsect]
+
+[section:empty `empty()`]
+
+ bool empty();
+
+[variablelist
+[[Effects:] [Returns `true` if the scheduler contains fibers (maybe runnable or waiting).]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:size `size()`]
+
+ std::size_t size();
+
+[variablelist
+[[Effects:] [Returns how many fibers the scheduler contains (maybe runnable or waiting).]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:submit_fiber `submit_fiber( fiber f)`]
+
+ void submit_fiber( fiber f);
+
+[variablelist
+[[Effects:] [This function stores the passed fiber in the scheduler.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:make_fiber `make_fiber()`]
+
+ template< typename Fn >
+ void make_fiber( Fn fn);
+
+ template< typename Fn >
+ void make_fiber( std::size_t stack_size, Fn fn);
+
+ template< typename Fn, typename A1, typename A2,... >
+ void make_fiber( Fn fn, A0 a0, A1 a1,...);
+
+ template< typename Fn, typename A1, typename A2,... >
+ void make_fiber( std::size_t stack_size, Fn fn, A1 a1, A2 a2,...);
+
+[variablelist
+[[Effects:] [The functionscreate a fiber which gets stored in the internal structures from scheduler.]]
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[endsect]
+
+[endsect]

Added: sandbox/fiber/libs/fiber/doc/todo.qbk
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/doc/todo.qbk 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,24 @@
+[/
+ 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
+
+ Based on documentation from Boost.Thread.
+]
+
+[section:todo Todo]
+
+* replace spin-waiting in condition- and event-variables
+
+* improve implementation of atomic-ops
+
+* replace system calls related to fiber switching (like swapcontext()) by assembler
+
+* explicit migraton of fiber between schedulers (that measn threads)
+
+* improve scheduling algorithm (take priorities into acount)
+
+* provide a spin-wait class
+
+[endsect]

Modified: sandbox/fiber/libs/fiber/examples/Jamfile.v2
==============================================================================
--- sandbox/fiber/libs/fiber/examples/Jamfile.v2 (original)
+++ sandbox/fiber/libs/fiber/examples/Jamfile.v2 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -24,7 +24,6 @@
     ;
 
 exe at_exit : at_exit.cpp ;
-exe suspend : suspend.cpp ;
 exe join : join.cpp ;
 exe interrupt : interrupt.cpp ;
 exe cancel : cancel.cpp ;

Modified: sandbox/fiber/libs/fiber/examples/interrupt.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/examples/interrupt.cpp (original)
+++ sandbox/fiber/libs/fiber/examples/interrupt.cpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -41,7 +41,7 @@
         {
                 ++value3;
                 std::cout << "fn_3() increment value3 " << value3 << std::endl;
- boost::fibers::restore_interruption restored;
+ boost::fibers::restore_interruption restored( disabled);
                 boost::this_fiber::interruption_point();
                 boost::this_fiber::yield();
         }

Deleted: sandbox/fiber/libs/fiber/examples/suspend.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/examples/suspend.cpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
+++ (empty file)
@@ -1,72 +0,0 @@
-#include <cstdlib>
-#include <iostream>
-#include <string>
-
-#include <boost/bind.hpp>
-#include <boost/system/system_error.hpp>
-
-#include <boost/fiber.hpp>
-
-int value1 = 0;
-int value2 = 0;
-
-void fn_1()
-{
- for ( int i = 0; i < 5; ++i)
- {
- ++value1;
- std::cout << "fn_1() increment value1 " << value1 << std::endl;
- if ( i == 1)
- {
- std::cout << "fiber suspends itself " << boost::this_fiber::get_id() << std::endl;
- boost::this_fiber::suspend();
- }
- boost::this_fiber::yield();
- }
-}
-
-void fn_2( boost::fiber f)
-{
- for ( int i = 0; i < 5; ++i)
- {
- ++value2;
- std::cout << "fn_2() increment value2 " << value2 << std::endl;
- boost::this_fiber::yield();
- }
- std::cout << "fn_2() resume fiber " << f.get_id() << std::endl;
- f.resume();
-}
-
-int main()
-{
- try
- {
- boost::fibers::scheduler sched;
-
- boost::fiber f( fn_1);
- sched.submit_fiber( f);
- sched.make_fiber( fn_2, f);
-
- std::cout << "start" << std::endl;
- std::cout << "fiber to be suspended " << f.get_id() << std::endl;
-
- for (;;)
- {
- while ( sched.run() );
- if ( sched.empty() ) break;
- }
-
- std::cout << "finish: value1 == " << value1 << ", value2 == " << value2 << std::endl;
-
- return EXIT_SUCCESS;
- }
- catch ( boost::system::system_error const& e)
- { std::cerr << "system_error: " << e.code().value() << std::endl; }
- catch ( boost::fibers::scheduler_error const& e)
- { std::cerr << "scheduler_error: " << e.what() << std::endl; }
- catch ( std::exception const& e)
- { std::cerr << "exception: " << e.what() << std::endl; }
- catch (...)
- { std::cerr << "unhandled exception" << std::endl; }
- return EXIT_FAILURE;
-}

Modified: sandbox/fiber/libs/fiber/src/auto_reset_event.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/auto_reset_event.cpp (original)
+++ sandbox/fiber/libs/fiber/src/auto_reset_event.cpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -31,7 +31,9 @@
                         & state_, & expected,
                         static_cast< uint32_t >( RESET) ) )
         {
+ this_fiber::interruption_point();
                 this_fiber::yield();
+ this_fiber::interruption_point();
                 expected = static_cast< uint32_t >( SET);
         }
 }
@@ -46,6 +48,8 @@
                         & state_, & expected,
                         static_cast< uint32_t >( RESET) ) )
         {
+ this_fiber::interruption_point();
+ this_fiber::interruption_point();
                 this_fiber::yield();
         
                 if ( get_system_time() >= abs_time) return false;

Modified: sandbox/fiber/libs/fiber/src/condition.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/condition.cpp (original)
+++ sandbox/fiber/libs/fiber/src/condition.cpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -164,6 +164,9 @@
         check_mtx_()
 {}
 
+condition::~condition()
+{}
+
 void
 condition::notify_one()
 { notify_( static_cast< uint32_t >( NOTIFY_ONE) ); }

Modified: sandbox/fiber/libs/fiber/src/count_down_event.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/count_down_event.cpp (original)
+++ sandbox/fiber/libs/fiber/src/count_down_event.cpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -47,7 +47,11 @@
 count_down_event::wait()
 {
         while ( 0 != detail::atomic_load( & current_) )
+ {
+ this_fiber::interruption_point();
                 this_fiber::yield();
+ this_fiber::interruption_point();
+ }
 }
 
 bool
@@ -57,7 +61,9 @@
 
         while ( 0 < detail::atomic_load( & current_) )
         {
+ this_fiber::interruption_point();
                 this_fiber::yield();
+ this_fiber::interruption_point();
 
                 if ( get_system_time() >= abs_time) return false;
         }

Modified: sandbox/fiber/libs/fiber/src/fiber.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/fiber.cpp (original)
+++ sandbox/fiber/libs/fiber/src/fiber.cpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -146,20 +146,6 @@
 }
 
 void
-fiber::suspend()
-{
- if ( ! info_base_) throw fiber_moved();
- scheduler::suspend( get_id() );
-}
-
-void
-fiber::resume()
-{
- if ( ! info_base_) throw fiber_moved();
- scheduler::resume( get_id() );
-}
-
-void
 fiber::join()
 {
         if ( ! info_base_) throw fiber_moved();

Modified: sandbox/fiber/libs/fiber/src/manual_reset_event.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/manual_reset_event.cpp (original)
+++ sandbox/fiber/libs/fiber/src/manual_reset_event.cpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -56,7 +56,11 @@
         }
 
         while ( static_cast< uint32_t >( RESET) == detail::atomic_load( & state_) )
+ {
+ this_fiber::interruption_point();
                 this_fiber::yield();
+ this_fiber::interruption_point();
+ }
 
         if ( 1 == detail::atomic_fetch_sub( & waiters_, 1) )
                 enter_mtx_.unlock();
@@ -69,7 +73,9 @@
 
         while ( static_cast< uint32_t >( RESET) == detail::atomic_load( & state_) )
         {
+ this_fiber::interruption_point();
                 this_fiber::yield();
+ this_fiber::interruption_point();
         
                 if ( get_system_time() >= abs_time) return false;
         }

Added: sandbox/fiber/libs/fiber/src/round_robin.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/src/round_robin.cpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -0,0 +1,426 @@
+
+// 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)
+
+#include <boost/fiber/detail/round_robin.hpp>
+
+#include <utility>
+
+#include <boost/assert.hpp>
+#include <boost/foreach.hpp>
+
+#include <boost/fiber/detail/fiber_info.hpp>
+#include <boost/fiber/detail/move.hpp>
+#include <boost/fiber/detail/fiber_state.hpp>
+#include <boost/fiber/exceptions.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fibers {
+namespace detail {
+
+#define HAS_STATE_MASTER( state) \
+ ( state & STATE_MASTER) != 0
+
+#define HAS_STATE_NOT_STARTED( state) \
+ ( state & STATE_NOT_STARTED) != 0
+
+#define HAS_STATE_READY( state) \
+ ( state & STATE_READY) != 0
+
+#define HAS_STATE_RUNNING( state) \
+ ( state & STATE_RUNNING) != 0
+
+#define HAS_STATE_WAIT_FOR_JOIN( state) \
+ ( state & STATE_WAIT_FOR_JOIN) != 0
+
+#define HAS_STATE_TERMINATED( state) \
+ ( state & STATE_TERMINATED) != 0
+
+round_robin::round_robin() :
+ master_(),
+ active_(),
+ fibers_(),
+ runnable_fibers_(),
+ terminated_fibers_()
+{
+ fiber::convert_thread_to_fiber();
+ master_ = fiber(
+ fiber_info_base::ptr_t(
+ new fiber_info_default() ) );
+}
+
+round_robin::~round_robin()
+{ fiber::convert_fiber_to_thread(); }
+
+void
+round_robin::add( fiber const& f)
+{
+ if ( ! f) throw fiber_moved();
+
+ BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_()->state) );
+ BOOST_ASSERT( STATE_NOT_STARTED == f.info_()->state);
+
+ // set state to ready
+ f.info_()->state = STATE_READY;
+
+ // insert fiber to fiber-list
+ std::pair< std::map< fiber::id, schedulable >::iterator, bool > result(
+ fibers_.insert(
+ std::make_pair(
+ f.get_id(),
+ schedulable( f) ) ) );
+
+ // check result
+ if ( ! result.second) throw scheduler_error("inserting fiber failed");
+
+ // put fiber to runnable-queue
+ runnable_fibers_.push_back( result.first->first);
+}
+
+fiber::id
+round_robin::get_id() const
+{ return active_.get_id(); }
+
+void
+round_robin::yield()
+{
+ BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
+ BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
+
+ // set state ready
+ active_.info_()->state = STATE_READY;
+
+ // put fiber to runnable-queue
+ runnable_fibers_.push_back( active_.get_id() );
+
+ // switch to master-fiber
+ active_.switch_to_( master_);
+}
+
+void
+round_robin::cancel()
+{
+ BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
+ BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
+
+ schedulable s( fibers_[active_.get_id()]);
+
+ // invoke each fiber waiting on this fiber
+ BOOST_FOREACH( fiber::id id__, s.joining_fibers)
+ {
+ schedulable s__( fibers_[id__]);
+ fiber f__( s__.f);
+ BOOST_ASSERT( s__.waiting_on);
+ BOOST_ASSERT( active_.get_id() == * s__.waiting_on);
+ BOOST_ASSERT( HAS_STATE_WAIT_FOR_JOIN( f__.info_()->state) );
+
+ // clear waiting-on
+ fibers_[id__].waiting_on.reset();
+
+ // remove wait-for-join state
+ f__.info_()->state &= ~STATE_WAIT_FOR_JOIN;
+
+ // if fiber is in state ready or running
+ // put it on runnable-queue
+ if ( ( HAS_STATE_READY( f__.info_()->state) || HAS_STATE_RUNNING( f__.info_()->state) ) )
+ {
+ f__.info_()->state = STATE_READY;
+ runnable_fibers_.push_back( id__);
+ }
+ }
+ // clear waiting-queue
+ fibers_[active_.get_id()].joining_fibers.clear();
+
+ // set state to terminated
+ active_.info_()->state = STATE_TERMINATED;
+
+ // put fiber to terminated-queue
+ terminated_fibers_.push( active_.get_id() );
+
+ // switch to master-fiber
+ active_.switch_to_( master_);
+}
+
+void
+round_robin::interrupt()
+{
+ BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
+ BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
+
+ // gets invoked by interruption-points
+ // if interruption flag is set throw fiber_interrupted
+ // exceptions
+ if ( INTERRUPTION_ENABLED == active_.info_()->interrupt)
+ throw fiber_interrupted();
+}
+
+bool
+round_robin::interruption_requested() const
+{
+ BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
+ BOOST_ASSERT( ! fibers_.at( active_.get_id() ).waiting_on);
+
+ return active_.interruption_requested();
+}
+
+bool
+round_robin::interruption_enabled() const
+{
+ BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
+ BOOST_ASSERT( ! fibers_.at( active_.get_id() ).waiting_on);
+
+ return active_.info_()->interrupt == detail::INTERRUPTION_ENABLED;
+}
+
+fiber_interrupt_t &
+round_robin::interrupt_flags()
+{
+ BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
+ BOOST_ASSERT( ! fibers_.at( active_.get_id() ).waiting_on);
+
+ return active_.info_()->interrupt;
+}
+
+int
+round_robin::priority() const
+{
+ BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
+ BOOST_ASSERT( ! fibers_.at( active_.get_id() ).waiting_on);
+
+ return active_.priority();
+}
+
+void
+round_robin::priority( int prio)
+{
+ BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
+ BOOST_ASSERT( ! fibers_.at( active_.get_id() ).waiting_on);
+
+ // set priority
+ active_.priority( prio);
+}
+
+void
+round_robin::at_exit( callable_t ca)
+{
+ BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
+ BOOST_ASSERT( ! fibers_.at( active_.get_id() ).waiting_on);
+
+ // push a exit-callback on fibers stack
+ active_.info_()->at_exit.push( ca);
+}
+
+void
+round_robin::interrupt( fiber::id const& id)
+{
+ container::iterator i = fibers_.find( id);
+ if ( i == fibers_.end() ) return;
+ schedulable s( i->second);
+ fiber f( s.f);
+ BOOST_ASSERT( f);
+ BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_()->state) );
+ BOOST_ASSERT( ! HAS_STATE_NOT_STARTED( f.info_()->state) );
+
+ // nothing to do for al terminated fiber
+ if ( HAS_STATE_TERMINATED( f.info_()->state) ) return;
+
+ // remove disabled flag
+ f.info_()->interrupt &= ~detail::INTERRUPTION_DISABLED;
+
+ // set enabled flag
+ f.info_()->interrupt |= detail::INTERRUPTION_ENABLED;
+
+ // if fiber is waiting
+ if ( HAS_STATE_WAIT_FOR_JOIN( f.info_()->state) )
+ {
+ // fiber is waiting (joining) on another fiber
+ // remove it from the waiting-queue, reset waiting-on
+ // and reset the waiting state
+ BOOST_ASSERT( s.waiting_on);
+ fibers_[* s.waiting_on].joining_fibers.remove( id);
+ fibers_[id].waiting_on.reset();
+ f.info_()->interrupt &= ~STATE_WAIT_FOR_JOIN;
+
+ BOOST_ASSERT(
+ HAS_STATE_READY( f.info_()->state) ||
+ HAS_STATE_RUNNING( f.info_()->state) );
+ f.info_()->state = STATE_READY;
+ runnable_fibers_.push_back( id);
+ }
+}
+
+void
+round_robin::cancel( fiber::id const& id)
+{
+ container::iterator i = fibers_.find( id);
+ if ( i == fibers_.end() ) return;
+ schedulable s( i->second);
+ fiber f( s.f);
+ BOOST_ASSERT( f);
+ BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_()->state) );
+ BOOST_ASSERT( ! HAS_STATE_NOT_STARTED( f.info_()->state) );
+
+ // nothing to do for al terminated fiber
+ if ( HAS_STATE_TERMINATED( f.info_()->state) ) return;
+
+ // invoke each fiber waiting on this fiber
+ BOOST_FOREACH( fiber::id id__, s.joining_fibers)
+ {
+ schedulable s__( fibers_[id__]);
+ fiber f__( s__.f);
+ BOOST_ASSERT( s__.waiting_on);
+ BOOST_ASSERT( HAS_STATE_WAIT_FOR_JOIN( f__.info_()->state) );
+
+ // clear waiting-on
+ fibers_[id__].waiting_on.reset();
+
+ // remove wait-for-join state
+ f__.info_()->state &= ~STATE_WAIT_FOR_JOIN;
+
+ // if fiber is in state ready or running
+ // put it on runnable-queue
+ if ( ( HAS_STATE_READY( f__.info_()->state) || HAS_STATE_RUNNING( f__.info_()->state) ) )
+ {
+ f__.info_()->state = STATE_READY;
+ runnable_fibers_.push_back( id__);
+ }
+ }
+ // clear waiting-queue
+ fibers_[id].joining_fibers.clear();
+
+ // if fiber is ready remove it from the runnable-queue
+ // and put it to terminated-queue
+ if ( HAS_STATE_READY( f.info_()->state) )
+ {
+ f.info_()->state = STATE_TERMINATED;
+ runnable_fibers_.remove( id);
+ terminated_fibers_.push( id);
+ }
+ // if fiber is running (== active fiber)
+ // put it to terminated-queue and switch
+ // to master fiber
+ else if ( HAS_STATE_RUNNING( f.info_()->state) )
+ {
+ BOOST_ASSERT( active_.get_id() == id);
+ f.info_()->state = STATE_TERMINATED;
+ terminated_fibers_.push( id);
+ f.switch_to_( master_);
+ }
+ // if fiber is waiting then remove it from the
+ // waiting-queue and put it to terminated-queue
+ else if ( HAS_STATE_WAIT_FOR_JOIN( f.info_()->state) )
+ {
+ BOOST_ASSERT( s.waiting_on);
+ f.info_()->state = STATE_TERMINATED;
+ fibers_[* s.waiting_on].joining_fibers.remove( id);
+ terminated_fibers_.push( id);
+ }
+ else
+ BOOST_ASSERT( ! "should never reached");
+}
+
+void
+round_robin::join( fiber::id const& id)
+{
+ container::iterator i = fibers_.find( id);
+ if ( i == fibers_.end() ) return;
+ schedulable s( i->second);
+ fiber f( s.f);
+ BOOST_ASSERT( f);
+ BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_()->state) );
+ BOOST_ASSERT( ! HAS_STATE_NOT_STARTED( f.info_()->state) );
+
+ // nothing to do for a terminated fiber
+ if ( HAS_STATE_TERMINATED( f.info_()->state) ) return;
+
+ // prevent self-join
+ if ( active_.get_id() == id) throw scheduler_error("self-join denied");
+
+ // register on fiber to be joined
+ fibers_[id].joining_fibers.push_back( active_.get_id() );
+
+ // set state waiting
+ active_.info_()->state |= STATE_WAIT_FOR_JOIN;
+
+ // set fiber-id waiting-on
+ fibers_[active_.get_id()].waiting_on = id;
+
+ // switch to master-fiber
+ active_.switch_to_( master_);
+
+ // fiber was invoked
+ BOOST_ASSERT( ! HAS_STATE_WAIT_FOR_JOIN( active_.info_()->state) );
+ BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
+
+ // check if interruption was requested
+ interrupt();
+}
+
+void
+round_robin::reschedule( fiber::id const& id)
+{
+ container::iterator i = fibers_.find( id);
+ if ( i == fibers_.end() ) return;
+ fiber f( i->second.f);
+ BOOST_ASSERT( f);
+ BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_()->state) );
+ BOOST_ASSERT( ! HAS_STATE_NOT_STARTED( f.info_()->state) );
+ BOOST_ASSERT( ! HAS_STATE_TERMINATED( f.info_()->state) );
+
+ // TODO: re-schedule fiber == remove from
+ // runnable_fibers + re-insert
+}
+
+bool
+round_robin::run()
+{
+ bool result( false);
+ if ( ! runnable_fibers_.empty() )
+ {
+ schedulable s = fibers_[runnable_fibers_.front()];
+ active_ = s.f;
+ BOOST_ASSERT( ! s.waiting_on);
+ BOOST_ASSERT( active_.info_()->state == STATE_READY);
+ active_.info_()->state = STATE_RUNNING;
+ master_.switch_to_( active_);
+ runnable_fibers_.pop_front();
+ result = true;
+ }
+ else
+ active_.move();
+
+ while ( ! terminated_fibers_.empty() )
+ {
+ schedulable s = fibers_[terminated_fibers_.front()];
+ fiber f( s.f);
+ terminated_fibers_.pop();
+ BOOST_ASSERT( s.joining_fibers.empty() );
+ BOOST_ASSERT( STATE_TERMINATED == f.info_()->state);
+ fibers_.erase( f.get_id() );
+ result = true;
+ }
+ return result;
+}
+
+bool
+round_robin::empty() const
+{ return fibers_.empty(); }
+
+std::size_t
+round_robin::size() const
+{ return fibers_.size(); }
+
+#undef HAS_STATE_MASTER
+#undef HAS_STATE_NOT_STARTED
+#undef HAS_STATE_READY
+#undef HAS_STATE_RUNNING
+#undef HAS_STATE_WAIT_FOR_JOIN
+#undef HAS_STATE_TERMINATED
+
+}}}
+
+#include <boost/config/abi_suffix.hpp>

Modified: sandbox/fiber/libs/fiber/src/scheduler.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/scheduler.cpp (original)
+++ sandbox/fiber/libs/fiber/src/scheduler.cpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -7,7 +7,7 @@
 #include <boost/fiber/scheduler.hpp>
 
 #include <boost/fiber/detail/move.hpp>
-#include <boost/fiber/detail/strategy.hpp>
+#include <boost/fiber/detail/round_robin.hpp>
 #include <boost/fiber/exceptions.hpp>
 
 #include <boost/config/abi_prefix.hpp>
@@ -46,14 +46,6 @@
 }
 
 void
-scheduler::suspend()
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- impl->suspend();
-}
-
-void
 scheduler::interrupt()
 {
         detail::strategy * impl( impl_.get() );
@@ -126,22 +118,6 @@
 }
 
 void
-scheduler::suspend( fiber::id const& id)
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- impl->suspend( id);
-}
-
-void
-scheduler::resume( fiber::id const& id)
-{
- detail::strategy * impl( impl_.get() );
- if ( ! impl) throw fiber_error("not a fiber");
- impl->resume( id);
-}
-
-void
 scheduler::join( fiber::id const& id)
 {
         detail::strategy * impl( impl_.get() );
@@ -161,7 +137,7 @@
 scheduler::access_()
 {
         if ( ! impl_.get() )
- impl_.reset( new detail::strategy() );
+ impl_.reset( new detail::round_robin() );
         return impl_.get();
 }
 

Deleted: sandbox/fiber/libs/fiber/src/strategy.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/strategy.cpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
+++ (empty file)
@@ -1,517 +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)
-
-#include <boost/fiber/detail/strategy.hpp>
-
-#include <utility>
-
-#include <boost/assert.hpp>
-#include <boost/foreach.hpp>
-
-#include <boost/fiber/detail/fiber_info.hpp>
-#include <boost/fiber/detail/move.hpp>
-#include <boost/fiber/detail/fiber_state.hpp>
-#include <boost/fiber/exceptions.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-namespace boost {
-namespace fibers {
-namespace detail {
-
-#define HAS_STATE_MASTER( state) \
- ( state & STATE_MASTER) != 0
-
-#define HAS_STATE_NOT_STARTED( state) \
- ( state & STATE_NOT_STARTED) != 0
-
-#define HAS_STATE_READY( state) \
- ( state & STATE_READY) != 0
-
-#define HAS_STATE_RUNNING( state) \
- ( state & STATE_RUNNING) != 0
-
-#define HAS_STATE_SUSPENDED( state) \
- ( state & STATE_SUSPENDED) != 0
-
-#define HAS_STATE_WAIT_FOR_JOIN( state) \
- ( state & STATE_WAIT_FOR_JOIN) != 0
-
-#define HAS_STATE_TERMINATED( state) \
- ( state & STATE_TERMINATED) != 0
-
-strategy::strategy() :
- master_(),
- active_(),
- fibers_(),
- runnable_fibers_(),
- terminated_fibers_()
-{
- fiber::convert_thread_to_fiber();
- master_ = fiber(
- fiber_info_base::ptr_t(
- new fiber_info_default() ) );
-}
-
-strategy::~strategy()
-{ fiber::convert_fiber_to_thread(); }
-
-void
-strategy::add( fiber f)
-{
- if ( ! f) throw fiber_moved();
-
- BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_()->state) );
- BOOST_ASSERT( STATE_NOT_STARTED == f.info_()->state);
-
- // set state to ready
- f.info_()->state = STATE_READY;
-
- // insert fiber to fiber-list
- std::pair< std::map< fiber::id, schedulable >::iterator, bool > result(
- fibers_.insert(
- std::make_pair(
- f.get_id(),
- schedulable( f) ) ) );
-
- // check result
- if ( ! result.second) throw scheduler_error("inserting fiber failed");
-
- // put fiber to runnable-queue
- runnable_fibers_.push_back( result.first->first);
-}
-
-fiber::id
-strategy::get_id() const
-{ return active_.get_id(); }
-
-void
-strategy::yield()
-{
- BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- // set state ready
- active_.info_()->state = STATE_READY;
-
- // put fiber to runnable-queue
- runnable_fibers_.push_back( active_.get_id() );
-
- // switch to master-fiber
- active_.switch_to_( master_);
-}
-
-void
-strategy::cancel()
-{
- BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- schedulable s( fibers_[active_.get_id()]);
-
- // invoke each fiber waiting on this fiber
- BOOST_FOREACH( fiber::id id__, s.joining_fibers)
- {
- schedulable s__( fibers_[id__]);
- fiber f__( s__.f);
- BOOST_ASSERT( s__.waiting_on);
- BOOST_ASSERT( active_.get_id() == * s__.waiting_on);
- BOOST_ASSERT( HAS_STATE_WAIT_FOR_JOIN( f__.info_()->state) );
-
- // clear waiting-on
- fibers_[id__].waiting_on.reset();
-
- // remove wait-for-join state
- f__.info_()->state &= ~STATE_WAIT_FOR_JOIN;
-
- // if fiber is in state ready or running and not suspended
- // put it on runnable-queue
- if ( ( HAS_STATE_READY( f__.info_()->state) || HAS_STATE_RUNNING( f__.info_()->state) )
- && ! HAS_STATE_SUSPENDED( f__.info_()->state) )
- {
- f__.info_()->state = STATE_READY;
- runnable_fibers_.push_back( id__);
- }
- }
- // clear waiting-queue
- fibers_[active_.get_id()].joining_fibers.clear();
-
- // set state to terminated
- active_.info_()->state = STATE_TERMINATED;
-
- // put fiber to terminated-queue
- terminated_fibers_.push( active_.get_id() );
-
- // switch to master-fiber
- active_.switch_to_( master_);
-}
-
-void
-strategy::suspend()
-{
- BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- // set state suspended
- active_.info_()->state |= STATE_SUSPENDED;
-
- // switch to master-fiber
- active_.switch_to_( master_);
-}
-
-void
-strategy::interrupt()
-{
- BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- // gets invoked by interruption-points
- // if interruption flag is set throw fiber_interrupted
- // exceptions
- if ( INTERRUPTION_ENABLED == active_.info_()->interrupt)
- throw fiber_interrupted();
-}
-
-bool
-strategy::interruption_requested()
-{
- BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- return active_.interruption_requested();
-}
-
-bool
-strategy::interruption_enabled()
-{
- BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- return active_.info_()->interrupt == detail::INTERRUPTION_ENABLED;
-}
-
-fiber_interrupt_t &
-strategy::interrupt_flags()
-{
- BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- return active_.info_()->interrupt;
-}
-
-int
-strategy::priority()
-{
- BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- return active_.priority();
-}
-
-void
-strategy::priority( int prio)
-{
- BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- // set priority
- active_.priority( prio);
-}
-
-void
-strategy::at_exit( callable_t ca)
-{
- BOOST_ASSERT( STATE_RUNNING == active_.info_()->state);
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- // push a exit-callback on fibers stack
- active_.info_()->at_exit.push( ca);
-}
-
-void
-strategy::interrupt( fiber::id const& id)
-{
- container::iterator i = fibers_.find( id);
- if ( i == fibers_.end() ) return;
- schedulable s( i->second);
- fiber f( s.f);
- BOOST_ASSERT( f);
- BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_()->state) );
- BOOST_ASSERT( ! HAS_STATE_NOT_STARTED( f.info_()->state) );
-
- // nothing to do for al terminated fiber
- if ( HAS_STATE_TERMINATED( f.info_()->state) ) return;
-
- // remove disabled flag
- f.info_()->interrupt &= ~detail::INTERRUPTION_DISABLED;
-
- // set enabled flag
- f.info_()->interrupt |= detail::INTERRUPTION_ENABLED;
-
- // if fiber is waiting
- if ( HAS_STATE_WAIT_FOR_JOIN( f.info_()->state) )
- {
- // fiber is waiting (joining) on another fiber
- // remove it from the waiting-queue, reset waiting-on
- // and reset the waiting state
- BOOST_ASSERT( s.waiting_on);
- fibers_[* s.waiting_on].joining_fibers.remove( id);
- fibers_[id].waiting_on.reset();
- f.info_()->interrupt &= ~STATE_WAIT_FOR_JOIN;
-
- // if fiber is not suspended put it to runnable-queue
- if ( ! HAS_STATE_SUSPENDED( f.info_()->state) )
- {
- BOOST_ASSERT(
- HAS_STATE_READY( f.info_()->state) ||
- HAS_STATE_RUNNING( f.info_()->state) );
- f.info_()->state = STATE_READY;
- runnable_fibers_.push_back( id);
- }
- }
-}
-
-void
-strategy::cancel( fiber::id const& id)
-{
- container::iterator i = fibers_.find( id);
- if ( i == fibers_.end() ) return;
- schedulable s( i->second);
- fiber f( s.f);
- BOOST_ASSERT( f);
- BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_()->state) );
- BOOST_ASSERT( ! HAS_STATE_NOT_STARTED( f.info_()->state) );
-
- // nothing to do for al terminated fiber
- if ( HAS_STATE_TERMINATED( f.info_()->state) ) return;
-
- // invoke each fiber waiting on this fiber
- BOOST_FOREACH( fiber::id id__, s.joining_fibers)
- {
- schedulable s__( fibers_[id__]);
- fiber f__( s__.f);
- BOOST_ASSERT( s__.waiting_on);
- BOOST_ASSERT( HAS_STATE_WAIT_FOR_JOIN( f__.info_()->state) );
-
- // clear waiting-on
- fibers_[id__].waiting_on.reset();
-
- // remove wait-for-join state
- f__.info_()->state &= ~STATE_WAIT_FOR_JOIN;
-
- // if fiber is in state ready or running and not suspended
- // put it on runnable-queue
- if ( ( HAS_STATE_READY( f__.info_()->state) || HAS_STATE_RUNNING( f__.info_()->state) )
- && ! HAS_STATE_SUSPENDED( f__.info_()->state) )
- {
- f__.info_()->state = STATE_READY;
- runnable_fibers_.push_back( id__);
- }
- }
- // clear waiting-queue
- fibers_[id].joining_fibers.clear();
-
- // if fiber is ready remove it from the runnable-queue
- // and put it to terminated-queue
- if ( HAS_STATE_READY( f.info_()->state) )
- {
- f.info_()->state = STATE_TERMINATED;
- runnable_fibers_.remove( id);
- terminated_fibers_.push( id);
- }
- // if fiber is running (== active fiber)
- // put it to terminated-queue and switch
- // to master fiber
- else if ( HAS_STATE_RUNNING( f.info_()->state) )
- {
- BOOST_ASSERT( active_.get_id() == id);
- f.info_()->state = STATE_TERMINATED;
- terminated_fibers_.push( id);
- f.switch_to_( master_);
- }
- // if fiber is waiting then remove it from the
- // waiting-queue and put it to terminated-queue
- else if ( HAS_STATE_WAIT_FOR_JOIN( f.info_()->state) )
- {
- BOOST_ASSERT( s.waiting_on);
- f.info_()->state = STATE_TERMINATED;
- fibers_[* s.waiting_on].joining_fibers.remove( id);
- terminated_fibers_.push( id);
- }
- // suspended state is only used with one of the
- // other states
- else
- BOOST_ASSERT( ! "should never reached");
-}
-
-void
-strategy::suspend( fiber::id const& id)
-{
- container::iterator i = fibers_.find( id);
- if ( i == fibers_.end() ) return;
- fiber f( i->second.f);
- BOOST_ASSERT( f);
- BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_()->state) );
- BOOST_ASSERT( ! HAS_STATE_NOT_STARTED( f.info_()->state) );
-
- // nothing to do for a terminated fiber
- if ( HAS_STATE_TERMINATED( f.info_()->state) ) return;
-
- // if fiber is ready remove it from the
- // runnable-queue
- if ( HAS_STATE_READY( f.info_()->state) )
- {
- f.info_()->state |= STATE_SUSPENDED;
- runnable_fibers_.remove( id);
- }
- // if fiber is running (== active fiber)
- // switch to master-fiber
- else if ( HAS_STATE_RUNNING( f.info_()->state) )
- {
- BOOST_ASSERT( active_.get_id() == id);
- f.info_()->state |= STATE_SUSPENDED;
- f.switch_to_( master_);
- }
- // if fiber is in waiting state mark it only
- // as suspended
- else if ( HAS_STATE_WAIT_FOR_JOIN( f.info_()->state) )
- f.info_()->state |= STATE_SUSPENDED;
- else
- BOOST_ASSERT( ! "should never reached");
-}
-
-void
-strategy::resume( fiber::id const& id)
-{
- container::iterator i = fibers_.find( id);
- if ( i == fibers_.end() ) return;
- fiber f( i->second.f);
- BOOST_ASSERT( f);
- BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_()->state) );
- BOOST_ASSERT( ! HAS_STATE_NOT_STARTED( f.info_()->state) );
-
- BOOST_ASSERT( active_.get_id() != id);
-
- // nothing to do for already terminated fiber
- if ( HAS_STATE_TERMINATED( f.info_()->state) ) return;
-
- // remove suspended state an requeue fiber
- if ( HAS_STATE_SUSPENDED( f.info_()->state) )
- {
- f.info_()->state &= ~STATE_SUSPENDED;
- // if suspended fiber was ready or running and not waiting
- // put it to the runnable-queue
- if ( ( HAS_STATE_READY( f.info_()->state) || HAS_STATE_RUNNING( f.info_()->state) )
- && ! HAS_STATE_WAIT_FOR_JOIN( f.info_()->state) )
- {
- f.info_()->state = STATE_READY;
- runnable_fibers_.push_back( id);
- }
- }
-}
-
-void
-strategy::join( fiber::id const& id)
-{
- container::iterator i = fibers_.find( id);
- if ( i == fibers_.end() ) return;
- schedulable s( i->second);
- fiber f( s.f);
- BOOST_ASSERT( f);
- BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_()->state) );
- BOOST_ASSERT( ! HAS_STATE_NOT_STARTED( f.info_()->state) );
-
- // nothing to do for a terminated fiber
- if ( HAS_STATE_TERMINATED( f.info_()->state) ) return;
-
- // prevent self-join
- if ( active_.get_id() == id) throw scheduler_error("self-join denied");
-
- // register on fiber to be joined
- fibers_[id].joining_fibers.push_back( active_.get_id() );
-
- // set state waiting
- active_.info_()->state |= STATE_WAIT_FOR_JOIN;
-
- // set fiber-id waiting-on
- fibers_[active_.get_id()].waiting_on = id;
-
- // switch to master-fiber
- active_.switch_to_( master_);
-
- // fiber was invoked
- BOOST_ASSERT( ! HAS_STATE_WAIT_FOR_JOIN( active_.info_()->state) );
- BOOST_ASSERT( ! fibers_[active_.get_id()].waiting_on);
-
- // check if interruption was requested
- interrupt();
-}
-
-void
-strategy::reschedule( fiber::id const& id)
-{
- container::iterator i = fibers_.find( id);
- if ( i == fibers_.end() ) return;
- fiber f( i->second.f);
- BOOST_ASSERT( f);
- BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_()->state) );
- BOOST_ASSERT( ! HAS_STATE_NOT_STARTED( f.info_()->state) );
- BOOST_ASSERT( ! HAS_STATE_TERMINATED( f.info_()->state) );
-
- // TODO: re-schedule fiber == remove from
- // runnable_fibers + re-insert
-}
-
-bool
-strategy::run()
-{
- bool result( false);
- if ( ! runnable_fibers_.empty() )
- {
- schedulable s = fibers_[runnable_fibers_.front()];
- active_ = s.f;
- BOOST_ASSERT( ! s.waiting_on);
- BOOST_ASSERT( active_.info_()->state == STATE_READY);
- active_.info_()->state = STATE_RUNNING;
- master_.switch_to_( active_);
- runnable_fibers_.pop_front();
- result = true;
- }
- else
- active_.move();
-
- while ( ! terminated_fibers_.empty() )
- {
- schedulable s = fibers_[terminated_fibers_.front()];
- fiber f( s.f);
- terminated_fibers_.pop();
- BOOST_ASSERT( s.joining_fibers.empty() );
- BOOST_ASSERT( STATE_TERMINATED == f.info_()->state);
- fibers_.erase( f.get_id() );
- result = true;
- }
- return result;
-}
-
-bool
-strategy::empty()
-{ return fibers_.empty(); }
-
-std::size_t
-strategy::size()
-{ return fibers_.size(); }
-
-#undef HAS_STATE_MASTER
-#undef HAS_STATE_NOT_STARTED
-#undef HAS_STATE_READY
-#undef HAS_STATE_RUNNING
-#undef HAS_STATE_SUSPENDED
-#undef HAS_STATE_WAIT_FOR_JOIN
-#undef HAS_STATE_TERMINATED
-
-}}}
-
-#include <boost/config/abi_suffix.hpp>

Modified: sandbox/fiber/libs/fiber/test/Jamfile.v2
==============================================================================
--- sandbox/fiber/libs/fiber/test/Jamfile.v2 (original)
+++ sandbox/fiber/libs/fiber/test/Jamfile.v2 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -29,7 +29,6 @@
     [ fiber-test test_scheduler ]
     [ fiber-test test_utility ]
     [ fiber-test test_cancel ]
- [ fiber-test test_suspended ]
     [ fiber-test test_priority ]
     [ fiber-test test_join ]
     [ fiber-test test_interrupt ]

Modified: sandbox/fiber/libs/fiber/test/test_interrupt.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/test/test_interrupt.cpp (original)
+++ sandbox/fiber/libs/fiber/test/test_interrupt.cpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
@@ -34,7 +34,7 @@
 
 void fn_2()
 {
- boost::fibers::disable_interruption disabled;
+ boost::fibers::disable_interruption disabler;
         if ( boost::this_fiber::interruption_enabled() )
                 throw std::logic_error("interruption enabled");
         for ( int i = 0; i < 5; ++i)
@@ -49,13 +49,13 @@
 {
         try
         {
- boost::fibers::disable_interruption disabled;
+ boost::fibers::disable_interruption disabler;
                 if ( boost::this_fiber::interruption_enabled() )
                         throw std::logic_error("interruption enabled");
                 for ( int i = 0; i < 5; ++i)
                 {
                         ++value1;
- boost::fibers::restore_interruption restored;
+ boost::fibers::restore_interruption restorer( disabler);
                         boost::this_fiber::interruption_point();
                         boost::this_fiber::yield();
                 }

Deleted: sandbox/fiber/libs/fiber/test/test_suspended.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/test/test_suspended.cpp 2009-11-20 18:42:02 EST (Fri, 20 Nov 2009)
+++ (empty file)
@@ -1,121 +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)
-
-#include <sstream>
-#include <string>
-
-#include <boost/test/unit_test.hpp>
-#include <boost/utility.hpp>
-
-#include <boost/fiber.hpp>
-
-int value1 = 0;
-int value2 = 0;
-
-void fn_1()
-{
- for ( int i = 0; i < 3; ++i)
- {
- ++value1;
- if ( i == 1) boost::this_fiber::suspend();
- boost::this_fiber::yield();
- }
-}
-
-void fn_2( boost::fiber f)
-{
- for ( int i = 0; i < 3; ++i)
- {
- ++value2;
- boost::this_fiber::yield();
- }
- f.resume();
-}
-
-void test_case_1()
-{
- value1 = 0;
- value2 = 0;
-
- boost::fibers::scheduler sched;
-
- boost::fiber f( fn_1);
- sched.submit_fiber( f);
- sched.make_fiber( fn_2, f);
-
- BOOST_CHECK_EQUAL( 0, value1);
- BOOST_CHECK_EQUAL( 0, value2);
-
- BOOST_CHECK( sched.run() );
- BOOST_CHECK( ! sched.empty() );
- BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
- BOOST_CHECK_EQUAL( 1, value1);
- BOOST_CHECK_EQUAL( 0, value2);
-
- BOOST_CHECK( sched.run() );
- BOOST_CHECK( ! sched.empty() );
- BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
- BOOST_CHECK_EQUAL( 1, value1);
- BOOST_CHECK_EQUAL( 1, value2);
-
- BOOST_CHECK( sched.run() );
- BOOST_CHECK( ! sched.empty() );
- BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
- BOOST_CHECK_EQUAL( 2, value1);
- BOOST_CHECK_EQUAL( 1, value2);
-
- BOOST_CHECK( sched.run() );
- BOOST_CHECK( ! sched.empty() );
- BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
- BOOST_CHECK_EQUAL( 2, value1);
- BOOST_CHECK_EQUAL( 2, value2);
-
- BOOST_CHECK( sched.run() );
- BOOST_CHECK( ! sched.empty() );
- BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
- BOOST_CHECK_EQUAL( 2, value1);
- BOOST_CHECK_EQUAL( 3, value2);
-
- BOOST_CHECK( sched.run() );
- BOOST_CHECK( ! sched.empty() );
- BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
- BOOST_CHECK_EQUAL( 2, value1);
- BOOST_CHECK_EQUAL( 3, value2);
-
- BOOST_CHECK( sched.run() );
- BOOST_CHECK( ! sched.empty() );
- BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
- BOOST_CHECK_EQUAL( 2, value1);
- BOOST_CHECK_EQUAL( 3, value2);
-
- BOOST_CHECK( sched.run() );
- BOOST_CHECK( ! sched.empty() );
- BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
- BOOST_CHECK_EQUAL( 3, value1);
- BOOST_CHECK_EQUAL( 3, value2);
-
- BOOST_CHECK( sched.run() );
- BOOST_CHECK( sched.empty() );
- BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() );
- BOOST_CHECK_EQUAL( 3, value1);
- BOOST_CHECK_EQUAL( 3, value2);
-
- BOOST_CHECK( ! sched.run() );
- BOOST_CHECK( sched.empty() );
- BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() );
- BOOST_CHECK_EQUAL( 3, value1);
- BOOST_CHECK_EQUAL( 3, value2);
-}
-
-boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
-{
- boost::unit_test::test_suite * test =
- BOOST_TEST_SUITE("Boost.Fiber: suspend test suite");
-
- test->add( BOOST_TEST_CASE( & test_case_1) );
-
- 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