$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r52634 - in sandbox/task: boost/task boost/task/detail libs/task/build libs/task/src libs/task/test
From: oliver.kowalke_at_[hidden]
Date: 2009-04-27 16:52:26
Author: olli
Date: 2009-04-27 16:52:25 EDT (Mon, 27 Apr 2009)
New Revision: 52634
URL: http://svn.boost.org/trac/boost/changeset/52634
Log:
* bugfix related to async_handle::interrupt_and_wait() and async_in_thread()
  (hung because condition-variable gets never notified)
* unit-test modified
Added:
   sandbox/task/libs/task/test/test_in_bounded_pool.cpp   (contents, props changed)
   sandbox/task/libs/task/test/test_in_thread.cpp   (contents, props changed)
   sandbox/task/libs/task/test/test_in_unbounded_pool.cpp   (contents, props changed)
Text files modified: 
   sandbox/task/boost/task/async.hpp                  |    12 ++--                                    
   sandbox/task/boost/task/async_handle.hpp           |     8 +-                                      
   sandbox/task/boost/task/detail/interrupter.hpp     |     2                                         
   sandbox/task/boost/task/detail/thread_callable.hpp |    20 +++++--                                 
   sandbox/task/boost/task/pool.hpp                   |    10 ---                                     
   sandbox/task/libs/task/build/Jamfile.v2            |    46 +++++++++--------                       
   sandbox/task/libs/task/src/interrupter.cpp         |    10 +++                                     
   sandbox/task/libs/task/test/Jamfile.v2             |     6 +-                                      
   sandbox/task/libs/task/test/test_functions.hpp     |    11 ++++                                    
   sandbox/task/libs/task/test/test_handle.cpp        |   104 +++++++++++++++++++++++++++++++++------ 
   10 files changed, 163 insertions(+), 66 deletions(-)
Modified: sandbox/task/boost/task/async.hpp
==============================================================================
--- sandbox/task/boost/task/async.hpp	(original)
+++ sandbox/task/boost/task/async.hpp	2009-04-27 16:52:25 EDT (Mon, 27 Apr 2009)
@@ -20,14 +20,14 @@
 namespace boost { namespace task
 {
 template< typename R >
-async_handle< R > async_pool( task< R > t)
+async_handle< R > async_in_pool( task< R > t)
 { return get_default_pool().submit( t); }
 
 template<
         typename R,
         typename Attr
 >
-async_handle< R > async_pool(
+async_handle< R > async_in_pool(
         task< R > t,
         Attr const& attr)
 { return get_default_pool().submit( t, attr); }
@@ -36,7 +36,7 @@
         typename Channel,
         typename R
 >
-async_handle< R > async_pool(
+async_handle< R > async_in_pool(
         pool< Channel > & pool,
         task< R > t)
 { return pool.submit( t); }
@@ -46,7 +46,7 @@
         typename R,
         typename Attr
 >
-async_handle< R > async_pool(
+async_handle< R > async_in_pool(
         pool< Channel > & pool,
         task< R > t,
         Attr const& attr)
@@ -65,10 +65,10 @@
 }
 
 template< typename R >
-async_handle< R > async_thread( task< R > t)
+async_handle< R > async_in_thread( task< R > t)
 {
         detail::interrupter intr;
-	detail::thread_callable ca( t);
+	detail::thread_callable ca( t, intr);
 
         shared_ptr< thread > thrd( new thread( ca), detail::joiner() );
         intr.set( thrd);
Modified: sandbox/task/boost/task/async_handle.hpp
==============================================================================
--- sandbox/task/boost/task/async_handle.hpp	(original)
+++ sandbox/task/boost/task/async_handle.hpp	2009-04-27 16:52:25 EDT (Mon, 27 Apr 2009)
@@ -28,7 +28,7 @@
 class pool;
 
 template< typename R >
-async_handle< R > async_thread( task< R >);
+async_handle< R > async_in_thread( task< R >);
 
 template< typename R >
 class async_handle
@@ -37,7 +37,7 @@
         template< typename Channel >
         friend class pool;
         template< typename T >
-	friend async_handle< T > async_thread( task< T >);
+	friend async_handle< T > async_in_thread( task< T >);
         template< typename Iterator >
         friend void waitfor_all( Iterator begin, Iterator end);
         template< typename T1, typename T2 >
@@ -103,6 +103,8 @@
                 { return fut_.get(); }
                 catch ( broken_promise const&)
                 { throw broken_task(); }
+		catch ( promise_already_satisfied const&)
+		{ throw task_already_executed(); }
         }
 
         bool is_ready() const
@@ -139,7 +141,7 @@
         template< typename Channel >
         friend class pool;
         template< typename T >
-	friend async_handle< T > async_thread( task< T >);
+	friend async_handle< T > async_in_thread( task< T >);
         template< typename Iterator >
         friend void waitfor_all( Iterator begin, Iterator end);
         template< typename T1, typename T2 >
Modified: sandbox/task/boost/task/detail/interrupter.hpp
==============================================================================
--- sandbox/task/boost/task/detail/interrupter.hpp	(original)
+++ sandbox/task/boost/task/detail/interrupter.hpp	2009-04-27 16:52:25 EDT (Mon, 27 Apr 2009)
@@ -40,6 +40,8 @@
         public:
                 impl();
 
+		~impl();
+
                 void set( shared_ptr< thread > const& thrd);
 
                 void reset();
Modified: sandbox/task/boost/task/detail/thread_callable.hpp
==============================================================================
--- sandbox/task/boost/task/detail/thread_callable.hpp	(original)
+++ sandbox/task/boost/task/detail/thread_callable.hpp	2009-04-27 16:52:25 EDT (Mon, 27 Apr 2009)
@@ -35,23 +35,31 @@
         class impl_wrapper : public impl
         {
         private:
-		task< R >			t_;
+		task< R >		t_;
+		interrupter		i_;
 
         public:
-		impl_wrapper( task< R > const& t)
-		: t_( t)
+		impl_wrapper(
+			task< R > const& t,
+			interrupter const& i)
+		: t_( t), i_( i)
                 {}
 
                 void run()
-		{ t_(); }
+		{
+			t_();
+			i_.reset();
+		}
         };
 
         shared_ptr< impl >	impl_;
 
 public:
         template< typename R >
-	thread_callable( task< R > const& t)
-	: impl_( new impl_wrapper<  R >( t) )
+	thread_callable(
+		task< R > const& t,
+		interrupter const& i)
+	: impl_( new impl_wrapper<  R >( t, i) )
         {}
 
         void operator()();
Modified: sandbox/task/boost/task/pool.hpp
==============================================================================
--- sandbox/task/boost/task/pool.hpp	(original)
+++ sandbox/task/boost/task/pool.hpp	2009-04-27 16:52:25 EDT (Mon, 27 Apr 2009)
@@ -35,8 +35,6 @@
 
 namespace boost { namespace task
 {
-typedef detail::pool_callable	pool_callable;
-
 template< typename Channel >
 class pool : private noncopyable
 {
@@ -244,10 +242,9 @@
                 lk.unlock();
         }
 
-	const std::vector< pool_callable > shutdown_now()
+	const void shutdown_now()
         {
-		if ( closed_() || close_() > 1)
-			return std::vector< pool_callable >();
+		if ( closed_() || close_() > 1) return;
 
                 channel_.deactivate_now();
                 shared_lock< shared_mutex > lk( mtx_wg_);
@@ -255,9 +252,6 @@
                 wg_.interrupt_all();
                 wg_.join_all();
                 lk.unlock();
-		std::vector< pool_callable > drain( channel_.drain() );
-
-		return drain;
         }
 
         std::size_t size()
Modified: sandbox/task/libs/task/build/Jamfile.v2
==============================================================================
--- sandbox/task/libs/task/build/Jamfile.v2	(original)
+++ sandbox/task/libs/task/build/Jamfile.v2	2009-04-27 16:52:25 EDT (Mon, 27 Apr 2009)
@@ -30,34 +30,36 @@
 
 alias task_sources
     : ## win32 sources ##
-	 callable.cpp
-	 default_pool.cpp
-	 guard.cpp
-	 interrupter.cpp
-	 poolsize.cpp
-	 scanns.cpp
-	 semaphore_windows.cpp
-	 watermark.cpp
-	 worker.cpp
-	 worker_group.cpp
-	 wsq.cpp
+	default_pool.cpp
+	guard.cpp
+	interrupter.cpp
+	pool_callable.cpp
+	poolsize.cpp
+	scanns.cpp
+	semaphore_windows.cpp
+	thread_callable.cpp
+	watermark.cpp
+	worker.cpp
+	worker_group.cpp
+	wsq.cpp
     : ## requirements ##
       <taskapi>win32
     ;
 
 alias task_sources
     : ## posix sources ##
-	 callable.cpp
-	 default_pool.cpp
-	 guard.cpp
-	 interrupter.cpp
-	 poolsize.cpp
-	 scanns.cpp
-	 semaphore_posix.cpp
-	 watermark.cpp
-	 worker.cpp
-	 worker_group.cpp
-	 wsq.cpp
+	default_pool.cpp
+	guard.cpp
+	interrupter.cpp
+	pool_callable.cpp
+	poolsize.cpp
+	scanns.cpp
+	semaphore_posix.cpp
+	thread_callable.cpp
+	watermark.cpp
+	worker.cpp
+	worker_group.cpp
+	wsq.cpp
     : ## requirements ##
       <taskapi>posix
     ;
Modified: sandbox/task/libs/task/src/interrupter.cpp
==============================================================================
--- sandbox/task/libs/task/src/interrupter.cpp	(original)
+++ sandbox/task/libs/task/src/interrupter.cpp	2009-04-27 16:52:25 EDT (Mon, 27 Apr 2009)
@@ -31,6 +31,9 @@
 thrd_()
 {}
 
+interrupter::impl::~impl()
+{ reset(); }
+
 void
 interrupter::impl::set( shared_ptr< thread > const& thrd)
 {
@@ -45,8 +48,11 @@
 interrupter::impl::reset()
 {
         unique_lock< mutex > lk( mtx_);
-	BOOST_ASSERT( thrd_);
-	thrd_.reset();
+// 	BOOST_ASSERT( thrd_);
+// 	try
+// 	{ thrd_.reset(); }
+// 	catch (...)
+// 	{ printf("exception\n"); }
         try
         { this_thread::interruption_point(); }
         catch ( thread_interrupted const&)
Modified: sandbox/task/libs/task/test/Jamfile.v2
==============================================================================
--- sandbox/task/libs/task/test/Jamfile.v2	(original)
+++ sandbox/task/libs/task/test/Jamfile.v2	2009-04-27 16:52:25 EDT (Mon, 27 Apr 2009)
@@ -28,7 +28,7 @@
 
 test-suite thread_pool :
     [ tp-test test_handle ]
-    [ tp-test test_launch ]
-    [ tp-test test_pool_unbounded_channel ]
-    [ tp-test test_pool_bounded_channel ]
+    [ tp-test test_in_thread ]
+    [ tp-test test_in_unbounded_pool ]
+    [ tp-test test_in_bounded_pool ]
     ;
Modified: sandbox/task/libs/task/test/test_functions.hpp
==============================================================================
--- sandbox/task/libs/task/test/test_functions.hpp	(original)
+++ sandbox/task/libs/task/test/test_functions.hpp	2009-04-27 16:52:25 EDT (Mon, 27 Apr 2009)
@@ -34,6 +34,17 @@
 void delay_fn( pt::time_duration const& td)
 { boost::this_thread::sleep( td); }
 
+void interrupt_fn( pt::time_duration const& td, bool & finished)
+{
+	try
+	{ boost::this_thread::sleep( td); }
+	catch (...)
+	{
+		finished = true;
+		throw;
+	}
+}
+
 inline
 int fibonacci_fn( int n)
 {
Modified: sandbox/task/libs/task/test/test_handle.cpp
==============================================================================
--- sandbox/task/libs/task/test/test_handle.cpp	(original)
+++ sandbox/task/libs/task/test/test_handle.cpp	2009-04-27 16:52:25 EDT (Mon, 27 Apr 2009)
@@ -29,33 +29,102 @@
 class test_handle
 {
 public:
-	// test id
+	// check id
         void test_case_1()
         {
                 tsk::task< int > t(
                         tsk::make_task(
                                 fibonacci_fn,
                                 10) );
-		tsk::handle< int > h( t.get_handle() );
-		tsk::launch( t);
-		BOOST_CHECK_EQUAL( t.get_id(), h.get_id() );
+		tsk::async_handle< int > h(
+			tsk::async_in_thread(
+				t) );
+		BOOST_CHECK_EQUAL( h.get_id(), t.get_id() );
                 BOOST_CHECK_EQUAL( h.get(), 55);
         }
 
-	// test handle
+	// check waitfor_all()
         void test_case_2()
         {
-		tsk::task< int > t(
-			tsk::make_task(
-				fibonacci_fn,
-				10) );
-		tsk::handle< int > h1( t.get_handle() );
-		tsk::handle< int > h2( t.get_handle() );
-		tsk::launch( t);
-		BOOST_CHECK_EQUAL( t.get_id(), h1.get_id() );
-		BOOST_CHECK_EQUAL( t.get_id(), h2.get_id() );
-		BOOST_CHECK_EQUAL( h1.get_id(), h2.get_id() );
-		BOOST_CHECK_EQUAL( h1 == h2, true);
+		std::vector< tsk::async_handle< int > > vec;
+		for ( int i = 0; i <= 5; ++i)
+			vec.push_back(
+				tsk::async_in_pool(
+					tsk::make_task(
+						fibonacci_fn,
+						i) ) );
+		tsk::waitfor_all( vec.begin(), vec.end() );
+		BOOST_CHECK( vec[0].is_ready() );
+		BOOST_CHECK( vec[1].is_ready() );
+		BOOST_CHECK( vec[2].is_ready() );
+		BOOST_CHECK( vec[3].is_ready() );
+		BOOST_CHECK( vec[4].is_ready() );
+		BOOST_CHECK( vec[5].is_ready() );
+		BOOST_CHECK_EQUAL( vec[0].get(), 0);
+		BOOST_CHECK_EQUAL( vec[1].get(), 1);
+		BOOST_CHECK_EQUAL( vec[2].get(), 1);
+		BOOST_CHECK_EQUAL( vec[3].get(), 2);
+		BOOST_CHECK_EQUAL( vec[4].get(), 3);
+		BOOST_CHECK_EQUAL( vec[5].get(), 5);
+	}
+
+	// check waitfor_any()
+	void test_case_3()
+	{
+		tsk::async_handle< void > h1(
+			tsk::async_in_pool(
+				tsk::make_task(
+					delay_fn,
+					pt::seconds( 3) ) ) );
+		tsk::async_handle< int > h2(
+			tsk::async_in_pool(
+				tsk::make_task(
+					fibonacci_fn,
+					10) ) );
+		tsk::waitfor_any( h1, h2);
+		BOOST_CHECK( ! h1.is_ready() );
+		BOOST_CHECK( h2.is_ready() );
+		BOOST_CHECK_EQUAL( h2.get(), 55);
+	}
+
+	// check interrupt
+	void test_case_4()
+	{
+		tsk::async_handle< void > h(
+			tsk::async_in_thread(
+				tsk::make_task(
+					delay_fn,
+					pt::seconds( 3) ) ) );
+		h.interrupt();
+		BOOST_CHECK( h.interruption_requested() );
+		bool thrown( false);
+		try
+		{ h.get(); }
+		catch ( tsk::task_interrupted const&)
+		{ thrown = true; }
+		BOOST_CHECK( thrown);
+	}
+
+	// check interruption
+	void test_case_5()
+	{
+		bool finished( false);
+		tsk::async_handle< void > h(
+			tsk::async_in_thread(
+				tsk::make_task(
+					interrupt_fn,
+					pt::seconds( 3),
+					boost::ref( finished) ) ) );
+		h.interrupt_and_wait();
+		BOOST_CHECK( finished);
+		BOOST_CHECK( h.is_ready() );
+		BOOST_CHECK( h.interruption_requested() );
+		bool thrown( false);
+		try
+		{ h.get(); }
+		catch ( tsk::task_interrupted const&)
+		{ thrown = true; }
+		BOOST_CHECK( thrown);
         }
 };
 
@@ -66,6 +135,9 @@
         boost::shared_ptr< test_handle > instance( new test_handle() );
         test->add( BOOST_CLASS_TEST_CASE( & test_handle::test_case_1, instance) );
         test->add( BOOST_CLASS_TEST_CASE( & test_handle::test_case_2, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_handle::test_case_3, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_handle::test_case_4, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_handle::test_case_5, instance) );
 
         return test;
 }
Added: sandbox/task/libs/task/test/test_in_bounded_pool.cpp
==============================================================================
--- (empty file)
+++ sandbox/task/libs/task/test/test_in_bounded_pool.cpp	2009-04-27 16:52:25 EDT (Mon, 27 Apr 2009)
@@ -0,0 +1,437 @@
+
+//          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 <cstdlib>
+#include <iostream>
+#include <map>
+#include <stdexcept>
+#include <vector>
+
+#include <boost/bind.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/function.hpp>
+#include <boost/ref.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/thread.hpp>
+#include <boost/thread/barrier.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/task.hpp>
+
+#include "test_functions.hpp"
+
+namespace pt = boost::posix_time;
+namespace tsk = boost::task;
+
+class test_in_bounded_pool
+{
+public:
+	// check size, active, idle
+	void test_case_1()
+	{
+		tsk::pool<
+			tsk::bounded_channel< tsk::fifo >
+		> pool(
+			tsk::poolsize( 3),
+			tsk::high_watermark( 10),
+			tsk::low_watermark( 10) );
+		BOOST_CHECK_EQUAL( pool.size(), std::size_t( 3) );
+		BOOST_CHECK_EQUAL( pool.idle(), std::size_t( 3) );
+		BOOST_CHECK_EQUAL( pool.active(), std::size_t( 0) );
+	}
+
+	// check submit
+	void test_case_2()
+	{
+		tsk::pool<
+			tsk::bounded_channel< tsk::fifo >
+		> pool(
+			tsk::poolsize( 1),
+			tsk::high_watermark( 10),
+			tsk::low_watermark( 10) );
+		tsk::async_handle< int > h(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					fibonacci_fn,
+					10) ) );
+		BOOST_CHECK_EQUAL( h.get(), 55);
+	}
+
+	// check runs in pool
+	void test_case_3()
+	{
+		tsk::pool<
+			tsk::bounded_channel< tsk::fifo >
+		> pool(
+			tsk::poolsize( 1),
+			tsk::high_watermark( 10),
+			tsk::low_watermark( 10) );
+		tsk::async_handle< bool > h(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					runs_in_pool_fn) ) );
+		BOOST_CHECK_EQUAL( h.get(), true);
+	}
+
+	// don't execute twice
+	void test_case_4()
+	{
+		tsk::pool<
+			tsk::bounded_channel< tsk::fifo >
+		> pool(
+			tsk::poolsize( 1),
+			tsk::high_watermark( 10),
+			tsk::low_watermark( 10) );
+		tsk::task< int > t(
+			tsk::make_task(
+				fibonacci_fn,
+				10) );
+		tsk::async_handle< int > h(
+			tsk::async_in_pool(
+				pool,
+				t) );
+		BOOST_CHECK_EQUAL( h.get(), 55);
+		tsk::async_in_pool(
+			pool,
+			t);
+		bool thrown( false);
+		try
+		{ h.get(); }
+		catch ( tsk::task_already_executed const&)
+		{ thrown = true; }
+		BOOST_CHECK( thrown);
+	}
+
+	// check shutdown
+	void test_case_5()
+	{
+		tsk::pool<
+			tsk::bounded_channel< tsk::fifo >
+		> pool(
+			tsk::poolsize( 1),
+			tsk::high_watermark( 10),
+			tsk::low_watermark( 10) );
+		tsk::async_handle< int > h(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					fibonacci_fn,
+					10) ) );
+		pool.shutdown();
+		BOOST_CHECK( pool.closed() );
+		BOOST_CHECK_EQUAL( h.get(), 55);
+	}
+
+	// check runtime_error throw inside task
+	void test_case_6()
+	{
+		tsk::pool<
+			tsk::bounded_channel< tsk::fifo >
+		> pool(
+			tsk::poolsize( 1),
+			tsk::high_watermark( 10),
+			tsk::low_watermark( 10) );
+		tsk::async_handle< void > h(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					throwing_fn) ) );
+		pool.shutdown();
+		bool thrown( false);
+		try
+		{ h.get(); }
+		catch ( std::runtime_error const&)
+		{ thrown = true; }
+		BOOST_CHECK( thrown);
+	}
+
+	// check shutdown with task_rejected exception
+	void test_case_7()
+	{
+		tsk::pool<
+			tsk::bounded_channel< tsk::fifo >
+		> pool(
+			tsk::poolsize( 1),
+			tsk::high_watermark( 10),
+			tsk::low_watermark( 10) );
+		pool.shutdown();
+		BOOST_CHECK( pool.closed() );
+		bool thrown( false);
+		try
+		{
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					boost::bind(
+						fibonacci_fn,
+						10) ) );
+		}
+		catch ( tsk::task_rejected const&)
+		{ thrown = true; }
+		BOOST_CHECK( thrown);
+	}
+
+	// check shutdown_now with thread_interrupted exception
+	void test_case_8()
+	{
+		tsk::pool<
+			tsk::bounded_channel< tsk::fifo >
+		> pool(
+			tsk::poolsize( 1),
+			tsk::high_watermark( 1),
+			tsk::low_watermark( 1) );
+		tsk::async_handle< void > h(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					delay_fn,
+					pt::millisec( 500) ) ) );
+		boost::this_thread::sleep( pt::millisec( 250) );
+		BOOST_CHECK_EQUAL( pool.size(), std::size_t( 1) );
+		pool.shutdown_now();
+		BOOST_CHECK( pool.closed() );
+		BOOST_CHECK_EQUAL( pool.size(), std::size_t( 1) );
+		BOOST_CHECK_EQUAL( pool.idle(), std::size_t( 1) );
+		BOOST_CHECK_EQUAL( pool.active(), std::size_t( 0) );
+		bool thrown( false);
+		try
+		{ h.get(); }
+		catch ( tsk::task_interrupted const&)
+		{ thrown = true; }
+		BOOST_CHECK( thrown);
+	}
+
+	// check pending
+	void test_case_9()
+	{
+		typedef tsk::pool<
+			tsk::bounded_channel< tsk::fifo >
+		> pool_type;
+		pool_type pool(
+			tsk::poolsize( 1),
+			tsk::high_watermark( 10),
+			tsk::low_watermark( 10) );
+		boost::barrier b( 2);
+		tsk::async_handle< void > h1(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					barrier_fn,
+					boost::ref( b) ) ) );
+		boost::this_thread::sleep( pt::millisec( 250) );
+		BOOST_CHECK_EQUAL( pool.pending(), std::size_t( 0) );
+		tsk::async_handle< int > h2(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					fibonacci_fn,
+					10) ) );
+		boost::this_thread::sleep( pt::millisec(250) );
+		BOOST_CHECK_EQUAL( pool.pending(), std::size_t( 1) );
+		tsk::async_handle< int > h3(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					fibonacci_fn,
+					10) ) );
+		boost::this_thread::sleep( pt::millisec(250) );
+		BOOST_CHECK_EQUAL( pool.pending(), std::size_t( 2) );
+		b.wait();
+		h1.get();
+		BOOST_CHECK_EQUAL( h2.get(), 55);
+		BOOST_CHECK_EQUAL( h3.get(), 55);
+		BOOST_CHECK_EQUAL( pool.pending(), std::size_t( 0) );
+	}
+
+	// check interruption
+	void test_case_10()
+	{
+		typedef tsk::pool<
+			tsk::bounded_channel< tsk::fifo >
+		> pool_type;
+		pool_type pool(
+			tsk::poolsize( 1),
+			tsk::high_watermark( 10),
+			tsk::low_watermark( 10) );
+		boost::barrier b( 2);
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				barrier_fn,
+				boost::ref( b) ) );
+		std::vector< int > buffer;
+		tsk::async_handle< void > h(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					buffer_fibonacci_fn,
+					boost::ref( buffer),
+					10) ) );
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				buffer_fibonacci_fn,
+				boost::ref( buffer),
+				0) );
+		h.interrupt();
+		b.wait();
+		pool.shutdown();
+		BOOST_CHECK_EQUAL( buffer[0], 0);
+		BOOST_CHECK_EQUAL( buffer.size(), std::size_t( 1) );
+		bool thrown( false);
+		try
+		{ h.get(); }
+		catch ( tsk::task_interrupted const&)
+		{ thrown = true; }
+		BOOST_CHECK( thrown);
+	}
+
+	// check fifo scheduling
+	void test_case_11()
+	{
+		typedef tsk::pool<
+			tsk::bounded_channel< tsk::fifo >
+		> pool_type;
+		pool_type pool(
+			tsk::poolsize( 1),
+			tsk::high_watermark( 10),
+			tsk::low_watermark( 10) );
+		boost::barrier b( 2);
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				barrier_fn,
+				boost::ref( b) ) );
+		std::vector< int > buffer;
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				buffer_fibonacci_fn,
+				boost::ref( buffer),
+				10) );
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				buffer_fibonacci_fn,
+				boost::ref( buffer),
+				0) );
+		b.wait();
+		pool.shutdown();
+		BOOST_CHECK_EQUAL( buffer[0], 55);
+		BOOST_CHECK_EQUAL( buffer[1], 0);
+		BOOST_CHECK_EQUAL( buffer.size(), std::size_t( 2) );
+	}
+
+	// check priority scheduling
+	void test_case_12()
+	{
+		typedef tsk::pool<
+			tsk::bounded_channel< tsk::priority< int > >
+		> pool_type;
+		pool_type pool(
+			tsk::poolsize( 1),
+			tsk::high_watermark( 10),
+			tsk::low_watermark( 10) );
+		boost::barrier b( 2);
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				barrier_fn,
+				boost::ref( b) ),
+			0);
+		std::vector< int > buffer;
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				buffer_fibonacci_fn,
+				boost::ref( buffer),
+				10),
+			1);
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				buffer_fibonacci_fn,
+				boost::ref( buffer),
+				0),
+			0);
+		b.wait();
+		pool.shutdown();
+		BOOST_CHECK_EQUAL( buffer[0], 0);
+		BOOST_CHECK_EQUAL( buffer[1], 55);
+		BOOST_CHECK_EQUAL( buffer.size(), std::size_t( 2) );
+	}
+
+	// check smart scheduling
+	void test_case_13()
+	{
+		typedef tsk::pool<
+			tsk::bounded_channel< tsk::smart< int, std::less< int >, tsk::replace_oldest, tsk::take_oldest > >
+		> pool_type;
+		pool_type pool(
+			tsk::poolsize( 1),
+			tsk::high_watermark( 10),
+			tsk::low_watermark( 10) );
+		boost::barrier b( 2);
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				barrier_fn,
+				boost::ref( b) ),
+			0);
+		std::vector< int > buffer;
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				buffer_fibonacci_fn,
+				boost::ref( buffer),
+				10),
+			2);
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				buffer_fibonacci_fn,
+				boost::ref( buffer),
+				0),
+			1);
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				buffer_fibonacci_fn,
+				boost::ref( buffer),
+				1),
+			2);
+		b.wait();
+		pool.shutdown();
+		BOOST_CHECK_EQUAL( buffer[0], 0);
+		BOOST_CHECK_EQUAL( buffer[1], 1);
+		BOOST_CHECK_EQUAL( buffer.size(), std::size_t( 2) );
+	}
+};
+
+boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
+{
+	boost::unit_test::test_suite * test( BOOST_TEST_SUITE("Boost.Task: test suite") );
+
+	boost::shared_ptr< test_in_bounded_pool > instance( new test_in_bounded_pool() );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_bounded_pool::test_case_1, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_bounded_pool::test_case_2, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_bounded_pool::test_case_3, instance) );
+	//test->add( BOOST_CLASS_TEST_CASE( & test_in_bounded_pool::test_case_4, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_bounded_pool::test_case_5, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_bounded_pool::test_case_6, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_bounded_pool::test_case_7, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_bounded_pool::test_case_8, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_bounded_pool::test_case_9, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_bounded_pool::test_case_10, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_bounded_pool::test_case_11, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_bounded_pool::test_case_12, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_bounded_pool::test_case_13, instance) );
+
+	return test;
+}
+
Added: sandbox/task/libs/task/test/test_in_thread.cpp
==============================================================================
--- (empty file)
+++ sandbox/task/libs/task/test/test_in_thread.cpp	2009-04-27 16:52:25 EDT (Mon, 27 Apr 2009)
@@ -0,0 +1,118 @@
+
+//          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 <cstdlib>
+#include <iostream>
+#include <map>
+#include <stdexcept>
+#include <vector>
+
+#include <boost/bind.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/function.hpp>
+#include <boost/ref.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/thread.hpp>
+#include <boost/thread/barrier.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/task.hpp>
+
+#include "test_functions.hpp"
+
+namespace pt = boost::posix_time;
+namespace tsk = boost::task;
+
+class test_in_thread
+{
+public:
+	// check submit
+	void test_case_1()
+	{
+		tsk::async_handle< int > h(
+			tsk::async_in_thread(
+				tsk::make_task(
+					fibonacci_fn,
+					10) ) );
+		BOOST_CHECK_EQUAL( h.get(), 55);
+	}
+
+	// check runs not in pool
+	void test_case_2()
+	{
+		tsk::async_handle< bool > h(
+			tsk::async_in_thread(
+				tsk::make_task(
+					runs_in_pool_fn) ) );
+		BOOST_CHECK_EQUAL( h.get(), false);
+	}
+
+	// don't execute twice
+	void test_case_3()
+	{
+		tsk::task< int > t(
+			tsk::make_task(
+				fibonacci_fn,
+				10) );
+		tsk::async_in_thread( t);
+		tsk::async_handle< int > h( tsk::async_in_thread( t) );
+		BOOST_CHECK_EQUAL( h.get(), 55);
+		bool thrown( false);
+		try
+		{ h.get(); }
+		catch ( tsk::task_already_executed const&)
+		{ thrown = true; }
+		BOOST_CHECK( thrown);
+	}
+
+	// check runtime_error thrown inside the task
+	void test_case_4()
+	{
+		tsk::async_handle< void > h(
+			tsk::async_in_thread(
+				tsk::make_task(
+					throwing_fn) ) );
+		bool thrown( false);
+		try
+		{ h.get(); }
+		catch ( std::runtime_error const&)
+		{ thrown = true; }
+		BOOST_CHECK( thrown);
+	}
+
+	// check interruptation
+	void test_case_5()
+	{
+		boost::barrier b( 2);
+		tsk::async_handle< void > h(
+			tsk::async_in_thread(
+				tsk::make_task(
+					barrier_fn,
+					boost::ref( b) ) ) );
+		h.interrupt();
+		b.wait();
+		bool thrown( false);
+		try
+		{ h.get(); }
+		catch ( tsk::task_interrupted const&)
+		{ thrown = true; }
+		BOOST_CHECK( thrown);
+	}
+};
+
+boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
+{
+	boost::unit_test::test_suite * test( BOOST_TEST_SUITE("Boost.Task: test suite") );
+
+	boost::shared_ptr< test_in_thread > instance( new test_in_thread() );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_thread::test_case_1, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_thread::test_case_2, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_thread::test_case_3, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_thread::test_case_4, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_thread::test_case_5, instance) );
+
+	return test;
+}
Added: sandbox/task/libs/task/test/test_in_unbounded_pool.cpp
==============================================================================
--- (empty file)
+++ sandbox/task/libs/task/test/test_in_unbounded_pool.cpp	2009-04-27 16:52:25 EDT (Mon, 27 Apr 2009)
@@ -0,0 +1,395 @@
+
+//          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 <cstdlib>
+#include <iostream>
+#include <map>
+#include <stdexcept>
+#include <vector>
+
+#include <boost/bind.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/function.hpp>
+#include <boost/ref.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/thread.hpp>
+#include <boost/thread/barrier.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/task.hpp>
+
+#include "test_functions.hpp"
+
+namespace pt = boost::posix_time;
+namespace tsk = boost::task;
+
+class test_in_unbounded_pool
+{
+public:
+	// check size, active, idle
+	void test_case_1()
+	{
+		tsk::pool<
+			tsk::unbounded_channel< tsk::fifo >
+		> pool( tsk::poolsize( 3) );
+		BOOST_CHECK_EQUAL( pool.size(), std::size_t( 3) );
+		BOOST_CHECK_EQUAL( pool.idle(), std::size_t( 3) );
+		BOOST_CHECK_EQUAL( pool.active(), std::size_t( 0) );
+	}
+
+	// check submit
+	void test_case_2()
+	{
+		tsk::pool<
+			tsk::unbounded_channel< tsk::fifo >
+		> pool( tsk::poolsize( 1) );
+		tsk::async_handle< int > h(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					fibonacci_fn,
+					10) ) );
+		BOOST_CHECK_EQUAL( h.get(), 55);
+	}
+
+	// check runs in pool
+	void test_case_3()
+	{
+		tsk::pool<
+			tsk::unbounded_channel< tsk::fifo >
+		> pool( tsk::poolsize( 1) );
+		tsk::async_handle< bool > h(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					runs_in_pool_fn) ) );
+		BOOST_CHECK_EQUAL( h.get(), true);
+	}
+
+	// don't execute twice
+	void test_case_4()
+	{
+		tsk::pool<
+			tsk::unbounded_channel< tsk::fifo >
+		> pool( tsk::poolsize( 1) );
+		tsk::task< int > t(
+			tsk::make_task(
+				fibonacci_fn,
+				10) );
+		tsk::async_handle< int > h(
+			tsk::async_in_pool(
+				pool,
+				t) );
+		BOOST_CHECK_EQUAL( h.get(), 55);
+		tsk::async_in_pool(
+			pool,
+			t);
+		bool thrown( false);
+		try
+		{ h.get(); }
+		catch ( tsk::task_already_executed const&)
+		{ thrown = true; }
+		BOOST_CHECK( thrown);
+	}
+
+	// check shutdown
+	void test_case_5()
+	{
+		tsk::pool<
+			tsk::unbounded_channel< tsk::fifo >
+		> pool( tsk::poolsize( 1) );
+		tsk::async_handle< int > h(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					fibonacci_fn,
+					10) ) );
+		pool.shutdown();
+		BOOST_CHECK( pool.closed() );
+		BOOST_CHECK_EQUAL( h.get(), 55);
+	}
+
+	// check runtime_error throw inside task
+	void test_case_6()
+	{
+		tsk::pool<
+			tsk::unbounded_channel< tsk::fifo >
+		> pool( tsk::poolsize( 1) );
+		tsk::async_handle< void > h(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					throwing_fn) ) );
+		pool.shutdown();
+		bool thrown( false);
+		try
+		{ h.get(); }
+		catch ( std::runtime_error const&)
+		{ thrown = true; }
+		BOOST_CHECK( thrown);
+	}
+
+	// check shutdown with task_rejected exception
+	void test_case_7()
+	{
+		tsk::pool<
+			tsk::unbounded_channel< tsk::fifo >
+		> pool( tsk::poolsize( 1) );
+		pool.shutdown();
+		BOOST_CHECK( pool.closed() );
+		bool thrown( false);
+		try
+		{
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					boost::bind(
+						fibonacci_fn,
+						10) ) );
+		}
+		catch ( tsk::task_rejected const&)
+		{ thrown = true; }
+		BOOST_CHECK( thrown);
+	}
+
+	// check shutdown_now with thread_interrupted exception
+	void test_case_8()
+	{
+		tsk::pool<
+			tsk::unbounded_channel< tsk::fifo >
+		> pool( tsk::poolsize( 1) );
+		tsk::async_handle< void > h(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					delay_fn,
+					pt::millisec( 500) ) ) );
+		boost::this_thread::sleep( pt::millisec( 250) );
+		BOOST_CHECK_EQUAL( pool.size(), std::size_t( 1) );
+		pool.shutdown_now();
+		BOOST_CHECK( pool.closed() );
+		BOOST_CHECK_EQUAL( pool.size(), std::size_t( 1) );
+		BOOST_CHECK_EQUAL( pool.idle(), std::size_t( 1) );
+		BOOST_CHECK_EQUAL( pool.active(), std::size_t( 0) );
+		bool thrown( false);
+		try
+		{ h.get(); }
+		catch ( tsk::task_interrupted const&)
+		{ thrown = true; }
+		BOOST_CHECK( thrown);
+	}
+
+	// check pending
+	void test_case_9()
+	{
+		typedef tsk::pool<
+			tsk::unbounded_channel< tsk::fifo >
+		> pool_type;
+		pool_type pool( tsk::poolsize( 1) );
+		boost::barrier b( 2);
+		tsk::async_handle< void > h1(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					barrier_fn,
+					boost::ref( b) ) ) );
+		boost::this_thread::sleep( pt::millisec( 250) );
+		BOOST_CHECK_EQUAL( pool.pending(), std::size_t( 0) );
+		tsk::async_handle< int > h2(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					fibonacci_fn,
+					10) ) );
+		boost::this_thread::sleep( pt::millisec(250) );
+		BOOST_CHECK_EQUAL( pool.pending(), std::size_t( 1) );
+		tsk::async_handle< int > h3(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					fibonacci_fn,
+					10) ) );
+		boost::this_thread::sleep( pt::millisec(250) );
+		BOOST_CHECK_EQUAL( pool.pending(), std::size_t( 2) );
+		b.wait();
+		h1.get();
+		BOOST_CHECK_EQUAL( h2.get(), 55);
+		BOOST_CHECK_EQUAL( h3.get(), 55);
+		BOOST_CHECK_EQUAL( pool.pending(), std::size_t( 0) );
+	}
+
+	// check interruptation
+	void test_case_10()
+	{
+		typedef tsk::pool<
+			tsk::unbounded_channel< tsk::fifo >
+		> pool_type;
+		pool_type pool( tsk::poolsize( 1) );
+		boost::barrier b( 2);
+		pool.submit(
+			tsk::make_task(
+				barrier_fn,
+				boost::ref( b) ) );
+		std::vector< int > buffer;
+		tsk::async_handle< void > h(
+			tsk::async_in_pool(
+				pool,
+				tsk::make_task(
+					buffer_fibonacci_fn,
+					boost::ref( buffer),
+					10) ) );
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				buffer_fibonacci_fn,
+				boost::ref( buffer),
+				0) );
+		h.interrupt();
+		b.wait();
+		pool.shutdown();
+		BOOST_CHECK_EQUAL( buffer[0], 0);
+		BOOST_CHECK_EQUAL( buffer.size(), std::size_t( 1) );
+		bool thrown( false);
+		try
+		{ h.get(); }
+		catch ( tsk::task_interrupted const&)
+		{ thrown = true; }
+		BOOST_CHECK( thrown);
+	}
+
+	// check fifo scheduling
+	void test_case_11()
+	{
+		typedef tsk::pool<
+			tsk::unbounded_channel< tsk::fifo >
+		> pool_type;
+		pool_type pool( tsk::poolsize( 1) );
+		boost::barrier b( 2);
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				barrier_fn,
+				boost::ref( b) ) );
+		std::vector< int > buffer;
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				buffer_fibonacci_fn,
+				boost::ref( buffer),
+				10) );
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				buffer_fibonacci_fn,
+				boost::ref( buffer),
+				0) );
+		b.wait();
+		pool.shutdown();
+		BOOST_CHECK_EQUAL( buffer[0], 55);
+		BOOST_CHECK_EQUAL( buffer[1], 0);
+		BOOST_CHECK_EQUAL( buffer.size(), std::size_t( 2) );
+	}
+
+	// check priority scheduling
+	void test_case_12()
+	{
+		typedef tsk::pool<
+			tsk::unbounded_channel< tsk::priority< int > >
+		> pool_type;
+		pool_type pool( tsk::poolsize( 1) );
+		boost::barrier b( 2);
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				barrier_fn,
+				boost::ref( b) ),
+			0);
+		std::vector< int > buffer;
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				buffer_fibonacci_fn,
+				boost::ref( buffer),
+				10),
+			1);
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				buffer_fibonacci_fn,
+				boost::ref( buffer),
+				0),
+			0);
+		b.wait();
+		pool.shutdown();
+		BOOST_CHECK_EQUAL( buffer[0], 0);
+		BOOST_CHECK_EQUAL( buffer[1], 55);
+		BOOST_CHECK_EQUAL( buffer.size(), std::size_t( 2) );
+	}
+
+	// check smart scheduling
+	void test_case_13()
+	{
+		typedef tsk::pool<
+			tsk::unbounded_channel< tsk::smart< int, std::less< int >, tsk::replace_oldest, tsk::take_oldest > >
+		> pool_type;
+		pool_type pool( tsk::poolsize( 1) );
+		boost::barrier b( 2);
+		pool.submit(
+			tsk::make_task(
+				barrier_fn,
+				boost::ref( b) ),
+			0);
+		std::vector< int > buffer;
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				buffer_fibonacci_fn,
+				boost::ref( buffer),
+				10),
+			2);
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				buffer_fibonacci_fn,
+				boost::ref( buffer),
+				0),
+			1);
+		tsk::async_in_pool(
+			pool,
+			tsk::make_task(
+				buffer_fibonacci_fn,
+				boost::ref( buffer),
+				1),
+			2);
+		b.wait();
+		pool.shutdown();
+		BOOST_CHECK_EQUAL( buffer[0], 0);
+		BOOST_CHECK_EQUAL( buffer[1], 1);
+		BOOST_CHECK_EQUAL( buffer.size(), std::size_t( 2) );
+	}
+};
+
+boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
+{
+	boost::unit_test::test_suite * test( BOOST_TEST_SUITE("Boost.Task: test suite") );
+
+	boost::shared_ptr< test_in_unbounded_pool > instance( new test_in_unbounded_pool() );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_unbounded_pool::test_case_1, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_unbounded_pool::test_case_2, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_unbounded_pool::test_case_3, instance) );
+//	test->add( BOOST_CLASS_TEST_CASE( & test_in_unbounded_pool::test_case_4, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_unbounded_pool::test_case_5, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_unbounded_pool::test_case_6, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_unbounded_pool::test_case_7, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_unbounded_pool::test_case_8, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_unbounded_pool::test_case_9, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_unbounded_pool::test_case_10, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_unbounded_pool::test_case_11, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_unbounded_pool::test_case_12, instance) );
+	test->add( BOOST_CLASS_TEST_CASE( & test_in_unbounded_pool::test_case_13, instance) );
+
+	return test;
+}