$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r57640 - in sandbox/fiber: boost/fiber/detail libs/fiber/examples libs/fiber/src libs/fiber/test
From: oliver.kowalke_at_[hidden]
Date: 2009-11-13 15:30:40
Author: olli
Date: 2009-11-13 15:30:39 EST (Fri, 13 Nov 2009)
New Revision: 57640
URL: http://svn.boost.org/trac/boost/changeset/57640
Log:
- unit-test and example related to fiber cancelation added
Added:
   sandbox/fiber/libs/fiber/examples/cancel.cpp   (contents, props changed)
   sandbox/fiber/libs/fiber/test/test_cancel.cpp   (contents, props changed)
Text files modified: 
   sandbox/fiber/boost/fiber/detail/fiber_state.hpp |     2 +-                                      
   sandbox/fiber/libs/fiber/examples/Jamfile.v2     |     1 +                                       
   sandbox/fiber/libs/fiber/src/scheduler_impl.cpp  |    10 +++++++---                              
   sandbox/fiber/libs/fiber/test/Jamfile.v2         |     1 +                                       
   sandbox/fiber/libs/fiber/test/test_scheduler.cpp |     2 +-                                      
   5 files changed, 11 insertions(+), 5 deletions(-)
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-13 15:30:39 EST (Fri, 13 Nov 2009)
@@ -17,7 +17,7 @@
 {
         STATE_MASTER		= 1 << 0,
         STATE_NOT_STARTED	= 1 << 1,
-	STATE_READY		= 1 << 2,
+	STATE_READY			= 1 << 2,
         STATE_RUNNING		= 1 << 3,
         STATE_SUSPENDED		= 1 << 4,
         STATE_WAITING		= 1 << 5,
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-13 15:30:39 EST (Fri, 13 Nov 2009)
@@ -23,6 +23,7 @@
         <threading>multi
     ;
 
+exe cancel : cancel.cpp ;
 exe simple : simple.cpp ;
 exe simple_mt : simple_mt.cpp ;
 exe ping_pong : ping_pong.cpp ;
Added: sandbox/fiber/libs/fiber/examples/cancel.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/examples/cancel.cpp	2009-11-13 15:30:39 EST (Fri, 13 Nov 2009)
@@ -0,0 +1,70 @@
+#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;
+		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;
+		if ( i == 1)
+		{
+			std::cout << "fn_2() cancel fiber " << f.get_id() << std::endl;
+			f.cancel();
+		}
+		boost::this_fiber::yield();
+	}
+}
+
+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 canceled " << 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/scheduler_impl.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/src/scheduler_impl.cpp	(original)
+++ sandbox/fiber/libs/fiber/src/scheduler_impl.cpp	2009-11-13 15:30:39 EST (Fri, 13 Nov 2009)
@@ -57,6 +57,7 @@
 {
         if ( ! f) throw fiber_moved();
         fiber::id id( f.get_id() );
+	BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_->state) );
         BOOST_ASSERT( STATE_NOT_STARTED == f.info_->state);
         f.info_->state = STATE_READY;
         std::pair< std::map< fiber::id, fiber >::iterator, bool > result(
@@ -72,6 +73,7 @@
 void
 scheduler_impl::yield_active_fiber()
 {
+	BOOST_ASSERT( ! HAS_STATE_MASTER( fibers_[f_id_].info_->state) );
         BOOST_ASSERT( STATE_RUNNING == fibers_[f_id_].info_->state);
         fibers_[f_id_].info_->state = STATE_READY;
         runnable_fibers_.push_back( f_id_);
@@ -81,6 +83,7 @@
 void
 scheduler_impl::cancel_active_fiber()
 {
+	BOOST_ASSERT( ! HAS_STATE_MASTER( fibers_[f_id_].info_->state) );
         BOOST_ASSERT( STATE_RUNNING == fibers_[f_id_].info_->state);
         fibers_[f_id_].info_->state = STATE_TERMINATED;
         terminated_fibers_.push( f_id_);
@@ -90,6 +93,7 @@
 void
 scheduler_impl::suspend_active_fiber()
 {
+	BOOST_ASSERT( ! HAS_STATE_MASTER( fibers_[f_id_].info_->state) );
         BOOST_ASSERT( STATE_RUNNING == fibers_[f_id_].info_->state);
         fibers_[f_id_].info_->state |= STATE_SUSPENDED;
         fibers_[f_id_].switch_to_( master_);
@@ -102,7 +106,7 @@
         if ( i == fibers_.end() ) return;
         fiber f( i->second);
         BOOST_ASSERT( f);
-	BOOST_ASSERT( HAS_STATE_MASTER( f.info_->state) );
+	BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_->state) );
         
         if ( HAS_STATE_TERMINATED( f.info_->state) ||
              HAS_STATE_NOT_STARTED( f.info_->state) )
@@ -138,7 +142,7 @@
         if ( i == fibers_.end() ) return;
         fiber f( i->second);
         BOOST_ASSERT( f);
-	BOOST_ASSERT( STATE_MASTER != f.info_->state);
+	BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_->state) );
         
         if ( HAS_STATE_TERMINATED( f.info_->state) ||
              HAS_STATE_NOT_STARTED( f.info_->state) )
@@ -171,7 +175,7 @@
         if ( i == fibers_.end() ) return;
         fiber f( i->second);
         BOOST_ASSERT( f);
-	BOOST_ASSERT( STATE_MASTER != f.info_->state);
+	BOOST_ASSERT( ! HAS_STATE_MASTER( f.info_->state) );
 
         if ( HAS_STATE_SUSPENDED( f.info_->state) )
         {
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-13 15:30:39 EST (Fri, 13 Nov 2009)
@@ -28,6 +28,7 @@
     [ fiber-test test_fiber ]
     [ fiber-test test_scheduler ]
     [ fiber-test test_utility ]
+    [ fiber-test test_cancel ]
     [ fiber-test test_mutex ]
     [ fiber-test test_auto_reset_event ]
     [ fiber-test test_manual_reset_event ]
Added: sandbox/fiber/libs/fiber/test/test_cancel.cpp
==============================================================================
--- (empty file)
+++ sandbox/fiber/libs/fiber/test/test_cancel.cpp	2009-11-13 15:30:39 EST (Fri, 13 Nov 2009)
@@ -0,0 +1,177 @@
+
+//          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;
+int value3 = 0;
+
+void fn_1()
+{
+	for ( int i = 0; i < 3; ++i)
+	{
+		++value1;
+		boost::this_fiber::yield();
+		if ( i == 1)
+			boost::this_fiber::cancel();
+	}
+}
+
+void fn_2()
+{
+	for ( int i = 0; i < 3; ++i)
+	{
+		++value2;
+		boost::this_fiber::yield();
+	}
+}
+
+void fn_3( boost::fiber f)
+{
+	for ( int i = 0; i < 3; ++i)
+	{
+		++value3;
+		if ( i == 1) f.cancel();
+		boost::this_fiber::yield();
+	}
+}
+
+void test_case_1()
+{
+	value1 = 0;
+	value2 = 0;
+
+	boost::fibers::scheduler sched;
+
+	sched.make_fiber( fn_1);
+	sched.make_fiber( fn_2);
+
+	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( 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( 2, 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( 2, 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( 2, value1);
+	BOOST_CHECK_EQUAL( 3, value2);
+}
+
+void test_case_2()
+{
+	value2 = 0;
+	value3 = 0;
+
+	boost::fibers::scheduler sched;
+
+	boost::fiber f( fn_2);
+	sched.submit_fiber( f);
+	sched.make_fiber( fn_3, f);
+
+	BOOST_CHECK_EQUAL( 0, value2);
+	BOOST_CHECK_EQUAL( 0, value3);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK( ! sched.empty() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value2);
+	BOOST_CHECK_EQUAL( 0, value3);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK( ! sched.empty() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 1, value2);
+	BOOST_CHECK_EQUAL( 1, value3);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK( ! sched.empty() );
+	BOOST_CHECK_EQUAL( std::size_t( 2), sched.size() );
+	BOOST_CHECK_EQUAL( 2, value2);
+	BOOST_CHECK_EQUAL( 1, value3);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK( ! sched.empty() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 2, value2);
+	BOOST_CHECK_EQUAL( 2, value3);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK( ! sched.empty() );
+	BOOST_CHECK_EQUAL( std::size_t( 1), sched.size() );
+	BOOST_CHECK_EQUAL( 2, value2);
+	BOOST_CHECK_EQUAL( 3, value3);
+
+	BOOST_CHECK( sched.run() );
+	BOOST_CHECK( sched.empty() );
+	BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() );
+	BOOST_CHECK_EQUAL( 2, value2);
+	BOOST_CHECK_EQUAL( 3, value3);
+
+	BOOST_CHECK( ! sched.run() );
+	BOOST_CHECK( sched.empty() );
+	BOOST_CHECK_EQUAL( std::size_t( 0), sched.size() );
+	BOOST_CHECK_EQUAL( 2, value2);
+	BOOST_CHECK_EQUAL( 3, value3);
+}
+
+boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
+{
+	boost::unit_test::test_suite * test =
+		BOOST_TEST_SUITE("Boost.Fiber: cancel test suite");
+
+	test->add( BOOST_TEST_CASE( & test_case_1) );
+	test->add( BOOST_TEST_CASE( & test_case_2) );
+
+	return test;
+}
Modified: sandbox/fiber/libs/fiber/test/test_scheduler.cpp
==============================================================================
--- sandbox/fiber/libs/fiber/test/test_scheduler.cpp	(original)
+++ sandbox/fiber/libs/fiber/test/test_scheduler.cpp	2009-11-13 15:30:39 EST (Fri, 13 Nov 2009)
@@ -80,7 +80,7 @@
 boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
 {
         boost::unit_test::test_suite * test =
-		BOOST_TEST_SUITE("Boost.Fiber: rrp test suite");
+		BOOST_TEST_SUITE("Boost.Fiber: scheduler test suite");
 
         test->add( BOOST_TEST_CASE( & test_case_1) );
         test->add( BOOST_TEST_CASE( & test_case_2) );