Boost logo

Boost-Commit :

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


Author: olli
Date: 2009-11-15 16:15:52 EST (Sun, 15 Nov 2009)
New Revision: 57692
URL: http://svn.boost.org/trac/boost/changeset/57692

Log:
- support for fiber interruption added
- unit test for fiber interruption added

Added:
   sandbox/fiber/libs/fiber/test/test_interrupt.cpp (contents, props changed)
Text files modified:
   sandbox/fiber/boost/fiber/detail/fiber_info_base_posix.hpp | 1 +
   sandbox/fiber/boost/fiber/detail/fiber_info_base_windows.hpp | 1 +
   sandbox/fiber/boost/fiber/detail/scheduler_impl.hpp | 2 ++
   sandbox/fiber/boost/fiber/fiber.hpp | 4 ++++
   sandbox/fiber/boost/fiber/scheduler.hpp | 4 ++++
   sandbox/fiber/boost/fiber/utility.hpp | 4 ++++
   sandbox/fiber/libs/fiber/src/fiber.cpp | 14 ++++++++++++++
   sandbox/fiber/libs/fiber/src/fiber_info_base_posix.cpp | 6 ++++--
   sandbox/fiber/libs/fiber/src/fiber_info_base_windows.cpp | 6 ++++--
   sandbox/fiber/libs/fiber/src/scheduler.cpp | 4 ++++
   sandbox/fiber/libs/fiber/src/scheduler_impl.cpp | 9 +++++++++
   sandbox/fiber/libs/fiber/test/Jamfile.v2 | 1 +
   12 files changed, 52 insertions(+), 4 deletions(-)

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-15 16:15:52 EST (Sun, 15 Nov 2009)
@@ -36,6 +36,7 @@
         ::ucontext_t uctx;
         shared_array< char > uctx_stack;
         fiber_state_t state;
+ bool 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-15 16:15:52 EST (Sun, 15 Nov 2009)
@@ -36,6 +36,7 @@
         attributes attrs;
         LPVOID uctx;
         fiber_state_t state;
+ bool interrupt;
 
         fiber_info_base();
 

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-15 16:15:52 EST (Sun, 15 Nov 2009)
@@ -63,6 +63,8 @@
 
         void suspend_active_fiber();
 
+ void interrupt_active_fiber();
+
         void cancel_fiber( fiber::id const&);
 
         void suspend_fiber( fiber::id const&);

Modified: sandbox/fiber/boost/fiber/fiber.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/fiber.hpp (original)
+++ sandbox/fiber/boost/fiber/fiber.hpp 2009-11-15 16:15:52 EST (Sun, 15 Nov 2009)
@@ -193,6 +193,10 @@
 
         void priority( int);
 
+ void interrupt();
+
+ bool interruption_requested() const;
+
         void cancel();
 
         void suspend();

Modified: sandbox/fiber/boost/fiber/scheduler.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/scheduler.hpp (original)
+++ sandbox/fiber/boost/fiber/scheduler.hpp 2009-11-15 16:15:52 EST (Sun, 15 Nov 2009)
@@ -32,6 +32,7 @@
 void suspend();
 int priority();
 void priority( int);
+void interruption_point();
 
 }
 
@@ -47,6 +48,7 @@
         friend void this_fiber::suspend();
         friend int this_fiber::priority();
         friend void this_fiber::priority( int);
+ friend void this_fiber::interruption_point();
         friend class fiber;
 
         typedef scoped_ptr< detail::scheduler_impl > impl_t;
@@ -77,6 +79,8 @@
 
         static void join( fiber::id const&);
 
+ static void interruption_point();
+
 public:
         scheduler();
 

Modified: sandbox/fiber/boost/fiber/utility.hpp
==============================================================================
--- sandbox/fiber/boost/fiber/utility.hpp (original)
+++ sandbox/fiber/boost/fiber/utility.hpp 2009-11-15 16:15:52 EST (Sun, 15 Nov 2009)
@@ -47,6 +47,10 @@
 void priority( int prio)
 { fibers::scheduler::priority( get_id(), prio); }
 
+inline
+void interruption_point()
+{ fibers::scheduler::interruption_point(); }
+
 }}
 
 #include <boost/config/abi_suffix.hpp>

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-15 16:15:52 EST (Sun, 15 Nov 2009)
@@ -120,6 +120,20 @@
 }
 
 void
+fiber::interrupt()
+{
+ if ( ! info_) throw fiber_moved();
+ info_->interrupt = true;
+}
+
+bool
+fiber::interruption_requested() const
+{
+ if ( ! info_) throw fiber_moved();
+ return info_->interrupt;
+}
+
+void
 fiber::cancel()
 { scheduler::cancel_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-15 16:15:52 EST (Sun, 15 Nov 2009)
@@ -22,7 +22,8 @@
         attrs(),
         uctx(),
         uctx_stack(),
- state( STATE_MASTER)
+ state( STATE_MASTER),
+ interrupt( false)
 {}
 
 fiber_info_base::fiber_info_base( attributes const& attrs_) :
@@ -30,7 +31,8 @@
         attrs( attrs_),
         uctx(),
         uctx_stack( new char[attrs.stack_size()]),
- state( STATE_NOT_STARTED)
+ state( STATE_NOT_STARTED),
+ interrupt( false)
 {
         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-15 16:15:52 EST (Sun, 15 Nov 2009)
@@ -23,7 +23,8 @@
         use_count( 0),
         attrs(),
         uctx(),
- state( STATE_MASTER)
+ state( STATE_MASTER),
+ interrupt( false)
 {
         uctx = ::GetCurrentFiber();
         if ( ! uctx)
@@ -40,7 +41,8 @@
         use_count( 0),
         attrs( attrs_),
         uctx(),
- state( STATE_NOT_STARTED)
+ state( STATE_NOT_STARTED),
+ interrupt( false)
 {}
 
 }}}

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-15 16:15:52 EST (Sun, 15 Nov 2009)
@@ -93,6 +93,10 @@
 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-15 16:15:52 EST (Sun, 15 Nov 2009)
@@ -124,6 +124,15 @@
 }
 
 void
+scheduler_impl::interrupt_active_fiber()
+{
+ BOOST_ASSERT( ! HAS_STATE_MASTER( active_.info_->state) );
+ BOOST_ASSERT( STATE_RUNNING == active_.info_->state);
+
+ if ( active_.info_->interrupt) throw fiber_interrupted();
+}
+
+void
 scheduler_impl::cancel_fiber( fiber::id const& id)
 {
         container::iterator i = fibers_.find( id);

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-15 16:15:52 EST (Sun, 15 Nov 2009)
@@ -32,6 +32,7 @@
     [ fiber-test test_suspended ]
     [ fiber-test test_priority ]
     [ fiber-test test_join ]
+ [ fiber-test test_interrupt ]
     [ fiber-test test_mutex ]
     [ fiber-test test_auto_reset_event ]
     [ fiber-test test_manual_reset_event ]

Added: sandbox/fiber/libs/fiber/test/test_interrupt.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/test/test_interrupt.cpp 2009-11-15 16:15:52 EST (Sun, 15 Nov 2009)
@@ -0,0 +1,224 @@
+
+// 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;
+bool interrupted = false;
+
+void fn_1()
+{
+ try
+ {
+ for ( int i = 0; i < 5; ++i)
+ {
+ ++value1;
+ boost::this_fiber::interruption_point();
+ boost::this_fiber::yield();
+ }
+ }
+ catch ( boost::fibers::fiber_interrupted const&)
+ { interrupted = true; }
+}
+
+void fn_2( boost::fiber f)
+{
+ for ( int i = 0; i < 5; ++i)
+ {
+ ++value2;
+ if ( i == 1) f.interrupt();
+ boost::this_fiber::yield();
+ }
+}
+
+void fn_3()
+{
+ for ( int i = 0; i < 5; ++i)
+ {
+ ++value1;
+ boost::this_fiber::interruption_point();
+ boost::this_fiber::yield();
+ }
+}
+
+void test_case_1()
+{
+ value1 = 0;
+ value2 = 0;
+ interrupted = false;
+
+ 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( false, interrupted);
+ 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( false, interrupted);
+ 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( false, interrupted);
+ 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( false, interrupted);
+ BOOST_CHECK_EQUAL( 2, value1);
+ BOOST_CHECK_EQUAL( 2, value2);
+
+ BOOST_CHECK( sched.run() );
+ BOOST_CHECK( ! sched.empty() );
+ BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+ BOOST_CHECK_EQUAL( true, interrupted);
+ BOOST_CHECK_EQUAL( 3, value1);
+ BOOST_CHECK_EQUAL( 2, value2);
+
+ BOOST_CHECK( sched.run() );
+ BOOST_CHECK( ! sched.empty() );
+ BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+ BOOST_CHECK_EQUAL( true, interrupted);
+ BOOST_CHECK_EQUAL( 3, 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( true, interrupted);
+ BOOST_CHECK_EQUAL( 3, value1);
+ BOOST_CHECK_EQUAL( 4, value2);
+
+ BOOST_CHECK( sched.run() );
+ BOOST_CHECK( ! sched.empty() );
+ BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+ BOOST_CHECK_EQUAL( true, interrupted);
+ BOOST_CHECK_EQUAL( 3, value1);
+ BOOST_CHECK_EQUAL( 5, value2);
+
+ BOOST_CHECK( sched.run() );
+ BOOST_CHECK( sched.empty() );
+ BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() );
+ BOOST_CHECK_EQUAL( true, interrupted);
+ BOOST_CHECK_EQUAL( 3, value1);
+ BOOST_CHECK_EQUAL( 5, value2);
+
+ BOOST_CHECK( ! sched.run() );
+ BOOST_CHECK( sched.empty() );
+ BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() );
+ BOOST_CHECK_EQUAL( true, interrupted);
+ BOOST_CHECK_EQUAL( 3, value1);
+ BOOST_CHECK_EQUAL( 5, value2);
+}
+
+void test_case_2()
+{
+ value1 = 0;
+ value2 = 0;
+
+ boost::fibers::scheduler sched;
+
+ boost::fiber f( fn_3);
+ 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( 1), sched.size() );
+ BOOST_CHECK_EQUAL( 3, value1);
+ BOOST_CHECK_EQUAL( 2, 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( 1), sched.size() );
+ BOOST_CHECK_EQUAL( 3, value1);
+ BOOST_CHECK_EQUAL( 4, 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( 5, 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( 5, 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( 5, value2);
+}
+
+boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
+{
+ boost::unit_test::test_suite * test =
+ BOOST_TEST_SUITE("Boost.Fiber: interrupt test suite");
+
+ test->add( BOOST_TEST_CASE( & test_case_1) );
+ test->add( BOOST_TEST_CASE( & test_case_2) );
+
+ 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