Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r57711 - in sandbox/fiber: boost boost/fiber boost/fiber/detail libs/fiber/examples libs/fiber/src libs/fiber/test
From: oliver.kowalke_at_[hidden]
Date: 2009-11-16 15:51:57


Author: olli
Date: 2009-11-16 15:51:54 EST (Mon, 16 Nov 2009)
New Revision: 57711
URL: http://svn.boost.org/trac/boost/changeset/57711

Log:
- classes disable_interruption and restore_interruption added
- example for interruption added

Added:
   sandbox/fiber/boost/fiber/interruption.hpp (contents, props changed)
   sandbox/fiber/libs/fiber/examples/interrupt.cpp (contents, props changed)
Text files modified:
   sandbox/fiber/boost/fiber.hpp | 1
   sandbox/fiber/boost/fiber/detail/fiber_info_base_posix.hpp | 2
   sandbox/fiber/boost/fiber/detail/fiber_info_base_windows.hpp | 2
   sandbox/fiber/boost/fiber/detail/fiber_state.hpp | 11 +++
   sandbox/fiber/boost/fiber/detail/scheduler_impl.hpp | 12 +--
   sandbox/fiber/boost/fiber/fiber.hpp | 5 +
   sandbox/fiber/boost/fiber/scheduler.hpp | 23 +++++---
   sandbox/fiber/boost/fiber/utility.hpp | 12 ++-
   sandbox/fiber/libs/fiber/examples/Jamfile.v2 | 1
   sandbox/fiber/libs/fiber/src/fiber.cpp | 9 +-
   sandbox/fiber/libs/fiber/src/fiber_info_base_posix.cpp | 4
   sandbox/fiber/libs/fiber/src/fiber_info_base_windows.cpp | 4
   sandbox/fiber/libs/fiber/src/scheduler.cpp | 39 +++++++------
   sandbox/fiber/libs/fiber/src/scheduler_impl.cpp | 46 +++++----------
   sandbox/fiber/libs/fiber/test/test_interrupt.cpp | 112 +++++++++++++++++++++------------------
   15 files changed, 150 insertions(+), 133 deletions(-)

Modified: sandbox/fiber/boost/fiber.hpp
==============================================================================
--- sandbox/fiber/boost/fiber.hpp (original)
+++ sandbox/fiber/boost/fiber.hpp 2009-11-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -14,6 +14,7 @@
 #include <boost/fiber/count_down_event.hpp>
 #include <boost/fiber/exceptions.hpp>
 #include <boost/fiber/fiber.hpp>
+#include <boost/fiber/interruption.hpp>
 #include <boost/fiber/manual_reset_event.hpp>
 #include <boost/fiber/mutex.hpp>
 #include <boost/fiber/scheduler.hpp>

Modified: sandbox/fiber/boost/fiber/detail/fiber_info_base_posix.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/detail/fiber_info_base_posix.hpp (original)
+++ sandbox/fiber/boost/fiber/detail/fiber_info_base_posix.hpp 2009-11-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -36,7 +36,7 @@
         ::ucontext_t uctx;
         shared_array< char > uctx_stack;
         fiber_state_t state;
- bool interrupt;
+ fiber_interrupt_t interrupt;
 
         fiber_info_base();
 

Modified: sandbox/fiber/boost/fiber/detail/fiber_info_base_windows.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/detail/fiber_info_base_windows.hpp (original)
+++ sandbox/fiber/boost/fiber/detail/fiber_info_base_windows.hpp 2009-11-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -36,7 +36,7 @@
         attributes attrs;
         LPVOID uctx;
         fiber_state_t state;
- bool interrupt;
+ fiber_interrupt_t interrupt;
 
         fiber_info_base();
 

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-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -28,9 +28,16 @@
 
 #define IS_ALIVE_BIT_MASK 0x3C
 
-}}
+enum interrupt_t
+{
+ INTERRUPTION_DISABLED = 1 << 0,
+ INTERRUPTION_ENABLED = 1 << 1,
+ INTERRUPTION_BLOCKED = 1 << 2
+};
 
-}
+typedef char fiber_interrupt_t;
+
+}}}
 
 #include <boost/config/abi_suffix.hpp>
 

Modified: sandbox/fiber/boost/fiber/detail/scheduler_impl.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/detail/scheduler_impl.hpp (original)
+++ sandbox/fiber/boost/fiber/detail/scheduler_impl.hpp 2009-11-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -55,7 +55,7 @@
 
         void add_fiber( fiber);
 
- fiber::id active_fiber() const;
+ fiber const& active_fiber() const;
 
         void yield_active_fiber();
 
@@ -65,19 +65,17 @@
 
         void interrupt_active_fiber();
 
+ void priority_active_fiber( int);
+
         void cancel_fiber( fiber::id const&);
 
         void suspend_fiber( fiber::id const&);
 
         void resume_fiber( fiber::id const&);
 
- int priority( fiber::id const&);
-
- void priority( fiber::id const&, int);
-
- void re_schedule( fiber::id const&);
+ void reschedule_fiber( fiber::id const&);
 
- void join( fiber::id const&);
+ void join_fiber( fiber::id const&);
 
         bool run();
 

Modified: sandbox/fiber/boost/fiber/fiber.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/fiber.hpp (original)
+++ sandbox/fiber/boost/fiber/fiber.hpp 2009-11-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -31,10 +31,15 @@
 
 }
 
+class disable_interruption;
+class restore_interruption;
+
 class BOOST_FIBER_DECL fiber
 {
 private:
         friend class detail::scheduler_impl;
+ friend class disable_interruption;
+ friend class restore_interruption;
 
         struct dummy;
 

Added: sandbox/fiber/boost/fiber/interruption.hpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/boost/fiber/interruption.hpp 2009-11-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -0,0 +1,67 @@
+
+// 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_INTERRUPTION_H
+#define BOOST_FIBERS_INTERRUPTION_H
+
+#include <cstddef>
+
+#include <boost/utility.hpp>
+
+#include <boost/fiber/detail/config.hpp>
+#include <boost/fiber/detail/fiber_state.hpp>
+#include <boost/fiber/scheduler.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace fibers {
+
+class BOOST_FIBER_DECL disable_interruption : private noncopyable
+{
+private:
+ bool set_;
+
+public:
+ disable_interruption() :
+ set_( ( scheduler::active_fiber().info_->interrupt & detail::INTERRUPTION_BLOCKED) != 0)
+ {
+ if ( ! set_)
+ scheduler::active_fiber().info_->interrupt |= detail::INTERRUPTION_BLOCKED;
+ }
+
+ ~disable_interruption()
+ {
+ if ( ! set_)
+ scheduler::active_fiber().info_->interrupt &= ~detail::INTERRUPTION_BLOCKED;
+ }
+};
+
+class BOOST_FIBER_DECL restore_interruption : private noncopyable
+{
+private:
+ bool set_;
+
+public:
+ restore_interruption() :
+ set_( ( scheduler::active_fiber().info_->interrupt & detail::INTERRUPTION_BLOCKED) != 0)
+ {
+ if ( set_)
+ scheduler::active_fiber().info_->interrupt &= ~detail::INTERRUPTION_BLOCKED;
+ }
+
+ ~restore_interruption()
+ {
+ if ( set_)
+ scheduler::active_fiber().info_->interrupt |= detail::INTERRUPTION_BLOCKED;
+ }
+};
+
+}}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_FIBERS_INTERRUPTION_H

Modified: sandbox/fiber/boost/fiber/scheduler.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/scheduler.hpp (original)
+++ sandbox/fiber/boost/fiber/scheduler.hpp 2009-11-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -33,11 +33,15 @@
 int priority();
 void priority( int);
 void interruption_point();
+bool interruption_requested();
 
 }
 
 namespace fibers {
 
+class disable_interruption;
+class restore_interruption;
+
 class BOOST_FIBER_DECL scheduler : private noncopyable
 {
 private:
@@ -49,7 +53,10 @@
         friend int this_fiber::priority();
         friend void this_fiber::priority( int);
         friend void this_fiber::interruption_point();
+ friend bool this_fiber::interruption_requested();
         friend class fiber;
+ friend class disable_interruption;
+ friend class restore_interruption;
 
         typedef scoped_ptr< detail::scheduler_impl > impl_t;
 
@@ -57,7 +64,7 @@
 
         static bool runs_as_fiber();
 
- static fiber::id active_fiber();
+ static fiber const& active_fiber();
 
         static void yield_active_fiber();
 
@@ -65,21 +72,19 @@
 
         static void suspend_active_fiber();
 
+ static void interrupt_active_fiber();
+
+ static void priority_active_fiber( int);
+
         static void cancel_fiber( fiber::id const&);
 
         static void suspend_fiber( fiber::id const&);
 
         static void resume_fiber( fiber::id const&);
 
- static int priority( fiber::id const&);
-
- static void priority( fiber::id const&, int);
-
- static void re_schedule( fiber::id const&);
-
- static void join( fiber::id const&);
+ static void reschedule_fiber( fiber::id const&);
 
- static void interruption_point();
+ static void join_fiber( fiber::id const&);
 
 public:
         scheduler();

Modified: sandbox/fiber/boost/fiber/utility.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/utility.hpp (original)
+++ sandbox/fiber/boost/fiber/utility.hpp 2009-11-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -25,7 +25,7 @@
 
 inline
 fiber::id get_id()
-{ return fibers::scheduler::active_fiber(); }
+{ return fibers::scheduler::active_fiber().get_id(); }
 
 inline
 void yield()
@@ -41,15 +41,19 @@
 
 inline
 int priority()
-{ return fibers::scheduler::priority( get_id() ); }
+{ return fibers::scheduler::active_fiber().priority(); }
 
 inline
 void priority( int prio)
-{ fibers::scheduler::priority( get_id(), prio); }
+{ fibers::scheduler::priority_active_fiber( prio); }
 
 inline
 void interruption_point()
-{ fibers::scheduler::interruption_point(); }
+{ fibers::scheduler::interrupt_active_fiber(); }
+
+inline
+bool interruption_requested()
+{ return fibers::scheduler::active_fiber().interruption_requested(); }
 
 }}
 

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-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -25,6 +25,7 @@
 
 exe suspend : suspend.cpp ;
 exe join : join.cpp ;
+exe interrupt : interrupt.cpp ;
 exe cancel : cancel.cpp ;
 exe simple : simple.cpp ;
 exe ping_pong : ping_pong.cpp ;

Added: sandbox/fiber/libs/fiber/examples/interrupt.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/examples/interrupt.cpp 2009-11-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -0,0 +1,121 @@
+#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;
+int value3 = 0;
+
+void fn_1()
+{
+ for ( int i = 0; i < 10; ++i)
+ {
+ ++value1;
+ std::cout << "fn_1() increment value1 " << value1 << std::endl;
+ boost::this_fiber::interruption_point();
+ boost::this_fiber::yield();
+ }
+}
+
+void fn_2()
+{
+ boost::fibers::disable_interruption disabled;
+ for ( int i = 0; i < 10; ++i)
+ {
+ ++value2;
+ std::cout << "fn_2() increment value2 " << value2 << std::endl;
+ boost::this_fiber::interruption_point();
+ boost::this_fiber::yield();
+ }
+}
+
+void fn_3()
+{
+ boost::fibers::disable_interruption disabled;
+ for ( int i = 0; i < 10; ++i)
+ {
+ ++value3;
+ std::cout << "fn_3() increment value3 " << value3 << std::endl;
+ boost::fibers::restore_interruption restored;
+ boost::this_fiber::interruption_point();
+ boost::this_fiber::yield();
+ }
+}
+
+void fn_4( boost::fiber f)
+{
+ for ( int i = 0; i < 10; ++i)
+ {
+ if ( i == 1)
+ {
+ std::cout << "fn_4() interrupt fiber " << f.get_id() << std::endl;
+ f.interrupt();
+ break;
+ }
+ boost::this_fiber::yield();
+ }
+}
+
+int main()
+{
+ try
+ {
+ boost::fibers::scheduler sched;
+
+ boost::fiber f1( fn_1);
+ sched.submit_fiber( f1);
+ sched.make_fiber( fn_4, f1);
+
+ std::cout << "start: interrupt fn_1()" << std::endl;
+
+ for (;;)
+ {
+ while ( sched.run() );
+ if ( sched.empty() ) break;
+ }
+
+ std::cout << "finish: value1 == " << value1 << std::endl;
+
+ boost::fiber f2( fn_2);
+ sched.submit_fiber( f2);
+ sched.make_fiber( fn_4, f2);
+ std::cout << "start: interrupt fn_2()" << std::endl;
+
+ for (;;)
+ {
+ while ( sched.run() );
+ if ( sched.empty() ) break;
+ }
+
+ std::cout << "finish: value2 == " << value2 << std::endl;
+
+ boost::fiber f3( fn_3);
+ sched.submit_fiber( f3);
+ sched.make_fiber( fn_4, f3);
+ std::cout << "start: interrupt fn_3()" << std::endl;
+
+ for (;;)
+ {
+ while ( sched.run() );
+ if ( sched.empty() ) break;
+ }
+
+ std::cout << "finish: value3 == " << value3 << 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/fiber.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/fiber.cpp (original)
+++ sandbox/fiber/libs/fiber/src/fiber.cpp 2009-11-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -116,21 +116,22 @@
 {
         if ( ! info_) throw fiber_moved();
         info_->attrs.priority( prio);
- if ( is_alive() ) scheduler::re_schedule( get_id() );
+ if ( is_alive() ) scheduler::reschedule_fiber( get_id() );
 }
 
 void
 fiber::interrupt()
 {
         if ( ! info_) throw fiber_moved();
- info_->interrupt = true;
+ info_->interrupt &= ~detail::INTERRUPTION_DISABLED;
+ info_->interrupt |= detail::INTERRUPTION_ENABLED;
 }
 
 bool
 fiber::interruption_requested() const
 {
         if ( ! info_) throw fiber_moved();
- return info_->interrupt;
+ return ( info_->interrupt & detail::INTERRUPTION_ENABLED) != 0;
 }
 
 void
@@ -147,7 +148,7 @@
 
 void
 fiber::join()
-{ scheduler::join( get_id() ); }
+{ scheduler::join_fiber( get_id() ); }
 
 }}
 

Modified: sandbox/fiber/libs/fiber/src/fiber_info_base_posix.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/fiber_info_base_posix.cpp (original)
+++ sandbox/fiber/libs/fiber/src/fiber_info_base_posix.cpp 2009-11-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -23,7 +23,7 @@
         uctx(),
         uctx_stack(),
         state( STATE_MASTER),
- interrupt( false)
+ interrupt( INTERRUPTION_DISABLED)
 {}
 
 fiber_info_base::fiber_info_base( attributes const& attrs_) :
@@ -32,7 +32,7 @@
         uctx(),
         uctx_stack( new char[attrs.stack_size()]),
         state( STATE_NOT_STARTED),
- interrupt( false)
+ interrupt( INTERRUPTION_DISABLED)
 {
         BOOST_ASSERT( uctx_stack);
 

Modified: sandbox/fiber/libs/fiber/src/fiber_info_base_windows.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/fiber_info_base_windows.cpp (original)
+++ sandbox/fiber/libs/fiber/src/fiber_info_base_windows.cpp 2009-11-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -24,7 +24,7 @@
         attrs(),
         uctx(),
         state( STATE_MASTER),
- interrupt( false)
+ interrupt( INTERRUPTION_DISABLED)
 {
         uctx = ::GetCurrentFiber();
         if ( ! uctx)
@@ -42,7 +42,7 @@
         attrs( attrs_),
         uctx(),
         state( STATE_NOT_STARTED),
- interrupt( false)
+ interrupt( INTERRUPTION_DISABLED)
 {}
 
 }}}

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-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -21,7 +21,7 @@
 scheduler::runs_as_fiber()
 { return impl_; }
 
-fiber::id
+fiber const&
 scheduler::active_fiber()
 {
         if ( ! impl_) throw fiber_error("not a fiber");
@@ -50,6 +50,20 @@
 }
 
 void
+scheduler::interrupt_active_fiber()
+{
+ if ( ! impl_) throw fiber_error("not a fiber");
+ impl_->interrupt_active_fiber();
+}
+
+void
+scheduler::priority_active_fiber( int prio)
+{
+ if ( ! impl_) throw fiber_error("not a fiber");
+ impl_->priority_active_fiber( prio);
+}
+
+void
 scheduler::cancel_fiber( fiber::id const& id)
 {
         if ( ! impl_) throw fiber_error("not a fiber");
@@ -70,33 +84,20 @@
         impl_->resume_fiber( id);
 }
 
-int
-scheduler::priority( fiber::id const& id)
+void
+scheduler::reschedule_fiber( fiber::id const& id)
 {
         if ( ! impl_) throw fiber_error("not a fiber");
- return impl_->priority( id);
+ impl_->reschedule_fiber( id);
 }
 
 void
-scheduler::priority( fiber::id const& id, int prio)
+scheduler::join_fiber( fiber::id const& id)
 {
         if ( ! impl_) throw fiber_error("not a fiber");
- impl_->priority( id, prio);
- re_schedule( id);
+ impl_->join_fiber( id);
 }
 
-void
-scheduler::re_schedule( fiber::id const& id)
-{ impl_->re_schedule( id); }
-
-void
-scheduler::join( fiber::id const& id)
-{ impl_->join( id); }
-
-void
-scheduler::interruption_point()
-{ impl_->interrupt_active_fiber(); }
-
 scheduler::scheduler()
 {
         fiber::convert_thread_to_fiber();

Modified: sandbox/fiber/libs/fiber/src/scheduler_impl.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/scheduler_impl.cpp (original)
+++ sandbox/fiber/libs/fiber/src/scheduler_impl.cpp 2009-11-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -70,9 +70,9 @@
         runnable_fibers_.push_back( result.first->first);
 }
 
-fiber::id
+fiber const&
 scheduler_impl::active_fiber() const
-{ return active_.get_id(); }
+{ return active_; }
 
 void
 scheduler_impl::yield_active_fiber()
@@ -129,7 +129,18 @@
         BOOST_ASSERT( ! HAS_STATE_MASTER( active_.info_->state) );
         BOOST_ASSERT( STATE_RUNNING == active_.info_->state);
 
- if ( active_.info_->interrupt) throw fiber_interrupted();
+ if ( INTERRUPTION_ENABLED == active_.info_->interrupt)
+ throw fiber_interrupted();
+}
+
+void
+scheduler_impl::priority_active_fiber( int prio)
+{
+ BOOST_ASSERT( ! HAS_STATE_MASTER( active_.info_->state) );
+ BOOST_ASSERT( STATE_RUNNING == active_.info_->state);
+
+ active_.priority( prio);
+ reschedule_fiber( active_.get_id() );
 }
 
 void
@@ -235,33 +246,8 @@
         }
 }
 
-int
-scheduler_impl::priority( fiber::id const& id)
-{
- container::iterator i = fibers_.find( id);
- if ( i == fibers_.end() ) throw scheduler_error("fiber not found");
- fiber f( i->second.f);
- BOOST_ASSERT( f);
- BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_->state) );
-
- return f.info_->attrs.priority();
-}
-
-void
-scheduler_impl::priority( fiber::id const& id, int prio)
-{
- container::iterator i = fibers_.find( id);
- if ( i == fibers_.end() ) throw scheduler_error("fiber not found");
- fiber f( i->second.f);
- BOOST_ASSERT( f);
- BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_->state) );
-
- f.info_->attrs.priority( prio);
- re_schedule( id);
-}
-
 void
-scheduler_impl::re_schedule( fiber::id const& id)
+scheduler_impl::reschedule_fiber( fiber::id const& id)
 {
         container::iterator i = fibers_.find( id);
         if ( i == fibers_.end() ) return;
@@ -274,7 +260,7 @@
 }
 
 void
-scheduler_impl::join( fiber::id const& id)
+scheduler_impl::join_fiber( fiber::id const& id)
 {
         container::iterator i = fibers_.find( id);
         if ( i == fibers_.end() ) return;

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-16 15:51:54 EST (Mon, 16 Nov 2009)
@@ -31,22 +31,40 @@
         { interrupted = true; }
 }
 
-void fn_2( boost::fiber f)
+void fn_2()
 {
+ boost::fibers::disable_interruption disabled;
         for ( int i = 0; i < 5; ++i)
         {
- ++value2;
- if ( i == 1) f.interrupt();
+ ++value1;
+ boost::this_fiber::interruption_point();
                 boost::this_fiber::yield();
         }
 }
 
 void fn_3()
 {
+ try
+ {
+ boost::fibers::disable_interruption disabled;
+ for ( int i = 0; i < 5; ++i)
+ {
+ ++value1;
+ boost::fibers::restore_interruption restored;
+ boost::this_fiber::interruption_point();
+ boost::this_fiber::yield();
+ }
+ }
+ catch ( boost::fibers::fiber_interrupted const&)
+ { interrupted = true; }
+}
+
+void fn_5( boost::fiber f)
+{
         for ( int i = 0; i < 5; ++i)
         {
- ++value1;
- boost::this_fiber::interruption_point();
+ ++value2;
+ if ( i == 1) f.interrupt();
                 boost::this_fiber::yield();
         }
 }
@@ -61,7 +79,7 @@
 
         boost::fiber f( fn_1);
         sched.submit_fiber( f);
- sched.make_fiber( fn_2, f);
+ sched.make_fiber( fn_5, f);
 
         BOOST_CHECK_EQUAL( 0, value1);
         BOOST_CHECK_EQUAL( 0, value2);
@@ -141,75 +159,64 @@
 {
         value1 = 0;
         value2 = 0;
+ interrupted = false;
 
         boost::fibers::scheduler sched;
 
- boost::fiber f( fn_3);
+ boost::fiber f( fn_2);
         sched.submit_fiber( f);
- sched.make_fiber( fn_2, f);
+ sched.make_fiber( fn_5, 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_EQUAL( false, interrupted);
         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);
+ for (;;)
+ {
+ while ( sched.run() );
+ if ( sched.empty() ) break;
+ }
 
- 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( 0), sched.size() );
+ BOOST_CHECK_EQUAL( 5, value1);
+ BOOST_CHECK_EQUAL( 5, value2);
+ BOOST_CHECK_EQUAL( false, interrupted);
+}
 
- 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( 2, value2);
+void test_case_3()
+{
+ value1 = 0;
+ value2 = 0;
+ interrupted = false;
 
- 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::fibers::scheduler sched;
 
- 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( 4, value2);
+ boost::fiber f( fn_3);
+ sched.submit_fiber( f);
+ sched.make_fiber( fn_5, f);
 
- BOOST_CHECK( sched.run() );
+ BOOST_CHECK_EQUAL( 0, value1);
+ BOOST_CHECK_EQUAL( 0, value2);
+ BOOST_CHECK_EQUAL( false, interrupted);
         BOOST_CHECK( ! sched.empty() );
- BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
- BOOST_CHECK_EQUAL( 3, value1);
- BOOST_CHECK_EQUAL( 5, value2);
+ BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
 
- 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( 5, value2);
+ for (;;)
+ {
+ while ( sched.run() );
+ if ( sched.empty() ) break;
+ }
 
         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( 5, value2);
+ BOOST_CHECK_EQUAL( true, interrupted);
 }
 
 boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
@@ -219,6 +226,7 @@
 
         test->add( BOOST_TEST_CASE( & test_case_1) );
         test->add( BOOST_TEST_CASE( & test_case_2) );
+ test->add( BOOST_TEST_CASE( & test_case_3) );
 
         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