Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r56311 - in sandbox/task: boost boost/task boost/task/detail libs/task/build libs/task/doc libs/task/examples libs/task/src libs/task/test
From: oliver.kowalke_at_[hidden]
Date: 2009-09-19 15:06:53


Author: olli
Date: 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
New Revision: 56311
URL: http://svn.boost.org/trac/boost/changeset/56311

Log:
- takeover of 0.3.0 changes

Added:
   sandbox/task/boost/task/bounded_onelock_fifo.hpp (contents, props changed)
   sandbox/task/boost/task/bounded_onelock_prio_queue.hpp (contents, props changed)
   sandbox/task/boost/task/bounded_onelock_smart_queue.hpp (contents, props changed)
   sandbox/task/boost/task/bounded_twolock_fifo.hpp (contents, props changed)
   sandbox/task/boost/task/detail/smart.hpp (contents, props changed)
   sandbox/task/boost/task/local_rr_ums.hpp (contents, props changed)
   sandbox/task/boost/task/unbounded_onelock_fifo.hpp (contents, props changed)
   sandbox/task/boost/task/unbounded_onelock_prio_queue.hpp (contents, props changed)
   sandbox/task/boost/task/unbounded_onelock_smart_queue.hpp (contents, props changed)
   sandbox/task/boost/task/unbounded_twolock_fifo.hpp (contents, props changed)
   sandbox/task/libs/task/doc/queue.qbk (contents, props changed)
   sandbox/task/libs/task/src/context.cpp (contents, props changed)
   sandbox/task/libs/task/test/test_bounded_onelock_pool.cpp (contents, props changed)
   sandbox/task/libs/task/test/test_bounded_twolock_pool.cpp (contents, props changed)
   sandbox/task/libs/task/test/test_unbounded_onelock_pool.cpp (contents, props changed)
   sandbox/task/libs/task/test/test_unbounded_twolock_pool.cpp (contents, props changed)
Removed:
   sandbox/task/boost/task/bounded_channel.hpp
   sandbox/task/boost/task/detail/interrupter.hpp
   sandbox/task/boost/task/fifo.hpp
   sandbox/task/boost/task/priority.hpp
   sandbox/task/boost/task/smart.hpp
   sandbox/task/boost/task/unbounded_channel.hpp
   sandbox/task/libs/task/doc/channel.qbk
   sandbox/task/libs/task/examples/pending.cpp
   sandbox/task/libs/task/src/interrupter.cpp
   sandbox/task/libs/task/test/test_bounded_pool.cpp
   sandbox/task/libs/task/test/test_unbounded_pool.cpp
Text files modified:
   sandbox/task/boost/task.hpp | 14 +++-
   sandbox/task/boost/task/as_sub_task.hpp | 5 +
   sandbox/task/boost/task/async.hpp | 8 +-
   sandbox/task/boost/task/callable.hpp | 34 ++++--------
   sandbox/task/boost/task/context.hpp | 67 ++++++++++++++++++------
   sandbox/task/boost/task/detail/atomic_gcc_ppc.hpp | 4
   sandbox/task/boost/task/detail/atomic_gcc_x86.hpp | 4
   sandbox/task/boost/task/detail/atomic_interlocked.hpp | 4
   sandbox/task/boost/task/detail/atomic_solaris.hpp | 4
   sandbox/task/boost/task/detail/atomic_sync.hpp | 4
   sandbox/task/boost/task/detail/fiber_posix.hpp | 22 +-------
   sandbox/task/boost/task/detail/fiber_windows.hpp | 7 +-
   sandbox/task/boost/task/detail/pool_base.hpp | 79 ++++++++----------------------
   sandbox/task/boost/task/detail/worker.hpp | 47 ++++++++++++++---
   sandbox/task/boost/task/handle.hpp | 28 ++++------
   sandbox/task/boost/task/meta.hpp | 4
   sandbox/task/boost/task/new_thread.hpp | 9 +-
   sandbox/task/boost/task/own_thread.hpp | 4
   sandbox/task/boost/task/static_pool.hpp | 68 ++++++-------------------
   sandbox/task/libs/task/build/Jamfile.v2 | 8 +-
   sandbox/task/libs/task/doc/acknowledgements.qbk | 2
   sandbox/task/libs/task/doc/boost_task.qbk | 13 +---
   sandbox/task/libs/task/doc/fork_join.qbk | 6 -
   sandbox/task/libs/task/doc/introduction.qbk | 6 -
   sandbox/task/libs/task/doc/meta_functions.qbk | 6 -
   sandbox/task/libs/task/doc/overview.qbk | 6 -
   sandbox/task/libs/task/doc/pool.qbk | 11 +---
   sandbox/task/libs/task/doc/processor_binding.qbk | 4
   sandbox/task/libs/task/doc/ref_callable.qbk | 30 ++++++++---
   sandbox/task/libs/task/doc/ref_context.qbk | 56 ++++++++++++++++----
   sandbox/task/libs/task/doc/ref_handle.qbk | 13 ++++
   sandbox/task/libs/task/doc/ref_static_pool.qbk | 104 +++++++++------------------------------
   sandbox/task/libs/task/doc/ref_utility.qbk | 65 +++++++++++++++++++++++-
   sandbox/task/libs/task/doc/scheduler.qbk | 8 +-
   sandbox/task/libs/task/doc/shutdown.qbk | 12 ---
   sandbox/task/libs/task/doc/static_pool.qbk | 17 +-----
   sandbox/task/libs/task/doc/task.qbk | 6 -
   sandbox/task/libs/task/doc/todo.qbk | 4 -
   sandbox/task/libs/task/doc/user_defined_executor.qbk | 54 --------------------
   sandbox/task/libs/task/doc/utilities.qbk | 23 ++++++++
   sandbox/task/libs/task/doc/work_stealing.qbk | 2
   sandbox/task/libs/task/examples/Jamfile.v2 | 1
   sandbox/task/libs/task/examples/bind_to_processors.cpp | 2
   sandbox/task/libs/task/examples/buffer_multi.cpp | 2
   sandbox/task/libs/task/examples/buffer_multi2.cpp | 2
   sandbox/task/libs/task/examples/buffer_pool.cpp | 4 -
   sandbox/task/libs/task/examples/buffer_pool_thread.cpp | 4 -
   sandbox/task/libs/task/examples/fork_join.cpp | 2
   sandbox/task/libs/task/examples/interrupt.cpp | 4 -
   sandbox/task/libs/task/examples/no_deadlock_pool.cpp | 4 -
   sandbox/task/libs/task/examples/no_deadlock_pool3.cpp | 4 -
   sandbox/task/libs/task/examples/priority.cpp | 4 -
   sandbox/task/libs/task/examples/semaphore_pool.cpp | 4 -
   sandbox/task/libs/task/examples/semaphore_pool_thread.cpp | 4 -
   sandbox/task/libs/task/examples/shutdown_now.cpp | 4 -
   sandbox/task/libs/task/examples/smart.cpp | 8 --
   sandbox/task/libs/task/examples/submit.cpp | 6 -
   sandbox/task/libs/task/src/callable.cpp | 4 -
   sandbox/task/libs/task/test/Jamfile.v2 | 6 +
   sandbox/task/libs/task/test/test_as_sub_task.cpp | 3
   sandbox/task/libs/task/test/test_new_thread.cpp | 1
   sandbox/task/libs/task/test/test_own_thread.cpp | 1
   sandbox/task/libs/task/test/test_task.cpp | 1
   63 files changed, 432 insertions(+), 515 deletions(-)

Modified: sandbox/task/boost/task.hpp
==============================================================================
--- sandbox/task/boost/task.hpp (original)
+++ sandbox/task/boost/task.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -9,26 +9,30 @@
 
 #include <boost/task/as_sub_task.hpp>
 #include <boost/task/async.hpp>
-#include <boost/task/bounded_channel.hpp>
+#include <boost/task/bounded_twolock_fifo.hpp>
+#include <boost/task/bounded_onelock_fifo.hpp>
+#include <boost/task/bounded_onelock_prio_queue.hpp>
+#include <boost/task/bounded_onelock_smart_queue.hpp>
 #include <boost/task/callable.hpp>
 #include <boost/task/context.hpp>
 #include <boost/task/exceptions.hpp>
-#include <boost/task/fifo.hpp>
 #include <boost/task/future.hpp>
 #include <boost/task/handle.hpp>
+#include <boost/task/local_rr_ums.hpp>
 #include <boost/task/meta.hpp>
 #include <boost/task/new_thread.hpp>
 #include <boost/task/own_thread.hpp>
 #include <boost/task/poolsize.hpp>
-#include <boost/task/priority.hpp>
 #include <boost/task/scanns.hpp>
 #include <boost/task/semaphore.hpp>
 #include <boost/task/stacksize.hpp>
 #include <boost/task/static_pool.hpp>
-#include <boost/task/smart.hpp>
 #include <boost/task/task.hpp>
 #include <boost/task/unbounded_buffer.hpp>
-#include <boost/task/unbounded_channel.hpp>
+#include <boost/task/unbounded_twolock_fifo.hpp>
+#include <boost/task/unbounded_onelock_fifo.hpp>
+#include <boost/task/unbounded_onelock_prio_queue.hpp>
+#include <boost/task/unbounded_onelock_smart_queue.hpp>
 #include <boost/task/utility.hpp>
 #include <boost/task/watermark.hpp>
 

Modified: sandbox/task/boost/task/as_sub_task.hpp
==============================================================================
--- sandbox/task/boost/task/as_sub_task.hpp (original)
+++ sandbox/task/boost/task/as_sub_task.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -12,6 +12,7 @@
 #include <boost/function.hpp>
 #include <boost/thread/detail/move.hpp>
 
+#include <boost/task/callable.hpp>
 #include <boost/task/context.hpp>
 #include <boost/task/detail/worker.hpp>
 #include <boost/task/future.hpp>
@@ -43,8 +44,8 @@
                                         w,
                                         wcb) );
                         context ctx;
- handle< R > h( ctx.get_handle( f) );
- w->put( ctx.get_callable( boost::move( t) ) );
+ handle< R > h( f, ctx);
+ w->put( callable( boost::move( t), ctx) );
                         return h;
                 }
                 else

Modified: sandbox/task/boost/task/async.hpp
==============================================================================
--- sandbox/task/boost/task/async.hpp (original)
+++ sandbox/task/boost/task/async.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -27,12 +27,12 @@
 handle< R > async( task< R > t, EP ep)
 { return ep( boost::move( t) ); }
 
-template< typename R, typename Channel >
-handle< R > async( task< R > t, static_pool< Channel > & pool)
+template< typename R, typename Queue >
+handle< R > async( task< R > t, static_pool< Queue > & pool)
 { return pool.submit( boost::move( t) ); }
 
-template< typename R, typename Channel, typename Attr >
-handle< R > async( task< R > t, Attr attr, static_pool< Channel > & pool)
+template< typename R, typename Queue, typename Attr >
+handle< R > async( task< R > t, Attr attr, static_pool< Queue > & pool)
 { return pool.submit( boost::move( t), attr); }
 } }
 

Deleted: sandbox/task/boost/task/bounded_channel.hpp
==============================================================================
--- sandbox/task/boost/task/bounded_channel.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
+++ (empty file)
@@ -1,408 +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)
-
-#ifndef BOOST_TASK_BOUNDED_CHANNEL_H
-#define BOOST_TASK_BOUNDED_CHANNEL_H
-
-#include <cstddef>
-#include <vector>
-
-#include <boost/assert.hpp>
-#include <boost/bind.hpp>
-#include <boost/foreach.hpp>
-#include <boost/function.hpp>
-#include <boost/thread/condition.hpp>
-#include <boost/thread/locks.hpp>
-#include <boost/thread/shared_mutex.hpp>
-
-#include <boost/task/callable.hpp>
-#include <boost/task/exceptions.hpp>
-#include <boost/task/watermark.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-namespace boost { namespace task
-{
-template< typename SchedulingPolicy >
-class bounded_channel
-{
-public:
- typedef SchedulingPolicy scheduler_type;
- typedef typename scheduler_type::impl::item item;
-
-private:
- typedef typename scheduler_type::impl queue;
-
- enum channel_state
- {
- channel_active,
- channel_deactive,
- channel_deactive_now
- };
-
- channel_state state_;
- queue queue_;
- shared_mutex mtx_;
- condition not_empty_cond_;
- condition not_full_cond_;
- std::size_t hwm_;
- std::size_t lwm_;
-
- bool active_() const
- { return state_ == channel_active; }
-
- bool deactive_() const
- { return state_ == channel_deactive; }
-
- bool deactive_now_() const
- { return state_ == channel_deactive_now; }
-
- void activate_()
- { state_ = channel_active; }
-
- void clear_()
- {
- BOOST_ASSERT( ! active_() );
- queue_.clear();
- BOOST_ASSERT( empty_() );
- }
-
- void deactivate_()
- {
- if ( active_() )
- {
- state_ = channel_deactive;
- not_empty_cond_.notify_all();
- }
-
- BOOST_ASSERT( deactive_() );
- }
-
- void deactivate_now_()
- {
- if ( active_() )
- {
- state_ = channel_deactive_now;
- not_empty_cond_.notify_all();
- }
-
- BOOST_ASSERT( deactive_now_() );
- }
-
- const std::vector< callable > drain_()
- {
- BOOST_ASSERT( deactive_now_() );
- std::vector< callable > unprocessed;
- unprocessed.reserve( queue_.size() );
- BOOST_FOREACH( callable ca, queue_)
- { unprocessed.push_back( ca); }
- clear_();
- BOOST_ASSERT( empty_() );
- return unprocessed;
- }
-
- bool empty_() const
- { return queue_.empty(); }
-
- bool full_() const
- { return size_() >= hwm_; }
-
- std::size_t size_() const
- { return queue_.size(); }
-
- void upper_bound_( std::size_t hwm)
- {
- if ( lwm_ > hwm )
- throw invalid_watermark("low watermark must be less than or equal to high watermark");
- std::size_t tmp( hwm_);
- hwm_ = hwm;
- if ( hwm_ > tmp) not_full_cond_.notify_one();
- }
-
- void lower_bound_( std::size_t lwm)
- {
- if ( lwm > hwm_ )
- throw invalid_watermark("low watermark must be less than or equal to high watermark");
- std::size_t tmp( lwm_);
- lwm_ = lwm;
- if ( lwm_ > tmp) not_full_cond_.notify_one();
- }
-
- void put_(
- item const& itm,
- unique_lock< shared_mutex > & lk)
- {
- if ( full_() )
- {
- not_full_cond_.wait(
- lk,
- bind(
- & bounded_channel::producers_activate_,
- this) );
- }
- if ( ! active_() )
- throw task_rejected("channel is not active");
- queue_.push( itm);
- not_empty_cond_.notify_one();
- }
-
- template< typename Duration >
- void put_(
- item const& itm,
- Duration const& rel_time,
- unique_lock< shared_mutex > & lk)
- {
- if ( full_() )
- {
- if ( ! not_full_cond_.timed_wait(
- lk,
- rel_time,
- bind(
- & bounded_channel::producers_activate_,
- this) ) )
- throw task_rejected("timed out");
- }
- if ( ! active_() )
- throw task_rejected("channel is not active");
- queue_.push( itm);
- not_empty_cond_.notify_one();
- }
-
- bool take_(
- callable & ca,
- unique_lock< shared_mutex > & lk)
- {
- if ( deactive_now_() || ( deactive_() && empty_() ) )
- return false;
- if ( empty_() )
- {
- try
- {
- not_empty_cond_.wait(
- lk,
- bind(
- & bounded_channel::consumers_activate_,
- this) );
- }
- catch ( thread_interrupted const&)
- { return false; }
- }
- if ( deactive_now_() || ( deactive_() && empty_() ) )
- return false;
- queue_.pop( ca);
- if ( size_() <= lwm_)
- {
- if ( lwm_ == hwm_)
- not_full_cond_.notify_one();
- else
- // more than one producer could be waiting
- // for submiting an action object
- not_full_cond_.notify_all();
- }
- return ! ca.empty();
- }
-
- template< typename Duration >
- bool take_(
- callable & ca,
- Duration const& rel_time,
- unique_lock< shared_mutex > & lk)
- {
- if ( deactive_now_() || ( deactive_() && empty_() ) )
- return false;
- if ( empty_() )
- {
- try
- {
- if ( ! not_empty_cond_.timed_wait(
- lk,
- rel_time,
- bind(
- & bounded_channel::consumers_activate_,
- this) ) )
- return false;
- }
- catch ( thread_interrupted const&)
- { return false; }
- }
- if ( deactive_now_() || ( deactive_() && empty_() ) )
- return false;
- queue_.pop( ca);
- if ( size_() <= lwm_)
- {
- if ( lwm_ == hwm_)
- not_full_cond_.notify_one();
- else
- // more than one producer could be waiting
- // in order to submit an task
- not_full_cond_.notify_all();
- }
- return ! ca.empty();
- }
-
- bool try_take_( callable & ca)
- {
- if ( deactive_now_() || empty_() )
- return false;
- queue_.pop( ca);
- bool valid = ! ca.empty();
- if ( valid && size_() <= lwm_)
- {
- if ( lwm_ == hwm_)
- not_full_cond_.notify_one();
- else
- // more than one producer could be waiting
- // in order to submit an task
- not_full_cond_.notify_all();
- }
- return valid;
- }
-
- bool producers_activate_() const
- { return ! active_() || ! full_(); }
-
- bool consumers_activate_() const
- { return ! active_() || ! empty_(); }
-
-public:
- bounded_channel(
- high_watermark const& hwm,
- low_watermark const& lwm)
- :
- state_( channel_active),
- queue_(),
- mtx_(),
- not_empty_cond_(),
- not_full_cond_(),
- hwm_( hwm),
- lwm_( lwm)
- {
- if ( lwm_ > hwm_ )
- throw invalid_watermark("low watermark must be less than or equal to high watermark");
- }
-
- bool active()
- {
- lock_guard< shared_mutex > lk( mtx_);
- return active_();
- }
-
- void activate()
- {
- lock_guard< shared_mutex > lk( mtx_);
- activate_();
- }
-
- void clear()
- {
- lock_guard< shared_mutex > lk( mtx_);
- clear_();
- }
-
- bool deactive()
- { return ! active(); }
-
- void deactivate()
- {
- lock_guard< shared_mutex > lk( mtx_);
- deactivate_();
- }
-
- void deactivate_now()
- {
- lock_guard< shared_mutex > lk( mtx_);
- deactivate_now_();
- }
-
- const std::vector< callable > drain()
- {
- lock_guard< shared_mutex > lk( mtx_);
- return drain_();
- }
-
- bool empty()
- {
- lock_guard< shared_mutex > lk( mtx_);
- return empty_();
- }
-
- bool full()
- {
- lock_guard< shared_mutex > lk( mtx_);
- return full_();
- }
-
- std::size_t upper_bound()
- {
- lock_guard< shared_mutex > lk( mtx_);
- return hwm_;
- }
-
- void upper_bound( std::size_t hwm)
- {
- lock_guard< shared_mutex > lk( mtx_);
- upper_bound_( hwm);
- }
-
- std::size_t lower_bound()
- {
- lock_guard< shared_mutex > lk( mtx_);
- return lwm_;
- }
-
- void lower_bound( std::size_t lwm)
- {
- lock_guard< shared_mutex > lk( mtx_);
- lower_bound_( lwm);
- }
-
- std::size_t size()
- {
- lock_guard< shared_mutex > lk( mtx_);
- return size_();
- }
-
- void put( item const& itm)
- {
- unique_lock< shared_mutex > lk( mtx_);
- put_( itm, lk);
- }
-
- template< typename Duration >
- void put(
- item const& itm,
- Duration const& rel_time)
- {
- unique_lock< shared_mutex > lk( mtx_);
- put_( itm, rel_time, lk);
- }
-
- bool take( callable & ca)
- {
- unique_lock< shared_mutex > lk( mtx_);
- return take_( ca, lk);
- }
-
- template< typename Duration >
- bool take(
- callable & ca,
- Duration const& rel_time)
- {
- unique_lock< shared_mutex > lk( mtx_);
- return take_( ca, rel_time, lk);
- }
-
- bool try_take( callable & ca)
- {
- lock_guard< shared_mutex > lk( mtx_);
- return try_take_( ca);
- }
-};
-} }
-
-#include <boost/config/abi_suffix.hpp>
-
-#endif // BOOST_TASK_BOUNDED_CHANNEL_H

Added: sandbox/task/boost/task/bounded_onelock_fifo.hpp
==============================================================================
--- (empty file)
+++ sandbox/task/boost/task/bounded_onelock_fifo.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -0,0 +1,311 @@
+
+// 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_TASK_BOUNDED_ONELOCK_FIFO_H
+#define BOOST_TASK_BOUNDED_ONELOCK_FIFO_H
+
+#include <cstddef>
+#include <list>
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/foreach.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+
+#include <boost/task/callable.hpp>
+#include <boost/task/detail/atomic.hpp>
+#include <boost/task/detail/meta.hpp>
+#include <boost/task/exceptions.hpp>
+#include <boost/task/watermark.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost { namespace task
+{
+class bounded_onelock_fifo
+{
+public:
+ typedef detail::has_no_attribute attribute_tag_type;
+ typedef callable value_type;
+
+private:
+ typedef std::list< value_type > queue_type;
+
+ volatile uint32_t state_;
+ queue_type queue_;
+ shared_mutex mtx_;
+ condition not_empty_cond_;
+ condition not_full_cond_;
+ std::size_t hwm_;
+ std::size_t lwm_;
+
+ bool active_() const
+ { return 0 == state_; }
+
+ void deactivate_()
+ { detail::atomic_fetch_add( & state_, 1); }
+
+ bool empty_() const
+ { return queue_.empty(); }
+
+ bool full_() const
+ { return size_() >= hwm_; }
+
+ std::size_t size_() const
+ { return queue_.size(); }
+
+ void upper_bound_( std::size_t hwm)
+ {
+ if ( lwm_ > hwm )
+ throw invalid_watermark("low watermark must be less than or equal to high watermark");
+ std::size_t tmp( hwm_);
+ hwm_ = hwm;
+ if ( hwm_ > tmp) not_full_cond_.notify_one();
+ }
+
+ void lower_bound_( std::size_t lwm)
+ {
+ if ( lwm > hwm_ )
+ throw invalid_watermark("low watermark must be less than or equal to high watermark");
+ std::size_t tmp( lwm_);
+ lwm_ = lwm;
+ if ( lwm_ > tmp) not_full_cond_.notify_one();
+ }
+
+ void put_(
+ value_type const& va,
+ unique_lock< shared_mutex > & lk)
+ {
+ if ( full_() )
+ {
+ not_full_cond_.wait(
+ lk,
+ bind(
+ & bounded_onelock_fifo::producers_activate_,
+ this) );
+ }
+ if ( ! active_() )
+ throw task_rejected("queue is not active");
+ queue_.push_back( va);
+ not_empty_cond_.notify_one();
+ }
+
+ template< typename Duration >
+ void put_(
+ value_type const& va,
+ Duration const& rel_time,
+ unique_lock< shared_mutex > & lk)
+ {
+ if ( full_() )
+ {
+ if ( ! not_full_cond_.timed_wait(
+ lk,
+ rel_time,
+ bind(
+ & bounded_onelock_fifo::producers_activate_,
+ this) ) )
+ throw task_rejected("timed out");
+ }
+ if ( ! active_() )
+ throw task_rejected("queue is not active");
+ queue_.push_back( va);
+ not_empty_cond_.notify_one();
+ }
+
+ bool take_(
+ value_type & va,
+ unique_lock< shared_mutex > & lk)
+ {
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ not_empty_cond_.wait(
+ lk,
+ bind(
+ & bounded_onelock_fifo::consumers_activate_,
+ this) );
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ va.swap( queue_.front() );
+ queue_.pop_front();
+ if ( size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // for submiting an action object
+ not_full_cond_.notify_all();
+ }
+ return ! va.empty();
+ }
+
+ template< typename Duration >
+ bool take_(
+ value_type & va,
+ Duration const& rel_time,
+ unique_lock< shared_mutex > & lk)
+ {
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ if ( ! not_empty_cond_.timed_wait(
+ lk,
+ rel_time,
+ bind(
+ & bounded_onelock_fifo::consumers_activate_,
+ this) ) )
+ return false;
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ va.swap( queue_.front() );
+ queue_.pop_front();
+ if ( size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // in order to submit an task
+ not_full_cond_.notify_all();
+ }
+ return ! va.empty();
+ }
+
+ bool try_take_( value_type & va)
+ {
+ if ( empty_() )
+ return false;
+ va.swap( queue_.front() );
+ queue_.pop_front();
+ bool valid = ! va.empty();
+ if ( valid && size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // in order to submit an task
+ not_full_cond_.notify_all();
+ }
+ return valid;
+ }
+
+ bool producers_activate_() const
+ { return ! active_() || ! full_(); }
+
+ bool consumers_activate_() const
+ { return ! active_() || ! empty_(); }
+
+public:
+ bounded_onelock_fifo(
+ high_watermark const& hwm,
+ low_watermark const& lwm)
+ :
+ state_( 0),
+ queue_(),
+ mtx_(),
+ not_empty_cond_(),
+ not_full_cond_(),
+ hwm_( hwm),
+ lwm_( lwm)
+ {
+ if ( lwm_ > hwm_ )
+ throw invalid_watermark("low watermark must be less than or equal to high watermark");
+ }
+
+ void deactivate()
+ { deactivate_(); }
+
+ bool empty()
+ {
+ shared_lock< shared_mutex > lk( mtx_);
+ return empty_();
+ }
+
+ std::size_t upper_bound()
+ {
+ shared_lock< shared_mutex > lk( mtx_);
+ return hwm_;
+ }
+
+ void upper_bound( std::size_t hwm)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ upper_bound_( hwm);
+ }
+
+ std::size_t lower_bound()
+ {
+ shared_lock< shared_mutex > lk( mtx_);
+ return lwm_;
+ }
+
+ void lower_bound( std::size_t lwm)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ lower_bound_( lwm);
+ }
+
+ void put( value_type const& va)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ put_( va, lk);
+ }
+
+ template< typename Duration >
+ void put(
+ value_type const& va,
+ Duration const& rel_time)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ put_( va, rel_time, lk);
+ }
+
+ bool take( value_type & va)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return take_( va, lk);
+ }
+
+ template< typename Duration >
+ bool take(
+ value_type & va,
+ Duration const& rel_time)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return take_( va, rel_time, lk);
+ }
+
+ bool try_take( value_type & va)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return try_take_( va);
+ }
+};
+} }
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_TASK_BOUNDED_ONELOCK_FIFO_H

Added: sandbox/task/boost/task/bounded_onelock_prio_queue.hpp
==============================================================================
--- (empty file)
+++ sandbox/task/boost/task/bounded_onelock_prio_queue.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -0,0 +1,348 @@
+
+// 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_TASK_BOUNDED_ONELOCK_PRIO_QUEUE_H
+#define BOOST_TASK_BOUNDED_ONELOCK_PRIO_QUEUE_H
+
+#include <algorithm>
+#include <cstddef>
+#include <functional>
+#include <queue>
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/foreach.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+
+#include <boost/task/callable.hpp>
+#include <boost/task/detail/atomic.hpp>
+#include <boost/task/detail/meta.hpp>
+#include <boost/task/exceptions.hpp>
+#include <boost/task/watermark.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost { namespace task
+{
+template<
+ typename Attr,
+ typename Comp = std::less< Attr >
+>
+class bounded_onelock_prio_queue
+{
+public:
+ typedef detail::has_attribute attribute_tag_type;
+ typedef Attr attribute_type;
+
+ struct value_type
+ {
+ callable ca;
+ attribute_type attr;
+
+ value_type(
+ callable const& ca_,
+ attribute_type const& attr_)
+ : ca( ca_), attr( attr_)
+ { BOOST_ASSERT( ! ca.empty() ); }
+
+ void swap( value_type & other)
+ {
+ ca.swap( other.ca);
+ std::swap( attr, other.attr);
+ }
+ };
+
+private:
+ struct compare : public std::binary_function< value_type, value_type, bool >
+ {
+ bool operator()( value_type const& va1, value_type const& va2)
+ { return Comp()( va1.attr, va2.attr); }
+ };
+
+ typedef std::priority_queue<
+ value_type,
+ std::deque< value_type >,
+ compare
+ > queue_type;
+
+ volatile uint32_t state_;
+ queue_type queue_;
+ shared_mutex mtx_;
+ condition not_empty_cond_;
+ condition not_full_cond_;
+ std::size_t hwm_;
+ std::size_t lwm_;
+
+ bool active_() const
+ { return 0 == state_; }
+
+ void deactivate_()
+ { detail::atomic_fetch_add( & state_, 1); }
+
+ bool empty_() const
+ { return queue_.empty(); }
+
+ bool full_() const
+ { return size_() >= hwm_; }
+
+ std::size_t size_() const
+ { return queue_.size(); }
+
+ void upper_bound_( std::size_t hwm)
+ {
+ if ( lwm_ > hwm )
+ throw invalid_watermark("low watermark must be less than or equal to high watermark");
+ std::size_t tmp( hwm_);
+ hwm_ = hwm;
+ if ( hwm_ > tmp) not_full_cond_.notify_one();
+ }
+
+ void lower_bound_( std::size_t lwm)
+ {
+ if ( lwm > hwm_ )
+ throw invalid_watermark("low watermark must be less than or equal to high watermark");
+ std::size_t tmp( lwm_);
+ lwm_ = lwm;
+ if ( lwm_ > tmp) not_full_cond_.notify_one();
+ }
+
+ void put_(
+ value_type const& va,
+ unique_lock< shared_mutex > & lk)
+ {
+ if ( full_() )
+ {
+ not_full_cond_.wait(
+ lk,
+ bind(
+ & bounded_onelock_prio_queue::producers_activate_,
+ this) );
+ }
+ if ( ! active_() )
+ throw task_rejected("queue is not active");
+ queue_.push( va);
+ not_empty_cond_.notify_one();
+ }
+
+ template< typename Duration >
+ void put_(
+ value_type const& va,
+ Duration const& rel_time,
+ unique_lock< shared_mutex > & lk)
+ {
+ if ( full_() )
+ {
+ if ( ! not_full_cond_.timed_wait(
+ lk,
+ rel_time,
+ bind(
+ & bounded_onelock_prio_queue::producers_activate_,
+ this) ) )
+ throw task_rejected("timed out");
+ }
+ if ( ! active_() )
+ throw task_rejected("queue is not active");
+ queue_.push( va);
+ not_empty_cond_.notify_one();
+ }
+
+ bool take_(
+ callable & ca,
+ unique_lock< shared_mutex > & lk)
+ {
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ not_empty_cond_.wait(
+ lk,
+ bind(
+ & bounded_onelock_prio_queue::consumers_activate_,
+ this) );
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ callable tmp( queue_.top().ca);
+ queue_.pop();
+ ca.swap( tmp);
+ if ( size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // for submiting an action object
+ not_full_cond_.notify_all();
+ }
+ return ! ca.empty();
+ }
+
+ template< typename Duration >
+ bool take_(
+ callable & ca,
+ Duration const& rel_time,
+ unique_lock< shared_mutex > & lk)
+ {
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ if ( ! not_empty_cond_.timed_wait(
+ lk,
+ rel_time,
+ bind(
+ & bounded_onelock_prio_queue::consumers_activate_,
+ this) ) )
+ return false;
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ callable tmp( queue_.top().ca);
+ queue_.pop();
+ ca.swap( tmp);
+ if ( size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // in order to submit an task
+ not_full_cond_.notify_all();
+ }
+ return ! ca.empty();
+ }
+
+ bool try_take_( callable & ca)
+ {
+ if ( empty_() )
+ return false;
+ callable tmp( queue_.top().ca);
+ queue_.pop();
+ ca.swap( tmp);
+ bool valid = ! ca.empty();
+ if ( valid && size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // in order to submit an task
+ not_full_cond_.notify_all();
+ }
+ return valid;
+ }
+
+ bool producers_activate_() const
+ { return ! active_() || ! full_(); }
+
+ bool consumers_activate_() const
+ { return ! active_() || ! empty_(); }
+
+public:
+ bounded_onelock_prio_queue(
+ high_watermark const& hwm,
+ low_watermark const& lwm)
+ :
+ state_( 0),
+ queue_(),
+ mtx_(),
+ not_empty_cond_(),
+ not_full_cond_(),
+ hwm_( hwm),
+ lwm_( lwm)
+ {
+ if ( lwm_ > hwm_ )
+ throw invalid_watermark("low watermark must be less than or equal to high watermark");
+ }
+
+ void deactivate()
+ { deactivate_(); }
+
+ bool empty()
+ {
+ shared_lock< shared_mutex > lk( mtx_);
+ return empty_();
+ }
+
+ std::size_t upper_bound()
+ {
+ shared_lock< shared_mutex > lk( mtx_);
+ return hwm_;
+ }
+
+ void upper_bound( std::size_t hwm)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ upper_bound_( hwm);
+ }
+
+ std::size_t lower_bound()
+ {
+ shared_lock< shared_mutex > lk( mtx_);
+ return lwm_;
+ }
+
+ void lower_bound( std::size_t lwm)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ lower_bound_( lwm);
+ }
+
+ void put( value_type const& va)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ put_( va, lk);
+ }
+
+ template< typename Duration >
+ void put(
+ value_type const& va,
+ Duration const& rel_time)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ put_( va, rel_time, lk);
+ }
+
+ bool take( callable & ca)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return take_( ca, lk);
+ }
+
+ template< typename Duration >
+ bool take(
+ callable & ca,
+ Duration const& rel_time)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return take_( ca, rel_time, lk);
+ }
+
+ bool try_take( callable & ca)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return try_take_( ca);
+ }
+};
+} }
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_TASK_BOUNDED_ONELOCK_PRIO_QUEUE_H

Added: sandbox/task/boost/task/bounded_onelock_smart_queue.hpp
==============================================================================
--- (empty file)
+++ sandbox/task/boost/task/bounded_onelock_smart_queue.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -0,0 +1,355 @@
+
+// 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_TASK_BOUNDED_ONELOCK_SMART_QUEUE_H
+#define BOOST_TASK_BOUNDED_ONELOCK_SMART_QUEUE_H
+
+#include <algorithm>
+#include <cstddef>
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/foreach.hpp>
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+
+#include <boost/task/callable.hpp>
+#include <boost/task/detail/atomic.hpp>
+#include <boost/task/detail/meta.hpp>
+#include <boost/task/detail/smart.hpp>
+#include <boost/task/exceptions.hpp>
+#include <boost/task/watermark.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost { namespace task
+{
+template<
+ typename Attr,
+ typename Comp,
+ typename Enq = detail::replace_oldest,
+ typename Deq = detail::take_oldest
+>
+class bounded_onelock_smart_queue
+{
+public:
+ typedef detail::has_attribute attribute_tag_type;
+ typedef Attr attribute_type;
+
+ struct value_type
+ {
+ callable ca;
+ attribute_type attr;
+
+ value_type(
+ callable const& ca_,
+ attribute_type const& attr_)
+ : ca( ca_), attr( attr_)
+ { BOOST_ASSERT( ! ca.empty() ); }
+
+ void swap( value_type & other)
+ {
+ ca.swap( other.ca);
+ std::swap( attr, other.attr);
+ }
+ };
+
+private:
+ typedef multi_index::multi_index_container<
+ value_type,
+ multi_index::indexed_by<
+ multi_index::ordered_non_unique<
+ multi_index::member<
+ value_type,
+ Attr,
+ & value_type::attr
+ >,
+ Comp
+ >
+ >
+ > queue_type;
+ typedef typename queue_type::template nth_index< 0 >::type queue_index;
+
+ volatile uint32_t state_;
+ queue_type queue_;
+ queue_index & idx_;
+ shared_mutex mtx_;
+ condition not_empty_cond_;
+ condition not_full_cond_;
+ Enq enq_op_;
+ Deq deq_op_;
+ std::size_t hwm_;
+ std::size_t lwm_;
+
+ bool active_() const
+ { return 0 == state_; }
+
+ void deactivate_()
+ { detail::atomic_fetch_add( & state_, 1); }
+
+ bool empty_() const
+ { return queue_.empty(); }
+
+ bool full_() const
+ { return size_() >= hwm_; }
+
+ std::size_t size_() const
+ { return queue_.size(); }
+
+ void upper_bound_( std::size_t hwm)
+ {
+ if ( lwm_ > hwm )
+ throw invalid_watermark("low watermark must be less than or equal to high watermark");
+ std::size_t tmp( hwm_);
+ hwm_ = hwm;
+ if ( hwm_ > tmp) not_full_cond_.notify_one();
+ }
+
+ void lower_bound_( std::size_t lwm)
+ {
+ if ( lwm > hwm_ )
+ throw invalid_watermark("low watermark must be less than or equal to high watermark");
+ std::size_t tmp( lwm_);
+ lwm_ = lwm;
+ if ( lwm_ > tmp) not_full_cond_.notify_one();
+ }
+
+ void put_(
+ value_type const& va,
+ unique_lock< shared_mutex > & lk)
+ {
+ if ( full_() )
+ {
+ not_full_cond_.wait(
+ lk,
+ bind(
+ & bounded_onelock_smart_queue::producers_activate_,
+ this) );
+ }
+ if ( ! active_() )
+ throw task_rejected("queue is not active");
+ enq_op_( idx_, va);
+ not_empty_cond_.notify_one();
+ }
+
+ template< typename Duration >
+ void put_(
+ value_type const& va,
+ Duration const& rel_time,
+ unique_lock< shared_mutex > & lk)
+ {
+ if ( full_() )
+ {
+ if ( ! not_full_cond_.timed_wait(
+ lk,
+ rel_time,
+ bind(
+ & bounded_onelock_smart_queue::producers_activate_,
+ this) ) )
+ throw task_rejected("timed out");
+ }
+ if ( ! active_() )
+ throw task_rejected("queue is not active");
+ enq_op_( idx_, va);
+ not_empty_cond_.notify_one();
+ }
+
+ bool take_(
+ callable & ca,
+ unique_lock< shared_mutex > & lk)
+ {
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ not_empty_cond_.wait(
+ lk,
+ bind(
+ & bounded_onelock_smart_queue::consumers_activate_,
+ this) );
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ deq_op_( idx_, ca);
+ if ( size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // for submiting an action object
+ not_full_cond_.notify_all();
+ }
+ return ! ca.empty();
+ }
+
+ template< typename Duration >
+ bool take_(
+ callable & ca,
+ Duration const& rel_time,
+ unique_lock< shared_mutex > & lk)
+ {
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ if ( ! not_empty_cond_.timed_wait(
+ lk,
+ rel_time,
+ bind(
+ & bounded_onelock_smart_queue::consumers_activate_,
+ this) ) )
+ return false;
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ deq_op_( idx_, ca);
+ if ( size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // in order to submit an task
+ not_full_cond_.notify_all();
+ }
+ return ! ca.empty();
+ }
+
+ bool try_take_( callable & ca)
+ {
+ if ( empty_() )
+ return false;
+ deq_op_( idx_, ca);
+ bool valid = ! ca.empty();
+ if ( valid && size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // in order to submit an task
+ not_full_cond_.notify_all();
+ }
+ return valid;
+ }
+
+ bool producers_activate_() const
+ { return ! active_() || ! full_(); }
+
+ bool consumers_activate_() const
+ { return ! active_() || ! empty_(); }
+
+public:
+ bounded_onelock_smart_queue(
+ high_watermark const& hwm,
+ low_watermark const& lwm)
+ :
+ state_( 0),
+ queue_(),
+ idx_( queue_.get< 0 >() ),
+ mtx_(),
+ not_empty_cond_(),
+ not_full_cond_(),
+ enq_op_(),
+ deq_op_(),
+ hwm_( hwm),
+ lwm_( lwm)
+ {
+ if ( lwm_ > hwm_ )
+ throw invalid_watermark("low watermark must be less than or equal to high watermark");
+ }
+
+ void deactivate()
+ { deactivate_(); }
+
+ bool empty()
+ {
+ shared_lock< shared_mutex > lk( mtx_);
+ return empty_();
+ }
+
+ std::size_t upper_bound()
+ {
+ shared_lock< shared_mutex > lk( mtx_);
+ return hwm_;
+ }
+
+ void upper_bound( std::size_t hwm)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ upper_bound_( hwm);
+ }
+
+ std::size_t lower_bound()
+ {
+ shared_lock< shared_mutex > lk( mtx_);
+ return lwm_;
+ }
+
+ void lower_bound( std::size_t lwm)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ lower_bound_( lwm);
+ }
+
+ void put( value_type const& va)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ put_( va, lk);
+ }
+
+ template< typename Duration >
+ void put(
+ value_type const& va,
+ Duration const& rel_time)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ put_( va, rel_time, lk);
+ }
+
+ bool take( callable & ca)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return take_( ca, lk);
+ }
+
+ template< typename Duration >
+ bool take(
+ callable & ca,
+ Duration const& rel_time)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return take_( ca, rel_time, lk);
+ }
+
+ bool try_take( callable & ca)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return try_take_( ca);
+ }
+};
+} }
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_TASK_BOUNDED_ONELOCK_SMART_QUEUE_H

Added: sandbox/task/boost/task/bounded_twolock_fifo.hpp
==============================================================================
--- (empty file)
+++ sandbox/task/boost/task/bounded_twolock_fifo.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -0,0 +1,275 @@
+
+// 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_TASK_BOUNDED_TWOLOCK_FIFO_H
+#define BOOST_TASK_BOUNDED_TWOLOCK_FIFO_H
+
+#include <cstddef>
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/foreach.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+
+#include <boost/task/callable.hpp>
+#include <boost/task/detail/atomic.hpp>
+#include <boost/task/detail/meta.hpp>
+#include <boost/task/exceptions.hpp>
+#include <boost/task/watermark.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost { namespace task
+{
+class bounded_twolock_fifo
+{
+public:
+ typedef detail::has_no_attribute attribute_tag_type;
+ typedef callable value_type;
+
+private:
+ struct node
+ {
+ typedef shared_ptr< node > sptr_t;
+
+ value_type va;
+ sptr_t next;
+ };
+
+ volatile uint32_t state_;
+ volatile uint32_t count_;
+ node::sptr_t head_;
+ mutex head_mtx_;
+ node::sptr_t tail_;
+ mutex tail_mtx_;
+ condition not_empty_cond_;
+ condition not_full_cond_;
+ std::size_t hwm_;
+ std::size_t lwm_;
+
+ bool active_() const
+ { return 0 == state_; }
+
+ void deactivate_()
+ { detail::atomic_fetch_add( & state_, 1); }
+
+ uint32_t size_()
+ { return count_; }
+
+ bool empty_()
+ { return head_ == get_tail_(); }
+
+ bool full_()
+ { return size_() >= hwm_; }
+
+ node::sptr_t get_tail_()
+ {
+ lock_guard< mutex > lk( tail_mtx_);
+ node::sptr_t tmp = tail_;
+ return tmp;
+ }
+
+ node::sptr_t pop_head_()
+ {
+ node::sptr_t old_head = head_;
+ head_ = old_head->next;
+ detail::atomic_fetch_sub( & count_, 1);
+ return old_head;
+ }
+
+public:
+ bounded_twolock_fifo(
+ high_watermark const& hwm,
+ low_watermark const& lwm)
+ :
+ state_( 0),
+ count_( 0),
+ head_( new node),
+ head_mtx_(),
+ tail_( head_),
+ tail_mtx_(),
+ not_empty_cond_(),
+ not_full_cond_(),
+ hwm_( hwm),
+ lwm_( lwm)
+ {}
+
+ void upper_bound_( std::size_t hwm)
+ {
+ if ( lwm_ > hwm )
+ throw invalid_watermark("low watermark must be less than or equal to high watermark");
+ std::size_t tmp( hwm_);
+ hwm_ = hwm;
+ if ( hwm_ > tmp) not_full_cond_.notify_one();
+ }
+
+ std::size_t upper_bound()
+ { return hwm_; }
+
+ void lower_bound_( std::size_t lwm)
+ {
+ if ( lwm > hwm_ )
+ throw invalid_watermark("low watermark must be less than or equal to high watermark");
+ std::size_t tmp( lwm_);
+ lwm_ = lwm;
+ if ( lwm_ > tmp) not_full_cond_.notify_one();
+ }
+
+ std::size_t lower_bound()
+ { return lwm_; }
+
+ void deactivate()
+ { deactivate_(); }
+
+ bool empty()
+ {
+ unique_lock< mutex > lk( head_mtx_);
+ return empty_();
+ }
+
+ void put( value_type const& va)
+ {
+ node::sptr_t new_node( new node);
+ {
+ unique_lock< mutex > lk( tail_mtx_);
+
+ if ( full_() )
+ {
+ while ( active_() && full_() )
+ not_full_cond_.wait( lk);
+ }
+ if ( ! active_() )
+ throw task_rejected("queue is not active");
+
+ tail_->va = va;
+ tail_->next = new_node;
+ tail_ = new_node;
+ detail::atomic_fetch_add( & count_, 1);
+ }
+ not_empty_cond_.notify_one();
+ }
+
+ template< typename Duration >
+ void put(
+ value_type const& va,
+ Duration const& rel_time)
+ {
+ node::sptr_t new_node( new node);
+ {
+ unique_lock< mutex > lk( tail_mtx_);
+
+ if ( full_() )
+ {
+ while ( active_() && full_() )
+ if ( ! not_full_cond_.wait( lk, rel_time) )
+ throw task_rejected("timed out");
+ }
+ if ( ! active_() )
+ throw task_rejected("queue is not active");
+
+ tail_->va = va;
+ tail_->next = new_node;
+ tail_ = new_node;
+ detail::atomic_fetch_add( & count_, 1);
+ }
+ not_empty_cond_.notify_one();
+ }
+
+ bool take( value_type & va)
+ {
+ unique_lock< mutex > lk( head_mtx_);
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ while ( active_() && empty_() )
+ not_empty_cond_.wait( lk);
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ va.swap( head_->va);
+ pop_head_();
+ if ( size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // for submiting an action object
+ not_full_cond_.notify_all();
+ }
+ return ! va.empty();
+ }
+
+ template< typename Duration >
+ bool take(
+ value_type & va,
+ Duration const& rel_time)
+ {
+ unique_lock< mutex > lk( head_mtx_);
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ while ( active_() && empty_() )
+ if ( ! not_empty_cond_.timed_wait( lk, rel_time) )
+ return false;
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ va.swap( head_->va);
+ pop_head_();
+ if ( size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // for submiting an action object
+ not_full_cond_.notify_all();
+ }
+ return ! va.empty();
+ }
+
+ bool try_take( value_type & va)
+ {
+ unique_lock< mutex > lk( head_mtx_);
+ if ( empty_() )
+ return false;
+ va.swap( head_->va);
+ pop_head_();
+ bool valid = ! va.empty();
+ if ( valid && size_() <= lwm_)
+ {
+ if ( lwm_ == hwm_)
+ not_full_cond_.notify_one();
+ else
+ // more than one producer could be waiting
+ // in order to submit an task
+ not_full_cond_.notify_all();
+ }
+ return valid;
+ }
+};
+} }
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_TASK_BOUNDED_TWOLOCK_FIFO_H

Modified: sandbox/task/boost/task/callable.hpp
==============================================================================
--- sandbox/task/boost/task/callable.hpp (original)
+++ sandbox/task/boost/task/callable.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -11,8 +11,8 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/thread.hpp>
 
+#include <boost/task/context.hpp>
 #include <boost/task/detail/config.hpp>
-#include <boost/task/detail/interrupter.hpp>
 #include <boost/task/task.hpp>
 
 #include <boost/config/abi_prefix.hpp>
@@ -25,18 +25,13 @@
 namespace boost { namespace task
 {
 
-class context;
-
 class BOOST_TASK_DECL callable
 {
 private:
- friend class context;
-
         struct impl
         {
                 virtual ~impl() {}
                 virtual void run() = 0;
- virtual void reset() = 0;
                 virtual void reset( shared_ptr< thread > const&) = 0;
         };
 
@@ -44,46 +39,41 @@
         class impl_wrapper : public impl
         {
         private:
- task< R > t_;
- detail::interrupter intr_;
+ task< R > t_;
+ context ctx_;
 
         public:
                 impl_wrapper(
                         task< R > t,
- detail::interrupter const& intr)
- : t_( boost::move( t) ), intr_( intr)
+ context const& ctx)
+ : t_( boost::move( t) ), ctx_( ctx)
                 {}
 
                 void run()
                 { t_(); }
 
- void reset()
- { intr_.reset(); }
-
                 void reset( shared_ptr< thread > const& thrd)
- { intr_.reset( thrd); }
+ { ctx_.reset( thrd); }
         };
 
         shared_ptr< impl > impl_;
 
+public:
+ callable();
+
         template< typename R >
         callable(
                 task< R > t,
- detail::interrupter const& intr)
- : impl_( new impl_wrapper< R >( boost::move( t), intr) )
+ context const& ctx)
+ : impl_( new impl_wrapper< R >( boost::move( t), ctx) )
         {}
 
-public:
- callable();
-
         void operator()();
 
         bool empty() const;
 
         void clear();
 
- void reset();
-
         void reset( shared_ptr< thread > const&);
 
         void swap( callable &);
@@ -100,7 +90,7 @@
         { ca_.reset( thrd); }
 
         ~context_guard()
- { ca_.reset(); }
+ { ca_.clear(); }
 };
 
 }}

Modified: sandbox/task/boost/task/context.hpp
==============================================================================
--- sandbox/task/boost/task/context.hpp (original)
+++ sandbox/task/boost/task/context.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -8,36 +8,67 @@
 #define BOOST_TASK_CONTEXT_H
 
 #include <boost/shared_ptr.hpp>
-#include <boost/thread/detail/move.hpp>
+#include <boost/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/utility.hpp>
 
-#include <boost/task/callable.hpp>
-#include <boost/task/detail/interrupter.hpp>
-#include <boost/task/future.hpp>
-#include <boost/task/handle.hpp>
-#include <boost/task/task.hpp>
+#include <boost/task/detail/config.hpp>
 
 #include <boost/config/abi_prefix.hpp>
 
+# if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable:4251 4275)
+# endif
+
 namespace boost { namespace task
 {
-
-class context
+class BOOST_TASK_DECL context
 {
 private:
- detail::interrupter intr_;
+ class impl : private noncopyable
+ {
+ private:
+ bool requested_;
+ mutex mtx_;
+ shared_ptr< thread > thrd_;
+
+ void reset_( shared_ptr< thread > const& thrd);
+
+ void interrupt_();
+
+ public:
+ impl();
+
+ void reset( shared_ptr< thread > const& thrd);
+
+ void interrupt();
+
+ bool interruption_requested();
+ };
+
+ shared_ptr< impl > impl_;
 
 public:
- template< typename R >
- callable get_callable( task< R > t)
- { return callable( boost::move( t), intr_); }
-
- template< typename R >
- handle< R > get_handle( shared_future< R > f)
- { return handle< R >( f, intr_); }
-};
+ context();
+
+ void reset( shared_ptr< thread > const& thrd);
+
+ void interrupt();
 
+ bool interruption_requested();
+
+ void swap( context & other);
+};
 }}
 
+# if defined(BOOST_MSVC)
+# pragma warning(pop)
+# endif
+
 #include <boost/config/abi_suffix.hpp>
 
-#endif // BOOST_TASK_CONTEXT_H
+#endif // BOOST_TASK_DETAIL_context_H

Modified: sandbox/task/boost/task/detail/atomic_gcc_ppc.hpp
==============================================================================
--- sandbox/task/boost/task/detail/atomic_gcc_ppc.hpp (original)
+++ sandbox/task/boost/task/detail/atomic_gcc_ppc.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -51,7 +51,7 @@
                 : "memory", "cc"
         );
 
- return ++r;
+ return r;
 }
 
 inline
@@ -73,7 +73,7 @@
                 : "memory", "cc"
         );
 
- return --r;
+ return r;
 }
 } } }
 

Modified: sandbox/task/boost/task/detail/atomic_gcc_x86.hpp
==============================================================================
--- sandbox/task/boost/task/detail/atomic_gcc_x86.hpp (original)
+++ sandbox/task/boost/task/detail/atomic_gcc_x86.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -41,7 +41,7 @@
                 "memory", "cc"
         );
 
- return ++r;
+ return r;
 }
 
 inline
@@ -59,7 +59,7 @@
                 "memory", "cc"
         );
 
- return --r;
+ return r;
 }
 } } }
 

Modified: sandbox/task/boost/task/detail/atomic_interlocked.hpp
==============================================================================
--- sandbox/task/boost/task/detail/atomic_interlocked.hpp (original)
+++ sandbox/task/boost/task/detail/atomic_interlocked.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -25,14 +25,14 @@
 uint32_t atomic_fetch_add( uint32_t volatile * object, uint32_t operand)
 {
         BOOST_ASSERT( operand == 1);
- return BOOST_INTERLOCKED_INCREMENT( reinterpret_cast< long volatile * >( object) );
+ return BOOST_INTERLOCKED_INCREMENT( reinterpret_cast< long volatile * >( object) ) - 1;
 }
 
 inline
 uint32_t atomic_fetch_sub( uint32_t volatile * object, uint32_t operand)
 {
         BOOST_ASSERT( operand == 1);
- return BOOST_INTERLOCKED_DECREMENT( reinterpret_cast< long volatile * >( object) );
+ return BOOST_INTERLOCKED_DECREMENT( reinterpret_cast< long volatile * >( object) ) + 1;
 }
 } } }
 

Modified: sandbox/task/boost/task/detail/atomic_solaris.hpp
==============================================================================
--- sandbox/task/boost/task/detail/atomic_solaris.hpp (original)
+++ sandbox/task/boost/task/detail/atomic_solaris.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -29,14 +29,14 @@
 uint32_t atomic_fetch_add( uint32_t volatile * object, uint32_t operand)
 {
         BOOST_ASSERT( operand == 1);
- return ::atomic_inc_32_nv( object);
+ return ::atomic_inc_32( object);
 }
 
 inline
 uint32_t atomic_fetch_sub( uint32_t volatile * object, uint32_t operand)
 {
         BOOST_ASSERT( operand == 1);
- return ::atomic_dec_32_nv( object);
+ return ::atomic_dec_32( object);
 }
 } } }
 

Modified: sandbox/task/boost/task/detail/atomic_sync.hpp
==============================================================================
--- sandbox/task/boost/task/detail/atomic_sync.hpp (original)
+++ sandbox/task/boost/task/detail/atomic_sync.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -33,14 +33,14 @@
 uint32_t atomic_fetch_add( uint32_t volatile * object, uint32_t operand)
 {
         BOOST_ASSERT( operand == 1);
- return __sync_add_and_fetch( object, 1);
+ return __sync_fetch_and_add( object, 1);
 }
 
 inline
 uint32_t atomic_fetch_sub( uint32_t volatile * object, uint32_t operand)
 {
         BOOST_ASSERT( operand == 1);
- return __sync_add_and_fetch( object, -1);
+ return __sync_fetch_and_add( object, -1);
 }
 } } }
 

Modified: sandbox/task/boost/task/detail/fiber_posix.hpp
==============================================================================
--- sandbox/task/boost/task/detail/fiber_posix.hpp (original)
+++ sandbox/task/boost/task/detail/fiber_posix.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -80,33 +80,17 @@
         { return state_ == st_exited; }
 
         void exit_()
- {
- if ( ::swapcontext( & callee_, & caller_) == -1)
- throw system::system_error(
- system::error_code(
- errno,
- system::system_category) );
- }
+ { BOOST_ASSERT( ::swapcontext( & callee_, & caller_) != -1); }
 
         void switch_to_( fiber & to)
         {
                 std::swap( caller_, to.caller_);
                 std::swap( state_, to.state_);
- if ( ::swapcontext( & callee_, & to.callee_) == -1)
- throw system::system_error(
- system::error_code(
- errno,
- system::system_category) );
+ BOOST_ASSERT( ::swapcontext( & callee_, & to.callee_) != -1);
         }
 
         void run_()
- {
- if ( ::swapcontext( & caller_, & callee_) == -1)
- throw system::system_error(
- system::error_code(
- errno,
- system::system_category) );
- }
+ { BOOST_ASSERT( ::swapcontext( & caller_, & callee_) != -1); }
 
         void init_()
         {

Modified: sandbox/task/boost/task/detail/fiber_windows.hpp
==============================================================================
--- sandbox/task/boost/task/detail/fiber_windows.hpp (original)
+++ sandbox/task/boost/task/detail/fiber_windows.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -147,6 +147,7 @@
 
         void switch_to( sptr_t & to)
         {
+ BOOST_ASSERT( to);
                 BOOST_ASSERT( running_() );
                 if ( to->uninitialized_() ) to->init_();
                 switch_to_( * to);
@@ -155,8 +156,8 @@
 
         void run()
         {
- BOOST_ASSERT( uninitialized_() || ready_() );
- if ( uninitialized_() ) init_();
+ BOOST_ASSERT( uninitialized_() );
+ init_();
                 BOOST_ASSERT( ready_() );
                 state_ = st_running;
                 run_();
@@ -165,7 +166,7 @@
 
         void exit()
         {
- BOOST_ASSERT( running_() || ready_() ) ;
+ BOOST_ASSERT( running_() ) ;
                 state_ = st_exited;
                 exit_();
                 BOOST_ASSERT(!"should never be reached");

Deleted: sandbox/task/boost/task/detail/interrupter.hpp
==============================================================================
--- sandbox/task/boost/task/detail/interrupter.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
+++ (empty file)
@@ -1,82 +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)
-
-#ifndef BOOST_TASK_DETAIL_INTERRUPTER_H
-#define BOOST_TASK_DETAIL_INTERRUPTER_H
-
-#include <boost/shared_ptr.hpp>
-#include <boost/thread.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/locks.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/thread_time.hpp>
-#include <boost/utility.hpp>
-
-#include <boost/task/detail/config.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-# if defined(BOOST_MSVC)
-# pragma warning(push)
-# pragma warning(disable:4251 4275)
-# endif
-
-namespace boost { namespace task
-{
-namespace detail
-{
-class BOOST_TASK_DECL interrupter
-{
-private:
- class impl : private noncopyable
- {
- private:
- bool requested_;
- mutex mtx_;
- shared_ptr< thread > thrd_;
-
- void reset_();
-
- void reset_( shared_ptr< thread > const& thrd);
-
- void interrupt_();
-
- public:
- impl();
-
- void reset();
-
- void reset( shared_ptr< thread > const& thrd);
-
- void interrupt();
-
- bool interruption_requested();
- };
-
- shared_ptr< impl > impl_;
-
-public:
- interrupter();
-
- void reset();
-
- void reset( shared_ptr< thread > const& thrd);
-
- void interrupt();
-
- bool interruption_requested();
-
- void swap( interrupter & other);
-};
-}}}
-
-# if defined(BOOST_MSVC)
-# pragma warning(pop)
-# endif
-
-#include <boost/config/abi_suffix.hpp>
-
-#endif // BOOST_TASK_DETAIL_INTERRUPTER_H

Modified: sandbox/task/boost/task/detail/pool_base.hpp
==============================================================================
--- sandbox/task/boost/task/detail/pool_base.hpp (original)
+++ sandbox/task/boost/task/detail/pool_base.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -39,7 +39,7 @@
 namespace detail
 {
 
-template< typename Channel, typename UMS >
+template< typename Queue, typename UMS >
 class pool_base
 {
 private:
@@ -48,15 +48,14 @@
         template< typename T, typename X, typename Z >
         friend class worker_object;
 
- typedef Channel channel;
- typedef typename channel::item channel_item;
+ typedef Queue queue_type;
+ typedef typename queue_type::value_type value_type;
 
         UMS ums_;
         worker_group wg_;
         shared_mutex mtx_wg_;
         volatile uint32_t state_;
- channel channel_;
- volatile uint32_t active_worker_;
+ queue_type queue_;
         volatile uint32_t idle_worker_;
 
         void worker_entry_()
@@ -118,12 +117,6 @@
         }
 # endif
 
- std::size_t active_() const
- { return active_worker_; }
-
- std::size_t idle_() const
- { return size_() - active_(); }
-
         std::size_t size_() const
         { return wg_.size(); }
 
@@ -131,7 +124,7 @@
         { return state_ > 0; }
 
         bool close_()
- { return atomic_fetch_add( & state_, 1) > 1; }
+ { return atomic_fetch_add( & state_, 1) > 0; }
 
 public:
         explicit pool_base(
@@ -144,13 +137,11 @@
         wg_(),
         mtx_wg_(),
         state_( 0),
- channel_(),
- active_worker_( 0),
+ queue_(),
         idle_worker_( 0)
         {
                 if ( asleep.is_special() || asleep.is_negative() )
                         throw invalid_timeduration();
- channel_.activate();
                 lock_guard< shared_mutex > lk( mtx_wg_);
                 for ( std::size_t i( 0); i < psize; ++i)
                         create_worker_( psize, asleep, max_scns, stack_size);
@@ -167,15 +158,13 @@
         wg_(),
         mtx_wg_(),
         state_( 0),
- channel_(
+ queue_(
                 hwm,
                 lwm),
- active_worker_( 0),
         idle_worker_( 0)
         {
                 if ( asleep.is_special() || asleep.is_negative() )
                         throw invalid_timeduration();
- channel_.activate();
                 lock_guard< shared_mutex > lk( mtx_wg_);
                 for ( std::size_t i( 0); i < psize; ++i)
                         create_worker_( psize, asleep, max_scns, stack_size);
@@ -190,15 +179,13 @@
         wg_(),
         mtx_wg_(),
         state_( 0),
- channel_(),
- active_worker_( 0),
+ queue_(),
         idle_worker_( 0)
         {
                 if ( asleep.is_special() || asleep.is_negative() )
                         throw invalid_timeduration();
                 poolsize psize( thread::hardware_concurrency() );
                 BOOST_ASSERT( psize > 0);
- channel_.activate();
                 lock_guard< shared_mutex > lk( mtx_wg_);
                 for ( std::size_t i( 0); i < psize; ++i)
                         create_worker_( psize, asleep, max_scns, stack_size, i);
@@ -214,17 +201,15 @@
         wg_(),
         mtx_wg_(),
         state_( 0),
- channel_(
+ queue_(
                 hwm,
                 lwm),
- active_worker_( 0),
         idle_worker_( 0)
         {
                 if ( asleep.is_special() || asleep.is_negative() )
                         throw invalid_timeduration();
                 poolsize psize( thread::hardware_concurrency() );
                 BOOST_ASSERT( psize > 0);
- channel_.activate();
                 lock_guard< shared_mutex > lk( mtx_wg_);
                 for ( std::size_t i( 0); i < psize; ++i)
                         create_worker_( psize, asleep, max_scns, stack_size, i);
@@ -234,18 +219,6 @@
         ~pool_base()
         { shutdown(); }
 
- std::size_t active()
- {
- shared_lock< shared_mutex > lk( mtx_wg_);
- return active_();
- }
-
- std::size_t idle()
- {
- shared_lock< shared_mutex > lk( mtx_wg_);
- return idle_();
- }
-
         void interrupt_all_worker()
         {
                 if ( closed_() ) return;
@@ -258,7 +231,7 @@
         {
                 if ( closed_() || close_() ) return;
 
- channel_.deactivate();
+ queue_.deactivate();
                 shared_lock< shared_mutex > lk( mtx_wg_);
                 wg_.signal_shutdown_all();
                 wg_.join_all();
@@ -268,7 +241,7 @@
         {
                 if ( closed_() || close_() ) return;
 
- channel_.deactivate_now();
+ queue_.deactivate();
                 shared_lock< shared_mutex > lk( mtx_wg_);
                 wg_.signal_shutdown_now_all();
                 wg_.interrupt_all();
@@ -284,26 +257,17 @@
         bool closed()
         { return closed_(); }
 
- void clear()
- { channel_.clear(); }
-
- bool empty()
- { return channel_.empty(); }
-
- std::size_t pending()
- { return channel_.size(); }
-
         std::size_t upper_bound()
- { return channel_.upper_bound(); }
+ { return queue_.upper_bound(); }
 
         void upper_bound( high_watermark const& hwm)
- { channel_.upper_bound( hwm); }
+ { queue_.upper_bound( hwm); }
 
         std::size_t lower_bound()
- { return channel_.lower_bound(); }
+ { return queue_.lower_bound(); }
 
         void lower_bound( low_watermark const lwm)
- { channel_.lower_bound( lwm); }
+ { queue_.lower_bound( lwm); }
 
         template< typename R >
         handle< R > submit( task< R > t)
@@ -313,9 +277,8 @@
 
                 shared_future< R > f( t.get_future() );
                 context ctx;
- handle< R > h( ctx.get_handle( f) );
- channel_.put(
- ctx.get_callable( boost::move( t) ) );
+ handle< R > h( f, ctx);
+ queue_.put( callable( boost::move( t), ctx) );
                 return h;
         }
 
@@ -327,10 +290,10 @@
 
                 shared_future< R > f( t.get_future() );
                 context ctx;
- handle< R > h( ctx.get_handle( f) );
- channel_.put(
- channel_item(
- ctx.get_callable( boost::move( t) ),
+ handle< R > h( f, ctx);
+ queue_.put(
+ value_type(
+ callable( boost::move( t), ctx),
                                         attr) );
                 return h;
         }

Added: sandbox/task/boost/task/detail/smart.hpp
==============================================================================
--- (empty file)
+++ sandbox/task/boost/task/detail/smart.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -0,0 +1,65 @@
+
+// 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_DETAIL_SMART_H
+#define BOOST_DETAIL_SMART_H
+
+#include <boost/task/callable.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost { namespace task {
+namespace detail
+{
+struct replace_oldest
+{
+ template<
+ typename PrioIndex,
+ typename Value
+ >
+ void operator()( PrioIndex & idx, Value const& va)
+ {
+ typedef typename PrioIndex::iterator iterator;
+ iterator i( idx.find( va.attr) );
+ if ( i == idx.end() )
+ idx.insert( va);
+ else
+ idx.replace( i, va);
+ }
+};
+
+struct take_oldest
+{
+ class swapper
+ {
+ private:
+ callable & ca_;
+
+ public:
+ swapper( callable & ca)
+ : ca_( ca)
+ {}
+
+ template< typename Value >
+ void operator()( Value & va)
+ { ca_.swap( va.ca); }
+ };
+
+ template< typename PrioIndex >
+ void operator()( PrioIndex & idx, callable & ca)
+ {
+ typedef typename PrioIndex::iterator iterator;
+ iterator i( idx.begin() );
+ BOOST_ASSERT( i != idx.end() );
+ idx.modify( i, swapper( ca) );
+ idx.erase( i);
+ }
+};
+}}}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_TASK_DETAIL_SMART_H

Modified: sandbox/task/boost/task/detail/worker.hpp
==============================================================================
--- sandbox/task/boost/task/detail/worker.hpp (original)
+++ sandbox/task/boost/task/detail/worker.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -8,8 +8,6 @@
 #define BOOST_TASK_DETAIL_WORKER_H
 
 #include <cstddef>
-#include <list>
-#include <set>
 #include <utility>
 
 #include <boost/assert.hpp>
@@ -23,7 +21,6 @@
 #include <boost/task/detail/config.hpp>
 #include <boost/task/detail/fiber.hpp>
 #include <boost/task/detail/guard.hpp>
-#include <boost/task/detail/interrupter.hpp>
 #include <boost/task/detail/wsq.hpp>
 #include <boost/task/poolsize.hpp>
 #include <boost/task/scanns.hpp>
@@ -113,7 +110,6 @@
         void execute_( callable & ca)
         {
                 BOOST_ASSERT( ! ca.empty() );
- guard grd( pool_.active_worker_);
                 {
                         context_guard lk( ca, thrd_);
                         ca();
@@ -125,10 +121,10 @@
         bool take_global_callable_(
                         callable & ca,
                         posix_time::time_duration const& asleep)
- { return pool_.channel_.take( ca, asleep); }
+ { return pool_.queue_.take( ca, asleep); }
 
         bool try_take_global_callable_( callable & ca)
- { return pool_.channel_.try_take( ca); }
+ { return pool_.queue_.try_take( ca); }
 
         bool try_take_local_callable_( callable & ca)
         { return wsq_.try_take( ca); }
@@ -207,15 +203,46 @@
 
         void run_()
         {
- BOOST_ASSERT( fib_->running() );
                 while ( ! shutdown_() )
- process_( true);
- BOOST_ASSERT( fib_->running() );
+ {
+ try_blocked_fibers_();
+ callable ca;
+ if ( try_take_local_callable_( ca) ||
+ try_steal_other_callable_( ca) ||
+ try_take_global_callable_( ca) )
+ {
+ execute_( ca);
+ scns_ = 0;
+ }
+ else
+ {
+ guard grd( pool_.idle_worker_);
+ ++scns_;
+ if ( scns_ >= max_scns_)
+ {
+ if ( pool_.size_() > pool_.idle_worker_)
+ {
+ if ( take_global_callable_( ca, asleep_) )
+ execute_( ca);
+ }
+ else if ( ! ums_.has_blocked() )
+ {
+ try
+ { this_thread::sleep( asleep_); }
+ catch ( thread_interrupted const&)
+ { return; }
+ }
+ scns_ = 0;
+ }
+ else
+ this_thread::yield();
+ }
+ }
         }
 
         bool shutdown_()
         {
- if ( shutdown__() && pool_.channel_.empty() && ! ums_.has_blocked() )
+ if ( shutdown__() && pool_.queue_.empty() && ! ums_.has_blocked() )
                         return true;
                 else if ( shutdown_now__() )
                         return true;

Deleted: sandbox/task/boost/task/fifo.hpp
==============================================================================
--- sandbox/task/boost/task/fifo.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
+++ (empty file)
@@ -1,70 +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)
-
-#ifndef BOOST_TASK_FIFO_H
-#define BOOST_TASK_FIFO_H
-
-#include <cstddef>
-#include <list>
-
-#include <boost/task/callable.hpp>
-#include <boost/task/detail/meta.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-namespace boost { namespace task
-{
-struct fifo
-{
- typedef detail::has_no_attribute attribute_tag_type;
-
- class impl
- {
- public:
- typedef callable item;
- typedef std::list< item >::iterator iterator;
- typedef std::list< item >::const_iterator const_iterator;
-
- private:
- std::list< item > lst_;
-
- public:
- void push( item const& itm)
- { lst_.push_back( itm); }
-
- void pop( callable & ca)
- {
- ca.swap( lst_.front() );
- lst_.pop_front();
- }
-
- std::size_t size() const
- { return lst_.size(); }
-
- bool empty() const
- { return lst_.empty(); }
-
- void clear()
- { lst_.clear(); }
-
- const iterator begin()
- { return lst_.begin(); }
-
- const const_iterator begin() const
- { return lst_.begin(); }
-
- const iterator end()
- { return lst_.end(); }
-
- const const_iterator end() const
- { return lst_.end(); }
- };
-};
-} }
-
-#include <boost/config/abi_suffix.hpp>
-
-#endif // BOOST_TASK_FIFO_H

Modified: sandbox/task/boost/task/handle.hpp
==============================================================================
--- sandbox/task/boost/task/handle.hpp (original)
+++ sandbox/task/boost/task/handle.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -10,7 +10,7 @@
 #include <boost/thread.hpp>
 #include <boost/thread/thread_time.hpp>
 
-#include <boost/task/detail/interrupter.hpp>
+#include <boost/task/context.hpp>
 #include <boost/task/future.hpp>
 #include <boost/task/exceptions.hpp>
 
@@ -19,32 +19,28 @@
 namespace boost { namespace task
 {
 
-class context;
-
 template< typename R >
 class handle
 {
 private:
- friend class context;
+ shared_future< R > fut_;
+ context ctx_;
 
- shared_future< R > fut_;
- detail::interrupter intr_;
+public:
+ handle()
+ : fut_(), ctx_()
+ {}
 
         handle(
                 shared_future< R > fut,
- detail::interrupter const& intr)
+ context const& ctx)
         :
         fut_( fut),
- intr_( intr)
- {}
-
-public:
- handle()
- : fut_(), intr_()
+ ctx_( ctx)
         {}
 
         void interrupt()
- { intr_.interrupt(); }
+ { ctx_.interrupt(); }
 
         void interrupt_and_wait()
         {
@@ -66,7 +62,7 @@
         }
 
         bool interruption_requested()
- { return intr_.interruption_requested(); }
+ { return ctx_.interruption_requested(); }
 
         R get()
         {
@@ -132,7 +128,7 @@
         void swap( handle< R > & other)
         {
                 fut_.swap( other.fut_);
-// intr_.swap( other.intr_);
+ ctx_.swap( other.ctx_);
         }
 };
 

Added: sandbox/task/boost/task/local_rr_ums.hpp
==============================================================================
--- (empty file)
+++ sandbox/task/boost/task/local_rr_ums.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -0,0 +1,72 @@
+
+// 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_TASK_LOCAL_RR_UMS_H
+#define BOOST_TASK_LOCAL_RR_UMS_H
+
+#include <list>
+
+#include <boost/assert.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread.hpp>
+
+#include <boost/task/detail/fiber.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost { namespace task
+{
+class local_rr_ums
+{
+private:
+ thread_specific_ptr< std::list< detail::fiber::sptr_t > > runnable_;
+ thread_specific_ptr< std::list< detail::fiber::sptr_t > > blocked_;
+
+public:
+ local_rr_ums()
+ : runnable_(), blocked_()
+ {}
+
+ void attach()
+ {
+ runnable_.reset( new std::list< detail::fiber::sptr_t >() );
+ blocked_.reset( new std::list< detail::fiber::sptr_t >() );
+ }
+
+ bool has_runnable() const
+ { return ! runnable_->empty(); }
+
+ bool has_blocked() const
+ { return ! blocked_->empty(); }
+
+ void put_runnable( detail::fiber::sptr_t const& fib)
+ { runnable_->push_back( fib); }
+
+ void put_blocked( detail::fiber::sptr_t const& fib)
+ { blocked_->push_back( fib); }
+
+ bool try_take_runnable( detail::fiber::sptr_t & fib)
+ {
+ if ( ! has_runnable() ) return false;
+ fib = runnable_->front();
+ runnable_->pop_front();
+ return true;
+ }
+
+ bool try_take_blocked( detail::fiber::sptr_t & fib)
+ {
+ if ( ! has_blocked() ) return false;
+ fib = blocked_->front();
+ blocked_->pop_front();
+ return true;
+ }
+};
+} }
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_TASK_LOCAL_RR_UMS_H
+

Modified: sandbox/task/boost/task/meta.hpp
==============================================================================
--- sandbox/task/boost/task/meta.hpp (original)
+++ sandbox/task/boost/task/meta.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -20,7 +20,7 @@
 struct has_attribute : public mpl::bool_<
         is_same<
                 detail::has_attribute,
- typename Pool::channel::scheduler_type::attribute_tag_type
+ typename Pool::queue_type::attribute_tag_type
>::value
>
 {};
@@ -28,7 +28,7 @@
 template< typename Pool >
 struct attribute_type
 {
- typedef typename Pool::channel::scheduler_type::attribute_type type;
+ typedef typename Pool::queue_type::attribute_type type;
 };
 } }
 

Modified: sandbox/task/boost/task/new_thread.hpp
==============================================================================
--- sandbox/task/boost/task/new_thread.hpp (original)
+++ sandbox/task/boost/task/new_thread.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -13,6 +13,7 @@
 #include <boost/thread.hpp>
 #include <boost/thread/detail/move.hpp>
 
+#include <boost/task/callable.hpp>
 #include <boost/task/context.hpp>
 #include <boost/task/future.hpp>
 #include <boost/task/handle.hpp>
@@ -66,13 +67,13 @@
         handle< R > operator()( task< R > t)
         {
                 shared_future< R > f( t.get_future() );
- context ctx;
- handle< R > h( ctx.get_handle( f) );
- callable ca( ctx.get_callable( boost::move( t) ) );
+ context ctx1, ctx2;
+ handle< R > h( f, ctx1);
+ callable ca( boost::move( t), ctx2);
                 shared_ptr< thread > thrd(
                         new thread( wrapper( ca) ),
                         detail::joiner() );
- ca.reset( thrd);
+ ctx1.reset( thrd);
 
                 return h;
         }

Modified: sandbox/task/boost/task/own_thread.hpp
==============================================================================
--- sandbox/task/boost/task/own_thread.hpp (original)
+++ sandbox/task/boost/task/own_thread.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -27,8 +27,8 @@
         {
                 shared_future< R > f( t.get_future() );
                 context ctx;
- handle< R > h( ctx.get_handle( f) );
- callable ca( ctx.get_callable( boost::move( t) ) );
+ handle< R > h( f, ctx);
+ callable ca( boost::move( t), ctx);
                 ca();
                 return h;
         }

Deleted: sandbox/task/boost/task/priority.hpp
==============================================================================
--- sandbox/task/boost/task/priority.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
+++ (empty file)
@@ -1,133 +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)
-
-#ifndef BOOST_TASK_PRIORITY_H
-#define BOOST_TASK_PRIORITY_H
-
-#include <cstddef>
-#include <utility>
-
-#include <boost/assert.hpp>
-#include <boost/multi_index_container.hpp>
-#include <boost/multi_index/member.hpp>
-#include <boost/multi_index/ordered_index.hpp>
-
-#include <boost/task/callable.hpp>
-#include <boost/task/detail/meta.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-namespace boost { namespace task
-{
-template<
- typename Attr,
- typename Ord = std::greater< Attr >
->
-struct priority
-{
- typedef detail::has_attribute attribute_tag_type;
- typedef Attr attribute_type;
-
- class impl
- {
- private:
- typedef Attr attribute;
- typedef Ord ordering;
-
- public:
- struct item
- {
- callable ca;
- attribute attr;
-
- item(
- callable const& ca_,
- attribute const& attr_)
- : ca( ca_), attr( attr_)
- { BOOST_ASSERT( ! ca.empty() ); }
- };
-
- private:
- typedef multi_index::multi_index_container<
- item,
- multi_index::indexed_by<
- multi_index::ordered_non_unique<
- multi_index::member<
- item,
- attribute,
- & item::attr
- >,
- ordering
- >
- >
- > list;
- typedef typename list::template nth_index< 0 >::type index;
-
- class swapper
- {
- private:
- callable & ca_;
-
- public:
- swapper( callable & ca)
- : ca_( ca)
- {}
-
- void operator()( item & itm)
- { ca_.swap( itm.ca); }
- };
-
- list lst_;
- index & idx_;
-
- public:
- typedef typename list::iterator iterator;
- typedef typename list::const_iterator const_iterator;
-
- impl()
- :
- lst_(),
- idx_( lst_.get< 0 >() )
- {}
-
- void push( item const& itm)
- { lst_.insert( itm); }
-
- void pop( callable & ca)
- {
- iterator i( lst_.begin() );
- BOOST_ASSERT( i != lst_.end() );
- lst_.modify( i, swapper( ca) );
- lst_.erase( i);
- }
-
- std::size_t size() const
- { return lst_.size(); }
-
- bool empty() const
- { return lst_.empty(); }
-
- void clear()
- { lst_.clear(); }
-
- const iterator begin()
- { return lst_.begin(); }
-
- const const_iterator begin() const
- { return lst_.begin(); }
-
- const iterator end()
- { return lst_.end(); }
-
- const const_iterator end() const
- { return lst_.end(); }
- };
-};
-} }
-
-#include <boost/config/abi_suffix.hpp>
-
-#endif // BOOST_TASK_PRIORITY_H

Deleted: sandbox/task/boost/task/smart.hpp
==============================================================================
--- sandbox/task/boost/task/smart.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
+++ (empty file)
@@ -1,185 +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)
-
-#ifndef BOOST_TASK_SMART_H
-#define BOOST_TASK_SMART_H
-
-#include <cstddef>
-
-#include <boost/assert.hpp>
-#include <boost/multi_index_container.hpp>
-#include <boost/multi_index/member.hpp>
-#include <boost/multi_index/ordered_index.hpp>
-
-#include <boost/task/callable.hpp>
-#include <boost/task/detail/meta.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-namespace boost { namespace task
-{
-template<
- typename Attr,
- typename Ord,
- typename Enq,
- typename Deq
->
-struct smart
-{
- typedef detail::has_attribute attribute_tag_type;
- typedef Attr attribute_type;
-
- class impl
- {
- private:
- typedef Attr attribute;
- typedef Deq dequeue_op;
- typedef Enq enqueue_op;
- typedef Ord ordering;
-
- public:
- struct item
- {
- callable ca;
- attribute attr;
-
- item()
- : ca(), attr()
- {}
-
- item(
- callable const& ca_,
- attribute const& attr_)
- : ca( ca_), attr( attr_)
- { BOOST_ASSERT( ! ca.empty() ); }
-
- void swap( item & other)
- {
- ca.swap( other.ca);
- std::swap( attr, other.attr);
- }
- };
-
- private:
- typedef multi_index::multi_index_container<
- item,
- multi_index::indexed_by<
- multi_index::ordered_non_unique<
- multi_index::member<
- item,
- attribute,
- & item::attr
- >,
- ordering
- >
- >
- > list;
- typedef typename list::template nth_index< 0 >::type index;
-
- list lst_;
- index & idx_;
- enqueue_op enq_op_;
- dequeue_op deq_op_;
-
- public:
- typedef typename index::iterator iterator;
- typedef typename index::const_iterator const_iterator;
-
- impl(
- enqueue_op const& enq_op = enqueue_op(),
- dequeue_op const& deq_op = dequeue_op() )
- :
- lst_(),
- idx_( lst_.get< 0 >() ),
- enq_op_( enq_op),
- deq_op_( deq_op)
- {}
-
- void push( item const& itm)
- { enq_op_( idx_, itm); }
-
- void pop( callable & ca)
- {
- item itm;
- deq_op_( idx_, itm);
- ca.swap( itm.ca);
- }
-
- std::size_t size() const
- { return lst_.size(); }
-
- bool empty() const
- { return lst_.empty(); }
-
- void clear()
- { lst_.clear(); }
-
- const iterator begin()
- { return lst_.begin(); }
-
- const const_iterator begin() const
- { return lst_.begin(); }
-
- const iterator end()
- { return lst_.end(); }
-
- const const_iterator end() const
- { return lst_.end(); }
- };
-};
-
-struct replace_oldest
-{
- template<
- typename Index,
- typename Item
- >
- void operator()( Index & idx, Item const& itm)
- {
- typedef typename Index::iterator iterator;
- iterator i( idx.find( itm.attr) );
- if ( i == idx.end() )
- idx.insert( itm);
- else
- idx.replace( i, itm);
- }
-};
-
-struct take_oldest
-{
- template< typename Item >
- class swapper
- {
- private:
- Item & itm_;
-
- public:
- swapper( Item & itm)
- : itm_( itm)
- {}
-
- void operator()( Item & itm)
- { itm_.swap( itm); }
- };
-
- template<
- typename Index,
- typename Item
- >
- void operator()( Index & idx, Item & itm)
- {
- typedef typename Index::iterator iterator;
- iterator i( idx.begin() );
- BOOST_ASSERT( i != idx.end() );
- idx.modify( i, swapper< Item >( itm) );
- idx.erase( i);
- }
-};
-} }
-
-#include <boost/config/abi_suffix.hpp>
-
-#endif // BOOST_TASK_SMART_H

Modified: sandbox/task/boost/task/static_pool.hpp
==============================================================================
--- sandbox/task/boost/task/static_pool.hpp (original)
+++ sandbox/task/boost/task/static_pool.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -30,13 +30,16 @@
 
 namespace boost { namespace task
 {
-template< typename Channel, typename UMS = local_rr_ums >
+template< typename Queue, typename UMS = local_rr_ums >
 class static_pool
 {
 public:
- typedef Channel channel;
+ typedef Queue queue_type;
+ typedef UMS ums_type;
 
 private:
+ typedef detail::pool_base< queue_type, ums_type > base_type;
+
         template< typename T, typename X, typename Z >
         friend class detail::worker_object;
 
@@ -44,7 +47,7 @@
         struct tag_bind_to_processors {};
 # endif
         
- shared_ptr< detail::pool_base< Channel, UMS > > pool_;
+ shared_ptr< base_type > pool_;
 
         static_pool( static_pool &);
         static_pool & operator=( static_pool &);
@@ -59,7 +62,7 @@
                 posix_time::time_duration const& asleep = posix_time::microseconds( 10),
                 scanns const& max_scns = scanns( 20),
                 stacksize const& stack_size = stacksize( 64000) )
- : pool_( new detail::pool_base< Channel, UMS >( psize, asleep, max_scns, stack_size) )
+ : pool_( new base_type( psize, asleep, max_scns, stack_size) )
         {}
 
         explicit static_pool(
@@ -69,7 +72,7 @@
                 posix_time::time_duration const& asleep = posix_time::microseconds( 100),
                 scanns const& max_scns = scanns( 20),
                 stacksize const& stack_size = stacksize( 64000) )
- : pool_( new detail::pool_base< Channel, UMS >( psize, hwm, lwm, asleep, max_scns, stack_size) )
+ : pool_( new base_type( psize, hwm, lwm, asleep, max_scns, stack_size) )
         {}
 
 # if defined(BOOST_HAS_PROCESSOR_BINDINGS)
@@ -78,7 +81,7 @@
                 posix_time::time_duration const& asleep = posix_time::microseconds( 10),
                 scanns const& max_scns = scanns( 20),
                 stacksize const& stack_size = stacksize( 64000) )
- : pool_( new detail::pool_base< Channel, UMS >( asleep, max_scns, stack_size) )
+ : pool_( new base_type( asleep, max_scns, stack_size) )
         {}
 
         explicit static_pool(
@@ -88,7 +91,7 @@
                 posix_time::time_duration const& asleep = posix_time::microseconds( 100),
                 scanns const& max_scns = scanns( 20),
                 stacksize const& stack_size = stacksize( 64000) )
- : pool_( new detail::pool_base< Channel, UMS >( hwm, lwm, asleep, max_scns, stack_size) )
+ : pool_( new base_type( hwm, lwm, asleep, max_scns, stack_size) )
         {}
 
         static tag_bind_to_processors bind_to_processors()
@@ -131,20 +134,6 @@
         }
 # endif
 
- std::size_t active()
- {
- if ( ! pool_)
- throw pool_moved();
- return pool_->active();
- }
-
- std::size_t idle()
- {
- if ( ! pool_)
- throw pool_moved();
- return pool_->idle();
- }
-
         void interrupt_all_worker()
         {
                 if ( ! pool_)
@@ -180,27 +169,6 @@
                 return pool_->closed();
         }
 
- void clear()
- {
- if ( ! pool_)
- throw pool_moved();
- pool_->clear();
- }
-
- bool empty()
- {
- if ( ! pool_)
- throw pool_moved();
- return pool_->empty();
- }
-
- std::size_t pending()
- {
- if ( ! pool_)
- throw pool_moved();
- return pool_->pending();
- }
-
         std::size_t upper_bound()
         {
                 if ( ! pool_)
@@ -245,7 +213,7 @@
                 return pool_->submit( boost::move( t), attr);
         }
 
- typedef typename shared_ptr< detail::pool_base< Channel, UMS > >::unspecified_bool_type unspecified_bool_type;
+ typedef typename shared_ptr< base_type >::unspecified_bool_type unspecified_bool_type;
 
         operator unspecified_bool_type() const // throw()
         { return pool_; }
@@ -258,18 +226,18 @@
 };
 }
 
-template< typename Channel, typename UMS >
-void swap( task::static_pool< Channel, UMS > & l, task::static_pool< Channel, UMS > & r)
+template< typename Queue, typename UMS >
+void swap( task::static_pool< Queue, UMS > & l, task::static_pool< Queue, UMS > & r)
 { return l.swap( r); }
 
 # if defined(BOOST_HAS_RVALUE_REFS)
-template< typename Channel, typename UMS >
-task::static_pool< Channel, UMS > && move( task::static_pool< Channel, UMS > && t)
+template< typename Queue, typename UMS >
+task::static_pool< Queue, UMS > && move( task::static_pool< Queue, UMS > && t)
 { return t; }
 # else
-template< typename Channel, typename UMS >
-task::static_pool< Channel, UMS > move( boost::detail::thread_move_t< task::static_pool< Channel, UMS > > t)
-{ return task::static_pool< Channel, UMS >( t); }
+template< typename Queue, typename UMS >
+task::static_pool< Queue, UMS > move( boost::detail::thread_move_t< task::static_pool< Queue, UMS > > t)
+{ return task::static_pool< Queue, UMS >( t); }
 # endif
 
 }

Deleted: sandbox/task/boost/task/unbounded_channel.hpp
==============================================================================
--- sandbox/task/boost/task/unbounded_channel.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
+++ (empty file)
@@ -1,276 +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)
-
-#ifndef BOOST_TASK_UNBOUNDED_CHANNEL_H
-#define BOOST_TASK_UNBOUNDED_CHANNEL_H
-
-#include <cstddef>
-#include <vector>
-
-#include <boost/assert.hpp>
-#include <boost/bind.hpp>
-#include <boost/foreach.hpp>
-#include <boost/function.hpp>
-#include <boost/thread/condition.hpp>
-#include <boost/thread/locks.hpp>
-#include <boost/thread/shared_mutex.hpp>
-
-#include <boost/task/callable.hpp>
-#include <boost/task/exceptions.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-namespace boost { namespace task
-{
-template< typename SchedulingPolicy >
-class unbounded_channel
-{
-public:
- typedef SchedulingPolicy scheduler_type;
- typedef typename scheduler_type::impl::item item;
-
-private:
- typedef typename scheduler_type::impl queue;
-
- enum channel_state
- {
- channel_active,
- channel_deactive,
- channel_deactive_now
- };
-
- channel_state state_;
- queue queue_;
- shared_mutex mtx_;
- condition not_empty_cond_;
-
- bool active_() const
- { return state_ == channel_active; }
-
- bool deactive_() const
- { return state_ == channel_deactive; }
-
- bool deactive_now_() const
- { return state_ == channel_deactive_now; }
-
- void activate_()
- { state_ = channel_active; }
-
- void clear_()
- {
- BOOST_ASSERT( ! active_() );
- queue_.clear();
- BOOST_ASSERT( empty_() );
- }
-
- void deactivate_()
- {
- if ( active_() )
- {
- state_ = channel_deactive;
- not_empty_cond_.notify_all();
- }
-
- BOOST_ASSERT( deactive_() );
- }
-
- void deactivate_now_()
- {
- if ( active_() )
- {
- state_ = channel_deactive_now;
- not_empty_cond_.notify_all();
- }
-
- BOOST_ASSERT( deactive_now_() );
- }
-
- const std::vector< callable > drain_()
- {
- BOOST_ASSERT( deactive_now_() );
- std::vector< callable > unprocessed;
- unprocessed.reserve( queue_.size() );
- BOOST_FOREACH( callable ca, queue_)
- { unprocessed.push_back( ca); }
- clear_();
- BOOST_ASSERT( empty_() );
- return unprocessed;
- }
-
- bool empty_() const
- { return queue_.empty(); }
-
- std::size_t size_() const
- { return queue_.size(); }
-
- void put_( item const& itm)
- {
- if ( ! active_() )
- throw task_rejected("channel is not active");
- queue_.push( itm);
- not_empty_cond_.notify_one();
- }
-
- bool take_(
- callable & ca,
- unique_lock< shared_mutex > & lk)
- {
- if ( deactive_now_() || ( deactive_() && empty_() ) )
- return false;
- if ( empty_() )
- {
- try
- {
- not_empty_cond_.wait(
- lk,
- bind(
- & unbounded_channel::consumers_activate_,
- this) );
- }
- catch ( thread_interrupted const&)
- { return false; }
- }
- if ( deactive_now_() || ( deactive_() && empty_() ) )
- return false;
- queue_.pop( ca);
- return ! ca.empty();
- }
-
- template< typename Duration >
- bool take_(
- callable & ca,
- Duration const& rel_time,
- unique_lock< shared_mutex > & lk)
- {
- if ( deactive_now_() || ( deactive_() && empty_() ) )
- return false;
- if ( empty_() )
- {
- try
- {
- if ( ! not_empty_cond_.timed_wait(
- lk,
- rel_time,
- bind(
- & unbounded_channel::consumers_activate_,
- this) ) )
- return false;
- }
- catch ( thread_interrupted const&)
- { return false; }
- }
- if ( deactive_now_() || ( deactive_() && empty_() ) )
- return false;
- queue_.pop( ca);
- return ! ca.empty();
- }
-
- bool try_take_( callable & ca)
- {
- if ( deactive_now_() || empty_() )
- return false;
- queue_.pop( ca);
- return ! ca.empty();
- }
-
- bool consumers_activate_() const
- { return ! active_() || ! empty_(); }
-
-public:
- unbounded_channel()
- :
- state_( channel_active),
- queue_(),
- mtx_(),
- not_empty_cond_()
- {}
-
- bool active()
- {
- shared_lock< shared_mutex > lk( mtx_);
- return active_();
- }
-
- void activate()
- {
- lock_guard< shared_mutex > lk( mtx_);
- activate_();
- }
-
- void clear()
- {
- lock_guard< shared_mutex > lk( mtx_);
- clear_();
- }
-
- bool deactive()
- { return ! active(); }
-
- void deactivate()
- {
- lock_guard< shared_mutex > lk( mtx_);
- deactivate_();
- }
-
- void deactivate_now()
- {
- lock_guard< shared_mutex > lk( mtx_);
- deactivate_now_();
- }
-
- const std::vector< callable > drain()
- {
- lock_guard< shared_mutex > lk( mtx_);
- return drain_();
- }
-
- bool empty()
- {
- lock_guard< shared_mutex > lk( mtx_);
- return empty_();
- }
-
- bool full()
- { return false; }
-
- std::size_t size()
- {
- lock_guard< shared_mutex > lk( mtx_);
- return size_();
- }
-
- void put( item const& itm)
- {
- lock_guard< shared_mutex > lk( mtx_);
- put_( itm);
- }
-
- bool take( callable & ca)
- {
- unique_lock< shared_mutex > lk( mtx_);
- return take_( ca, lk);
- }
-
- template< typename Duration >
- bool take(
- callable & ca,
- Duration const& rel_time)
- {
- unique_lock< shared_mutex > lk( mtx_);
- return take_( ca, rel_time, lk);
- }
-
- bool try_take( callable & ca)
- {
- lock_guard< shared_mutex > lk( mtx_);
- return try_take_( ca);
- }
-};
-} }
-
-#include <boost/config/abi_suffix.hpp>
-
-#endif // BOOST_TASK_UNBOUNDED_CHANNEL_H

Added: sandbox/task/boost/task/unbounded_onelock_fifo.hpp
==============================================================================
--- (empty file)
+++ sandbox/task/boost/task/unbounded_onelock_fifo.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -0,0 +1,179 @@
+
+// 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_TASK_UNBOUNDED_ONELOCK_FIFO_H
+#define BOOST_TASK_UNBOUNDED_ONELOCK_FIFO_H
+
+#include <cstddef>
+#include <list>
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/foreach.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+
+#include <boost/task/callable.hpp>
+#include <boost/task/detail/atomic.hpp>
+#include <boost/task/detail/meta.hpp>
+#include <boost/task/exceptions.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost { namespace task
+{
+class unbounded_onelock_fifo
+{
+public:
+ typedef detail::has_no_attribute attribute_tag_type;
+ typedef callable value_type;
+
+private:
+ typedef std::list< value_type > queue_type;
+
+ volatile uint32_t state_;
+ queue_type queue_;
+ shared_mutex mtx_;
+ condition not_empty_cond_;
+
+ bool active_() const
+ { return 0 == state_; }
+
+ void deactivate_()
+ { detail::atomic_fetch_add( & state_, 1); }
+
+ bool empty_() const
+ { return queue_.empty(); }
+
+ void put_( value_type const& va)
+ {
+ if ( ! active_() )
+ throw task_rejected("queue is not active");
+ queue_.push_back( va);
+ not_empty_cond_.notify_one();
+ }
+
+ bool take_(
+ value_type & va,
+ unique_lock< shared_mutex > & lk)
+ {
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ not_empty_cond_.wait(
+ lk,
+ bind(
+ & unbounded_onelock_fifo::consumers_activate_,
+ this) );
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ va.swap( queue_.front() );
+ queue_.pop_front();
+ return ! va.empty();
+ }
+
+ template< typename Duration >
+ bool take_(
+ value_type & va,
+ Duration const& rel_time,
+ unique_lock< shared_mutex > & lk)
+ {
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ if ( ! not_empty_cond_.timed_wait(
+ lk,
+ rel_time,
+ bind(
+ & unbounded_onelock_fifo::consumers_activate_,
+ this) ) )
+ return false;
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ va.swap( queue_.front() );
+ queue_.pop_front();
+ return ! va.empty();
+ }
+
+ bool try_take_( value_type & va)
+ {
+ if ( empty_() )
+ return false;
+ va.swap( queue_.front() );
+ queue_.pop_front();
+ return ! va.empty();
+ }
+
+ bool consumers_activate_() const
+ { return ! active_() || ! empty_(); }
+
+public:
+ unbounded_onelock_fifo()
+ :
+ state_( 0),
+ queue_(),
+ mtx_(),
+ not_empty_cond_()
+ {}
+
+ void deactivate()
+ { deactivate_(); }
+
+ bool empty()
+ {
+ shared_lock< shared_mutex > lk( mtx_);
+ return empty_();
+ }
+
+ void put( value_type const& va)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ put_( va);
+ }
+
+ bool take( value_type & va)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return take_( va, lk);
+ }
+
+ template< typename Duration >
+ bool take(
+ value_type & va,
+ Duration const& rel_time)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return take_( va, rel_time, lk);
+ }
+
+ bool try_take( value_type & va)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return try_take_( va);
+ }
+};
+} }
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_TASK_UNBOUNDED_ONELOCK_FIFO_H

Added: sandbox/task/boost/task/unbounded_onelock_prio_queue.hpp
==============================================================================
--- (empty file)
+++ sandbox/task/boost/task/unbounded_onelock_prio_queue.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -0,0 +1,216 @@
+
+// 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_TASK_UNBOUNDED_ONELOCK_PRIO_QUEUE_H
+#define BOOST_TASK_UNBOUNDED_ONELOCK_PRIO_QUEUE_H
+
+#include <algorithm>
+#include <cstddef>
+#include <functional>
+#include <queue>
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/foreach.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+
+#include <boost/task/callable.hpp>
+#include <boost/task/detail/atomic.hpp>
+#include <boost/task/detail/meta.hpp>
+#include <boost/task/exceptions.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost { namespace task
+{
+template<
+ typename Attr,
+ typename Comp = std::less< Attr >
+>
+class unbounded_onelock_prio_queue
+{
+public:
+ typedef detail::has_attribute attribute_tag_type;
+ typedef Attr attribute_type;
+
+ struct value_type
+ {
+ callable ca;
+ attribute_type attr;
+
+ value_type(
+ callable const& ca_,
+ attribute_type const& attr_)
+ : ca( ca_), attr( attr_)
+ { BOOST_ASSERT( ! ca.empty() ); }
+
+ void swap( value_type & other)
+ {
+ ca.swap( other.ca);
+ std::swap( attr, other.attr);
+ }
+ };
+
+private:
+ struct compare : public std::binary_function< value_type, value_type, bool >
+ {
+ bool operator()( value_type const& va1, value_type const& va2)
+ { return Comp()( va1.attr, va2.attr); }
+ };
+
+ typedef std::priority_queue<
+ value_type,
+ std::deque< value_type >,
+ compare
+ > queue_type;
+
+ volatile uint32_t state_;
+ queue_type queue_;
+ shared_mutex mtx_;
+ condition not_empty_cond_;
+
+ bool active_() const
+ { return 0 == state_; }
+
+ void deactivate_()
+ { detail::atomic_fetch_add( & state_, 1); }
+
+ bool empty_() const
+ { return queue_.empty(); }
+
+ void put_( value_type const& va)
+ {
+ if ( ! active_() )
+ throw task_rejected("queue is not active");
+ queue_.push( va);
+ not_empty_cond_.notify_one();
+ }
+
+ bool take_(
+ callable & ca,
+ unique_lock< shared_mutex > & lk)
+ {
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ not_empty_cond_.wait(
+ lk,
+ bind(
+ & unbounded_onelock_prio_queue::consumers_activate_,
+ this) );
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ callable tmp( queue_.top().ca);
+ queue_.pop();
+ ca.swap( tmp);
+ return ! ca.empty();
+ }
+
+ template< typename Duration >
+ bool take_(
+ callable & ca,
+ Duration const& rel_time,
+ unique_lock< shared_mutex > & lk)
+ {
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ if ( ! not_empty_cond_.timed_wait(
+ lk,
+ rel_time,
+ bind(
+ & unbounded_onelock_prio_queue::consumers_activate_,
+ this) ) )
+ return false;
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ callable tmp( queue_.top().ca);
+ queue_.pop();
+ ca.swap( tmp);
+ return ! ca.empty();
+ }
+
+ bool try_take_( callable & ca)
+ {
+ if ( empty_() )
+ return false;
+ callable tmp( queue_.top().ca);
+ queue_.pop();
+ ca.swap( tmp);
+ return ! ca.empty();
+ }
+
+ bool consumers_activate_() const
+ { return ! active_() || ! empty_(); }
+
+public:
+ unbounded_onelock_prio_queue()
+ :
+ state_( 0),
+ queue_(),
+ mtx_(),
+ not_empty_cond_()
+ {}
+
+ void deactivate()
+ { deactivate_(); }
+
+ bool empty()
+ {
+ shared_lock< shared_mutex > lk( mtx_);
+ return empty_();
+ }
+
+ void put( value_type const& va)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ put_( va);
+ }
+
+ bool take( callable & ca)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return take_( ca, lk);
+ }
+
+ template< typename Duration >
+ bool take(
+ callable & ca,
+ Duration const& rel_time)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return take_( ca, rel_time, lk);
+ }
+
+ bool try_take( callable & ca)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return try_take_( ca);
+ }
+};
+} }
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_TASK_UNBOUNDED_ONELOCK_PRIO_QUEUE_H

Added: sandbox/task/boost/task/unbounded_onelock_smart_queue.hpp
==============================================================================
--- (empty file)
+++ sandbox/task/boost/task/unbounded_onelock_smart_queue.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -0,0 +1,223 @@
+
+// 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_TASK_UNBOUNDED_ONELOCK_SMART_QUEUE_H
+#define BOOST_TASK_UNBOUNDED_ONELOCK_SMART_QUEUE_H
+
+#include <algorithm>
+#include <cstddef>
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/foreach.hpp>
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+
+#include <boost/task/callable.hpp>
+#include <boost/task/detail/atomic.hpp>
+#include <boost/task/detail/meta.hpp>
+#include <boost/task/detail/smart.hpp>
+#include <boost/task/exceptions.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost { namespace task
+{
+template<
+ typename Attr,
+ typename Comp,
+ typename Enq = detail::replace_oldest,
+ typename Deq = detail::take_oldest
+>
+class unbounded_onelock_smart_queue
+{
+public:
+ typedef detail::has_attribute attribute_tag_type;
+ typedef Attr attribute_type;
+
+ struct value_type
+ {
+ callable ca;
+ attribute_type attr;
+
+ value_type(
+ callable const& ca_,
+ attribute_type const& attr_)
+ : ca( ca_), attr( attr_)
+ { BOOST_ASSERT( ! ca.empty() ); }
+
+ void swap( value_type & other)
+ {
+ ca.swap( other.ca);
+ std::swap( attr, other.attr);
+ }
+ };
+
+private:
+ typedef multi_index::multi_index_container<
+ value_type,
+ multi_index::indexed_by<
+ multi_index::ordered_non_unique<
+ multi_index::member<
+ value_type,
+ Attr,
+ & value_type::attr
+ >,
+ Comp
+ >
+ >
+ > queue_type;
+ typedef typename queue_type::template nth_index< 0 >::type queue_index;
+
+ volatile uint32_t state_;
+ queue_type queue_;
+ queue_index & idx_;
+ shared_mutex mtx_;
+ condition not_empty_cond_;
+ Enq enq_op_;
+ Deq deq_op_;
+
+ bool active_() const
+ { return 0 == state_; }
+
+ void deactivate_()
+ { detail::atomic_fetch_add( & state_, 1); }
+
+ bool empty_() const
+ { return queue_.empty(); }
+
+ void put_( value_type const& va)
+ {
+ if ( ! active_() )
+ throw task_rejected("queue is not active");
+ enq_op_( idx_, va);
+ not_empty_cond_.notify_one();
+ }
+
+ bool take_(
+ callable & ca,
+ unique_lock< shared_mutex > & lk)
+ {
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ not_empty_cond_.wait(
+ lk,
+ bind(
+ & unbounded_onelock_smart_queue::consumers_activate_,
+ this) );
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ deq_op_( idx_, ca);
+ return ! ca.empty();
+ }
+
+ template< typename Duration >
+ bool take_(
+ callable & ca,
+ Duration const& rel_time,
+ unique_lock< shared_mutex > & lk)
+ {
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ if ( ! not_empty_cond_.timed_wait(
+ lk,
+ rel_time,
+ bind(
+ & unbounded_onelock_smart_queue::consumers_activate_,
+ this) ) )
+ return false;
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ deq_op_( idx_, ca);
+ return ! ca.empty();
+ }
+
+ bool try_take_( callable & ca)
+ {
+ if ( empty_() )
+ return false;
+ deq_op_( idx_, ca);
+ return ! ca.empty();
+ }
+
+ bool consumers_activate_() const
+ { return ! active_() || ! empty_(); }
+
+public:
+ unbounded_onelock_smart_queue()
+ :
+ state_( 0),
+ queue_(),
+ idx_( queue_.get< 0 >() ),
+ mtx_(),
+ not_empty_cond_(),
+ enq_op_(),
+ deq_op_()
+ {}
+
+ void deactivate()
+ { detail::atomic_fetch_add( & state_, 1); }
+
+ bool empty()
+ {
+ shared_lock< shared_mutex > lk( mtx_);
+ return empty_();
+ }
+
+ void put( value_type const& va)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ put_( va);
+ }
+
+ bool take( callable & ca)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return take_( ca, lk);
+ }
+
+ template< typename Duration >
+ bool take(
+ callable & ca,
+ Duration const& rel_time)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return take_( ca, rel_time, lk);
+ }
+
+ bool try_take( callable & ca)
+ {
+ unique_lock< shared_mutex > lk( mtx_);
+ return try_take_( ca);
+ }
+};
+} }
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_TASK_UNBOUNDED_ONELOCK_SMART_QUEUE_H

Added: sandbox/task/boost/task/unbounded_twolock_fifo.hpp
==============================================================================
--- (empty file)
+++ sandbox/task/boost/task/unbounded_twolock_fifo.hpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -0,0 +1,169 @@
+
+// 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_TASK_UNBOUNDED_TWOLOCK_FIFO_H
+#define BOOST_TASK_UNBOUNDED_TWOLOCK_FIFO_H
+
+#include <cstddef>
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/foreach.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+
+#include <boost/task/callable.hpp>
+#include <boost/task/detail/atomic.hpp>
+#include <boost/task/detail/meta.hpp>
+#include <boost/task/exceptions.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost { namespace task
+{
+class unbounded_twolock_fifo
+{
+public:
+ typedef detail::has_no_attribute attribute_tag_type;
+ typedef callable value_type;
+
+private:
+ struct node
+ {
+ typedef shared_ptr< node > sptr_t;
+
+ value_type va;
+ sptr_t next;
+ };
+
+ volatile uint32_t state_;
+ node::sptr_t head_;
+ mutex head_mtx_;
+ node::sptr_t tail_;
+ mutex tail_mtx_;
+ condition not_empty_cond_;
+
+ bool active_() const
+ { return 0 == state_; }
+
+ void deactivate_()
+ { detail::atomic_fetch_add( & state_, 1); }
+
+ bool empty_()
+ { return head_ == get_tail_(); }
+
+ node::sptr_t get_tail_()
+ {
+ lock_guard< mutex > lk( tail_mtx_);
+ node::sptr_t tmp = tail_;
+ return tmp;
+ }
+
+ node::sptr_t pop_head_()
+ {
+ node::sptr_t old_head = head_;
+ head_ = old_head->next;
+ return old_head;
+ }
+
+public:
+ unbounded_twolock_fifo()
+ :
+ state_( 0),
+ head_( new node),
+ head_mtx_(),
+ tail_( head_),
+ tail_mtx_(),
+ not_empty_cond_()
+ {}
+
+ void deactivate()
+ { deactivate_(); }
+
+ bool empty()
+ {
+ unique_lock< mutex > lk( head_mtx_);
+ return empty_();
+ }
+
+ void put( value_type const& va)
+ {
+ node::sptr_t new_node( new node);
+ {
+ unique_lock< mutex > lk( tail_mtx_);
+ tail_->va = va;
+ tail_->next = new_node;
+ tail_ = new_node;
+ }
+ not_empty_cond_.notify_one();
+ }
+
+ bool take( value_type & va)
+ {
+ unique_lock< mutex > lk( head_mtx_);
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ while ( active_() && empty_() )
+ not_empty_cond_.wait( lk);
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ va.swap( head_->va);
+ pop_head_();
+ return ! va.empty();
+ }
+
+ template< typename Duration >
+ bool take(
+ value_type & va,
+ Duration const& rel_time)
+ {
+ unique_lock< mutex > lk( head_mtx_);
+ bool empty = empty_();
+ if ( ! active_() && empty)
+ return false;
+ if ( empty)
+ {
+ try
+ {
+ while ( active_() && empty_() )
+ if ( ! not_empty_cond_.timed_wait( lk, rel_time) )
+ return false;
+ }
+ catch ( thread_interrupted const&)
+ { return false; }
+ }
+ if ( ! active_() && empty_() )
+ return false;
+ va.swap( head_->va);
+ pop_head_();
+ return ! va.empty();
+ }
+
+ bool try_take( value_type & va)
+ {
+ unique_lock< mutex > lk( head_mtx_);
+ if ( empty_() )
+ return false;
+ va.swap( head_->va);
+ pop_head_();
+ return ! va.empty();
+ }
+};
+} }
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_TASK_UNBOUNDED_TWOLOCK_FIFO_H

Modified: sandbox/task/libs/task/build/Jamfile.v2
==============================================================================
--- sandbox/task/libs/task/build/Jamfile.v2 (original)
+++ sandbox/task/libs/task/build/Jamfile.v2 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -35,9 +35,9 @@
 
 alias task_sources
     : ## win32 sources ##
- guard.cpp
- interrupter.cpp
         callable.cpp
+ context.cpp
+ guard.cpp
         poolsize.cpp
         scanns.cpp
         semaphore_windows.cpp
@@ -52,9 +52,9 @@
 
 alias task_sources
     : ## posix sources ##
- guard.cpp
- interrupter.cpp
         callable.cpp
+ context.cpp
+ guard.cpp
         poolsize.cpp
         scanns.cpp
         semaphore_posix.cpp

Modified: sandbox/task/libs/task/doc/acknowledgements.qbk
==============================================================================
--- sandbox/task/libs/task/doc/acknowledgements.qbk (original)
+++ sandbox/task/libs/task/doc/acknowledgements.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -8,7 +8,7 @@
 
 [section:acknowledgements Appendix B: Acknowledgments]
 
-I'd like to thank Vicente J. Botet Escriba for his comments and contributions (this_task::delay, this_task::yield) as well Anthony Williams and Braddock Gaskill for their future libraries.
+I'd like to thank Vicente J. Botet Escriba for his comments and contributions (this_task::reschedule_until, this_task::delay, this_task::yield) as well Anthony Williams and Braddock Gaskill for their future libraries.
 
 
 [endsect]

Modified: sandbox/task/libs/task/doc/boost_task.qbk
==============================================================================
--- sandbox/task/libs/task/doc/boost_task.qbk (original)
+++ sandbox/task/libs/task/doc/boost_task.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -26,7 +26,7 @@
 [def __boost_future__ [@http://www.justsoftwaresolutions.co.uk/threading/updated-implementation-of-c++-futures-3.html [*Boost.Future]]]
 
 [template link_async[link_text] [link boost_task.async [link_text]]]
-[template link_channel[link_text] [link boost_task.execution_policy.pool.channel [link_text]]]
+[template link_queue[link_text] [link boost_task.execution_policy.pool.queue [link_text]]]
 [template link_forkjoin[link_text] [link boost_task.execution_policy.pool.forkjoin [link_text]]]
 [template link_handle[link_text] [link boost_task.async_completion_token.handle [link_text]]]
 [template link_own_thread[link_text] [link boost_task.own_thread [link_text]]]
@@ -42,7 +42,7 @@
 
 [def __as_sub_task__ `boost::task::as_sub_task`]
 [def __attribute_type__ `boost::task::attribute_type`]
-[def __bounded_channel__ `boost::task::bounded_channel`]
+[def __bounded_queue__ `boost::task::bounded_queue`]
 [def __dynamic_pool__ `boost::task::dynamic_pool`]
 [def __handle__ `boost::task::handle`]
 [def __has_attribute__ `boost::task::has_attribute`]
@@ -58,7 +58,7 @@
 [def __take_oldest__ `boost::task::take_oldest`]
 [def __task__ `boost::task::task`]
 [def __task_interrupted__ `boost::task::task_interrupted`]
-[def __unbounded_channel__ `boost::task::unbounded_channel`]
+[def __unbounded_queue__ `boost::task::unbounded_queue`]
 
 [def __make_task__ `boost::task::make_task()`]
 [def __waitfor_all__ `boost::task::waitfor_all()`]
@@ -77,16 +77,12 @@
 [def __fn_async__ `boost::task::async()`]
 [def __fn_make_task__ `boost::task::make_task()`]
 
-[def __fn_active__ `active()`]
 [def __fn_bind_to_processors__ `bind_to_processors()`]
 [def __fn_closed__ `close()`]
-[def __fn_clear__ `clear()`]
-[def __fn_empty__ `empty()`]
 [def __fn_get__ `get()`]
 [def __fn_get_future__ `get_future()`]
 [def __fn_has_value__ `has_value()`]
 [def __fn_has_exception__ `has_exception()`]
-[def __fn_idle__ `idle()`]
 [def __fn_interrupt__ `interrupt()`]
 [def __fn_interrupt_and_wait__ `interrupt_and_wait()`]
 [def __fn_interrupt_and_wait_for__ `interrupt_and_wait_for()`]
@@ -94,7 +90,6 @@
 [def __fn_interruption_requested__ `interruption_requested()`]
 [def __fn_is_ready__ `is_ready()`]
 [def __fn_operator__ `operator()()`]
-[def __fn_pending__ `pending()`]
 [def __fn_size__ `size()`]
 [def __fn_shutdown__ `shutdown()`]
 [def __fn_shutdown_now__ `shutdown_now()`]
@@ -108,12 +103,12 @@
 [def __eps__ ['execution-policies]]
 [def __blocked__ ['blocked]]
 [def __callable__ ['callable]]
-[def __channel__ ['channel]]
 [def __coop_task__ ['cooperative task]]
 [def __duration__ ['Duration]]
 [def __fork_join__ ['fork/join]]
 [def __interruption_point__ ['interruption-point]]
 [def __interruption_points__ ['interruption-points]]
+[def __queue__ ['queue]]
 [def __task_id__ ['task-id]]
 [def __thread_pool__ ['thread-pool]]
 [def __thread_pools__ ['thread-pools]]

Deleted: sandbox/task/libs/task/doc/channel.qbk
==============================================================================
--- sandbox/task/libs/task/doc/channel.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
+++ (empty file)
@@ -1,31 +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
-]
-
-
-[section:channel Channel]
-
-The channel synchronizes the access between non-pool threads (application threads) and __worker_threads__ and implements
-a queuing policy (limitation of queued tasks).
-
-
-[heading __bounded_channel__]
-
-__bounded_channel__ contains a single lock in order to synchronize access to the queue. The number of pending tasks is limited in order to prevent resource exhaustion.
-For this purpose a high- and low-watermark has to be passed at construction.
-__hwm__ sets the maximum of pending tasks. If this limited is reached all threads which submit a task will be set to sleep (blocked). If it is equal to __lwm__ everytime a
-sleeping producer thread will be woken up and puts its task if one worker thread has taken a task from the channel.
-__lwm__ sets the threshold when blocked threads get woken up. If it is less than __hwm__ all sleeping producer threads will be woken up if
-the amount of pending tasks reaches __lwm__.
-
-
-[heading __unbounded_channel__]
-
-__unbounded_channel__ contains a single lock in order to synchronize access to the queue. An unlimited number of tasks can be queued into this channel.
-The insertion of an __task__ will never block. If the channel becomes empty __worker_threads__ will be set to sleep until new tasks are enqueued.
-
-
-[endsect]

Modified: sandbox/task/libs/task/doc/fork_join.qbk
==============================================================================
--- sandbox/task/libs/task/doc/fork_join.qbk (original)
+++ sandbox/task/libs/task/doc/fork_join.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -54,11 +54,7 @@
 
         void main()
         {
- boost::task::static_pool<
- boost::task::unbounded_channel<
- boost::task::fifo
- >
- > pool( boost::task::poolsize( 5) );
+ boost::task::static_pool< boost::task::unbounded_twolock_fifo > pool( boost::task::poolsize( 5) );
 
                 // compute fibonacci-number 10
                 // for numbers < 5 do inline calculation

Modified: sandbox/task/libs/task/doc/introduction.qbk
==============================================================================
--- sandbox/task/libs/task/doc/introduction.qbk (original)
+++ sandbox/task/libs/task/doc/introduction.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -129,11 +129,7 @@
         void main()
         {
                 // create a thread-pool with five worker-threads
- boost::task::static_pool<
- boost::task::unbounded_channel<
- boost::task::fifo
- >
- > pool( boost::task::poolsize( 5) );
+ boost::task::static_pool< boost::task::unbounded_onelock_fifo > pool( boost::task::poolsize( 5) );
 
                 // execute task in a thread-pool
                 // move task ownership to executor

Modified: sandbox/task/libs/task/doc/meta_functions.qbk
==============================================================================
--- sandbox/task/libs/task/doc/meta_functions.qbk (original)
+++ sandbox/task/libs/task/doc/meta_functions.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -15,11 +15,7 @@
 ``
         // thread-pool with priority scheduling
         // type of priority is int
- typdef boost::task::static_pool<
- boost::task::unbounded_channel<
- boost::task::priority< int >
- >
- > pool_type;
+ typdef boost::task::static_pool< boost::task::unbounded_onelock_priority< int > > pool_type;
 
         // test if thread-pool supports priorities at compile time
         std::cout << std::boolalpha << boost::task::has_attribute< pool_type >::value << "\n";

Modified: sandbox/task/libs/task/doc/overview.qbk
==============================================================================
--- sandbox/task/libs/task/doc/overview.qbk (original)
+++ sandbox/task/libs/task/doc/overview.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -76,11 +76,7 @@
         void main()
         {
                 // create a thread-pool
- boost::task::static_pool<
- boost::task::unbounded_channel<
- boost::task::fifo
- >
- > pool( boost::task::poolsize( 5) );
+ boost::task::static_pool< boost::task::unbounded_twolock_fifo > > pool( boost::task::poolsize( 5) );
 
                 // execute tasks in thread-pool
                 // move tasks ownership to executor

Modified: sandbox/task/libs/task/doc/pool.qbk
==============================================================================
--- sandbox/task/libs/task/doc/pool.qbk (original)
+++ sandbox/task/libs/task/doc/pool.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -12,7 +12,7 @@
 creation and destruction can be avoided by running the __work_items__ on a __thread_pool__ (reusing an existing
 __worker_thread__ instead).
 
-A __thread_pool__ maintains a queue (or queues) of __work_items__ to be done, and a pool of __worker_threads__ which execute __work_items__ from the queue(s).
+A __thread_pool__ maintains a global queue of __work_items__ to be processed, and a pool of __worker_threads__ which execute __work_items__ from the global queue.
 
 __boost_task__ provides __fn_async__ with support of executing an __task__ in __thread_pool__:
 
@@ -27,11 +27,7 @@
                 // five worker-threads
                 // FIFO schduling of queued tasks
                 // and unlimited size of internal queue
- boost::task::static_pool<
- boost::task::unbounded_channel<
- boost::task::fifo
- >
- > pool( boost::task::poolsize( 5) );
+ boost::task::static_pool< boost::task::unbounded_twolock_fifo > pool( boost::task::poolsize( 5) );
 
                 // create task
                 boost::task::task< std::string > t( echo, "Hello World!");
@@ -55,8 +51,7 @@
 
 
 [include static_pool.qbk]
-[include channel.qbk]
-[include scheduler.qbk]
+[include queue.qbk]
 [include shutdown.qbk]
 [include processor_binding.qbk]
 [include work_stealing.qbk]

Modified: sandbox/task/libs/task/doc/processor_binding.qbk
==============================================================================
--- sandbox/task/libs/task/doc/processor_binding.qbk (original)
+++ sandbox/task/libs/task/doc/processor_binding.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -13,7 +13,7 @@
 
 ``
         typedef boost::task::static_pool<
- boost::task::unbounded_channel< boost::tp::fifo >
+ boost::task::unbounded_queue< boost::tp::fifo >
> pool_type;
 
         // constructs thread-pool with worker-threads as
@@ -21,7 +21,7 @@
         pool_type pool( pool_type::bind_to_processors() );
 ``
 
-The constructor takes additional arguments for the [link_work_stealing work-stealing algorithm] and [link_channel high-] and [link_channel low-watermark] too.
+The constructor takes additional arguments for the [link_work_stealing work-stealing algorithm] and [link_queue high-] and [link_queue low-watermark] too.
 
 [note __boost_task__ does provide this feature only for Windows, Linux, AIX, HP-UX, Solaris and FreeBSD.]
 

Added: sandbox/task/libs/task/doc/queue.qbk
==============================================================================
--- (empty file)
+++ sandbox/task/libs/task/doc/queue.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -0,0 +1,136 @@
+[/
+ 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:queue Queues]
+
+A __queue__ synchronizes the access between application threads and __worker_threads__ and implements policies for limitating the amount of queued tasks and how those tasks are scheduled ( first-in-first-out, priority ordering etc.
+
+
+[heading Bounded queues]
+
+__bounded_queue__ limits the number of queued (pending) tasks in order to prevent resource exhaustion.
+For this purpose a high- and low-watermark has to be passed at construction.
+__hwm__ sets the maximum of pending tasks. If this limited is reached all threads which submit a task will be set to sleep (blocked). If it is equal to __lwm__ everytime a
+sleeping producer thread will be woken up and puts its task if one worker thread has taken a task from the queue.
+__lwm__ sets the threshold when blocked threads get woken up. If it is less than __hwm__ all sleeping producer threads will be woken up if
+the amount of pending tasks reaches __lwm__.
+
+
+[heading Unbounded queues]
+
+__unbounded_queue__ allows ann unlimited number of tasks to be queued.
+The insertion of an __task__ will never block. If the queue becomes empty __worker_threads__ will be set to sleep until new tasks are enqueued.
+
+
+[heading Onelock queues]
+
+All operation on this queue are protected by one lock (one mutex).
+
+
+[heading Twolock queues]
+
+This kind of queue uses two different locks (mutexes) for put- and take-operations gaining a better performance._
+
+
+[heading Scheduling]
+
+For scheduling of tasks inside the queue following strategies are available:
+
+* fifo: first enqueued task is dequeued first
+
+* priority: the next item dequeued from the queue depends on its associated priority attribute and sorting criterion applied to the queue (template arguments)
+
+``
+ // thread-pool with priority scheduling
+ // tasks with higher priority are
+ // scheduled first
+ boost::task::static_pool< boost::task::unbounded_onelock_priority_queue< int > > pool( boost::task::poolsize( 5) );
+
+ boost::task::task< void > t1( some_fn);
+ boost::task::task< void > t2( another_fn);
+
+ // move task t1 with priority 5 to thread-pool
+ boost::task::async(
+ boost::move( t1),
+ 5,
+ pool);
+
+ // move task t2 with priority 3 to thread-pool
+ boost::task::async(
+ boost::move( t2),
+ 3,
+ pool);
+``
+
+* smart: enqueue- and dequeue-operations are determined by the template arguments und the task-attribute. The library provides an default let only one kind of task stored inside the queue (gets replaced by new one)
+
+``
+ long fibonacci_fn( long n)
+ {
+ if ( n == 0) return 0;
+ if ( n == 1) return 1;
+ long k1( 1), k2( 0);
+ for ( int i( 2); i <= n; ++i)
+ {
+ long tmp( k1);
+ k1 = k1 + k2;
+ k2 = tmp;
+ }
+ return k1;
+ }
+
+ typedef boost::task::static_pool< boost::task::unbounded_onelock_smart_queue< int > > pool_type;
+
+ void main()
+ {
+ pool_type pool( boost::task::poolsize( 1) );
+
+ ...
+
+ boost::task::task< long > t1(
+ boost::bind( fibonacci_fn, 10) );
+ boost::task::task< long > t2(
+ boost::bind( fibonacci_fn, 5) );
+
+ // replaced by later task with same attribute == 2
+ // if still pending in pool
+ boost::task::async(
+ boost::move( t1),
+ 2,
+ pool);
+
+ // will replace previous pending task with attribute == 2
+ boost::task::async(
+ boost::move( t2),
+ 2,
+ pool);
+ }
+``
+
+
+__boost_task__ provides following queues:
+
+* bounded_onelock_fifo
+
+* bounded_onelock_priority_queue< Attr, Comp = std::less< Attr > >
+
+* bounded_onelock_smart_queue< Attr, Comp, Enq = detail::replace_oldest, Deq = detail::take_oldest >
+
+* bounded_twolock_fifo
+
+
+* unbounded_onelock_fifo
+
+* unbounded_onelock_priority_queue< Attr, Comp = std::less< Attr > >
+
+* unbounded_onelock_smart_queue< Attr, Comp, Enq = detail::replace_oldest, Deq = detail::take_oldest >
+
+* unbounded_twolock_fifo
+
+
+[endsect]

Modified: sandbox/task/libs/task/doc/ref_callable.qbk
==============================================================================
--- sandbox/task/libs/task/doc/ref_callable.qbk (original)
+++ sandbox/task/libs/task/doc/ref_callable.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -16,15 +16,18 @@
         public:
                 callable();
 
+ template< typename R >
+ callable( task< R > t, context const& ctx);
+
                 void operator()();
 
                 bool empty() const;
 
                 void clear();
 
- void reset();
-
                 void reset( shared_ptr< thread > const& thrd);
+
+ void swap( callable &);
         };
 ``
 
@@ -39,6 +42,17 @@
 ]
 
 
+[heading Constructor `callable( task< R >, context const&)`]
+
+ template< typename R >
+ callable( task< R > t, context const& ctx)
+
+[variablelist
+[[Effects:] [constructs an callable associated with an task and a specific context]]
+[[Throws:] [Nothing]]
+]
+
+
 [heading Member function `operator()()`]
 
         void operator()()
@@ -69,22 +83,22 @@
 ]
 
 
-[heading Member function `reset()`]
+[heading Member function `reset( shared_ptr< thread> const&)`]
 
- void reset()
+ void reset( shared_ptr< thread > const& thrd)
 
 [variablelist
-[[Effects:] [clears internal thrread-context]]
+[[Effects:] [sets internal thread-context]]
 [[Throws:] [Nothing]]
 ]
 
 
-[heading Member function `reset( shared_ptr< thread> const& thrd)`]
+[heading Member function `swap( callable &)`]
 
- void reset( shared_ptr< thread > const& thrd)
+ void swap( callable & ca)
 
 [variablelist
-[[Effects:] [sets internal thread-context]]
+[[Effects:] [swaps content of both callable instances]]
 [[Throws:] [Nothing]]
 ]
 

Modified: sandbox/task/libs/task/doc/ref_context.qbk
==============================================================================
--- sandbox/task/libs/task/doc/ref_context.qbk (original)
+++ sandbox/task/libs/task/doc/ref_context.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -14,33 +14,65 @@
         class context
         {
         public:
- template< typename R >
- callable get_callable( task< R > t);
+ context();
 
- template< typename R >
- handle< R > get_handle( shared_future< R > f);
+ void reset( shared_ptr< thread > const& thrd);
+
+ void interrupt();
+
+ bool interruption_requested();
+
+ void swap( context & other);
         };
 ``
 
 
-[heading Templated member function `get_callable( task< R > t)`]
+[heading Constructor `callable()`]
+
+ callable()
+
+[variablelist
+[[Effects:] [creates an context object]
+[[Throws:] [Nothing]]
+]
+
+
+[heading Member function `reset( shared_ptr< thread> const&)`]
+
+ void reset( shared_ptr< thread > const& thrd)
+
+[variablelist
+[[Effects:] [sets internal thread-context]]
+[[Throws:] [Nothing]]
+]
+
+
+[heading Member function `interrupt()`]
+
+ void interrupt()
+
+[variablelist
+[[Effects:] [request interruption of associated task]]
+[[Throws:] [Nothing]]
+]
+
+
+[heading Member function `interruption_requested()`]
 
- template< typename R >
- callable get_callable( task< R > t);
+ bool interruption_requested()
 
 [variablelist
-[[Effects:] [returns a callable containing the moved task< R >]]
+[[Effects:] [retuns true if interruption of associated task is requested]]
 [[Throws:] [Nothing]]
 ]
 
 
-[heading Templated member function `get_handle( shared_future< R > f)`]
+[heading Member function `swap( context &)`]
 
- template< typename R >
- handle< R > get_handle( shared_future< R > f);
+ void swap( context & ctx)
 
 [variablelist
-[[Effects:] [returns a handle associated to the moved task< R >]]
+[[Effects:] [swaps content of both context instances]]
 [[Throws:] [Nothing]]
 ]
 

Modified: sandbox/task/libs/task/doc/ref_handle.qbk
==============================================================================
--- sandbox/task/libs/task/doc/ref_handle.qbk (original)
+++ sandbox/task/libs/task/doc/ref_handle.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -14,6 +14,7 @@
         class handle
         {
                 handle();
+ handle( shared_future< R >, context const&);
 
                 void interrupt();
                 void interrupt_and_wait();
@@ -52,7 +53,7 @@
         friend unsigned int waitfor_any( handle< T1 > & t1, handle< T2 > & t2, handle< T3 > & t3, handle< T4 > & t4, handle< T5 > & t5);
 ``
 
-[heading Constructor]
+[heading Constructor `handle()`]
 
         handle()
 
@@ -62,6 +63,16 @@
 ]
 
 
+[heading Constructor `handle( shared_future< R >, context const&)`]
+
+ handle( shared_future< R >, context const&);
+
+[variablelist
+[[Effects:] [constructs an handle associated with anfuture and an context]]
+[[Throws:] [Nothing]]
+]
+
+
 [heading Member function `interruption_requested()`]
 
         bool interruption_requested()

Modified: sandbox/task/libs/task/doc/ref_static_pool.qbk
==============================================================================
--- sandbox/task/libs/task/doc/ref_static_pool.qbk (original)
+++ sandbox/task/libs/task/doc/ref_static_pool.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -52,18 +52,13 @@
                 ~static_pool();
 
                 std::size_t size();
- std::size_t active();
- std::size_t idle();
 
                 void shutdown();
                 void shutdown_now();
 
- void interrupt_all_worker();
-
                 bool closed();
- void clear();
- bool empty();
- std::size_t pending();
+
+ void interrupt_all_worker();
 
                 const std::size_t upper_bound();
                 void upper_bound( high_watermark const& hwm);
@@ -93,7 +88,7 @@
 ]
 
 
-[heading Constructor (unbounded channel)]
+[heading Constructor (unbounded queue)]
 
         explicit static_pool(
                 <<unspec-type>>,
@@ -104,11 +99,11 @@
 [[Preconditions:] [operating system provides functionality for processor binding]]
 [[Effects:] [constructs a pool - for each processor a worker-thread is created and bound to one processor - global-queue can queue an unlimited number of tasks]]
 [[Throws:] [`boost::thread_resource_error`, `boost::task::invalid_scanns`, `boost::task::invalid_timeduration`]]
-[[Notes:] [constructor has to be called if a unbounded-channel is used and `bind_to_processors()` must be set as first argument]]
+[[Notes:] [constructor has to be called if a unbounded-queue is used and `bind_to_processors()` must be set as first argument]]
 ]
 
 
-[heading Constructor (unbounded channel/poolsize)]
+[heading Constructor (unbounded queue/poolsize)]
 
         explicit static_pool(
                 poolsize const& psize,
@@ -118,11 +113,11 @@
 [variablelist
 [[Effects:] [constructs a pool containing psize worker-threads - global-queue can queue an unlimited number of tasks]]
 [[Throws:] [`boost::thread_resource_error`, `boost::task::invalid_scanns`, `boost::task::invalid_timeduration`]]
-[[Notes:] [constructor has to be called if a unbounded-channel is used]]
+[[Notes:] [constructor has to be called if a unbounded-queue is used]]
 ]
 
 
-[heading Constructor (bounded channel)]
+[heading Constructor (bounded queue)]
 
         explicit static_pool(
                 <<unspec-type>>,
@@ -135,11 +130,11 @@
 [[Preconditions:] [operating system provides functionality for processor binding]]
 [[Effects:] [constructs a pool - for each processor a worker-thread is created and bound to one processor - global-queue can only queue a limited number of tasks]]
 [[Throws:] [`boost::thread_resource_error`, `boost::task::invalid_scanns`, `boost::task::invalid_timeduration`, `boost::task::invalid_watermark`]]
-[[Notes:] [constructor has to be called if a bounded-channel is used and `bind_to_processors()` must be set as first argument]]
+[[Notes:] [constructor has to be called if a bounded-queue is used and `bind_to_processors()` must be set as first argument]]
 ]
 
 
-[heading Constructor (bounded channel/poolsize)]
+[heading Constructor (bounded queue/poolsize)]
 
         explicit static_pool(
                 poolsize const& psize,
@@ -151,7 +146,7 @@
 [variablelist
 [[Effects:] [constructs a pool containing psize worker-threads - global-queue can only queue a limited number of tasks]]
 [[Throws:] [`boost::thread_resource_error`, `boost::task::invalid_scanns`, `boost::task::invalid_timeduration`, `boost::task::invalid_watermark`]]
-[[Notes:] [constructor has to be called if a bounded-channel is used]]
+[[Notes:] [constructor has to be called if a bounded-queue is used]]
 ]
 
 
@@ -205,33 +200,12 @@
 ]
 
 
-[heading Member function `active()`]
-
- std::size_t active()
-
-[variablelist
-[[Effects:] [returns how many worker-threads are active (executing an task)]]
-[[Throws:] [`boost::task::pool_moved`]]
-]
-
-
-[heading Member function `idle()`]
-
- std::size_t idle()
-
-[variablelist
-[[Effects:] [returns how many worker-threads are idle (not executing an task).]]
-[[Throws:] [`boost::task::pool_moved`]]
-[[Notes:] [the value is the difference of `size()` and `active()`]]
-]
-
-
 [heading Member function `shutdown()`]
 
         void shutdown()
 
 [variablelist
-[[Effects:] [deactivates the channel and joins all worker-threads - the pool is closed]]
+[[Effects:] [deactivates the queue and joins all worker-threads - the pool is closed]]
 [[Throws:] [`boost::thread_interrupted`, `boost::system::system_error`, `boost::task::pool_moved`]]
 [[Notes:] [all pending tasks are processed]]
 ]
@@ -242,7 +216,7 @@
         void shutdown_now()
 
 [variablelist
-[[Effects:] [deactivates the channel, send interruption request to all worker-threads and joins them - the pool is closed]]
+[[Effects:] [deactivates the queue, send interruption request to all worker-threads and joins them - the pool is closed]]
 [[Throws:] [`boost::thread_interrupted`, `boost::system::system_error`, `boost::task::pool_moved`]]
 [[Notes:] [pending tasks are not processed but returned]]
 ]
@@ -268,45 +242,15 @@
 ]
 
 
-[heading Member function `clear()`]
-
- void clear()
-
-[variablelist
-[[Effects:] [removes all pending tasks from the channel]]
-[[Throws:] [`boost::task::pool_moved`]]
-]
-
-
-[heading Member function `empty()`]
-
- bool empty()
-
-[variablelist
-[[Effects:] [queries if the channel is empty]]
-[[Throws:] [`boost::task::pool_moved`]]
-]
-
-
-[heading Member function `pending()`]
-
- std::size_t pending()
-
-[variablelist
-[[Effects:] [queries how many tasks are pending (still unprocessed) in the global-queue (channel)]]
-[[Throws:] [`boost::task::pool_moved`]]
-]
-
-
 [heading Member function `upper_bound()`]
 
         std::size_t upper_bound()
 
 [variablelist
-[[Preconditions:] [channel is of type bounded-channel]]
-[[Effects:] [returns the upper bound of the bounded-channel]]
+[[Preconditions:] [queue is of type bounded-queue]]
+[[Effects:] [returns the upper bound of the bounded-queue]]
 [[Throws:] [`boost::task::pool_moved`]]
-[[Notes:] [can only be used if a bounded-channel is used]]
+[[Notes:] [can only be used if a bounded-queue is used]]
 ]
 
 
@@ -315,11 +259,11 @@
         void upper_bound( high_watermark const& hwm)
 
 [variablelist
-[[Preconditions:] [channel is of type bounded-channel]]
-[[Effects:] [sets the upper bound of the bounded-channel]]
+[[Preconditions:] [queue is of type bounded-queue]]
+[[Effects:] [sets the upper bound of the bounded-queue]]
 [[Postconditions:] [`this->upper_bound() == hwm`]]
 [[Throws:] [`boost::task::invalid_watermark`, `boost::task::pool_moved`]]
-[[Notes:] [can only be used if a bounded-channel is used]]
+[[Notes:] [can only be used if a bounded-queue is used]]
 ]
 
 
@@ -328,10 +272,10 @@
         std::size_t lower_bound();
 
 [variablelist
-[[Preconditions:] [channel is of type bounded-channel]]
-[[Effects:] [returns the lower bound of the bounded-channel]]
+[[Preconditions:] [queue is of type bounded-queue]]
+[[Effects:] [returns the lower bound of the bounded-queue]]
 [[Throws:] [`boost::task::pool_moved`]]
-[[Notes:] [can only be used if a bounded-channel is used]]
+[[Notes:] [can only be used if a bounded-queue is used]]
 ]
 
 
@@ -340,11 +284,11 @@
         void lower_bound( low_watermark const& lwm)
 
 [variablelist
-[[Preconditions:] [channel is of type bounded-channel]]
-[[Effects:] [sets the lower bound of the bounded-channel]]
+[[Preconditions:] [queue is of type bounded-queue]]
+[[Effects:] [sets the lower bound of the bounded-queue]]
 [[Postconditions:] [`this->lower_bound() == lwm`]]
 [[Throws:] [`boost::task::invalid_watermark`, `boost::task::pool_moved`]]
-[[Notes:] [can only be used if a bounded-channel is used]]
+[[Notes:] [can only be used if a bounded-queue is used]]
 ]
 
 

Modified: sandbox/task/libs/task/doc/ref_utility.qbk
==============================================================================
--- sandbox/task/libs/task/doc/ref_utility.qbk (original)
+++ sandbox/task/libs/task/doc/ref_utility.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -6,6 +6,24 @@
 ]
 
 
+[section:reschedule_until Non-member function `reschedule_until()`]
+
+``
+ #include <boost/task/utility.hpp>
+
+ template< typename Pred >
+ void reschedule_until( Pred const&)
+``
+
+[variablelist
+[[Effects:] [reschedules current task until passed callable predicate becomes ready]]
+[[Throws:] [`boost::thread_interrupted`,`boost::system::system_error`]]
+[[Note:] [this function resides in namespace `boost::this_task`]]
+]
+
+[endsect]
+
+
 [section:get_pool Non-member function `get_pool()`]
 
 ``
@@ -50,22 +68,61 @@
 ``
 
 [variablelist
-[[Effects:] [returns the thread-id of the worker-thread]]
+[[Effects:] [returns returns the thread-id of the worker-thread]]
+[[Throws:] [nothing]]
+[[Note:] [this function resides in namespace `boost::this_task`]]
+]
+
+[endsect]
+
+
+[section:delay Non-member function `delay()`]
+
+``
+ #include <boost/task/utility.hpp>
+
+ void delay( system_time abs_time)
+
+ template< typename Duration >
+ void delay( Duration const& rel_time)
+``
+
+[variablelist
+[[Effects:] [delays the execution of the current task so that the worker-thread can process another task in the meantime]]
+[[Throws:] [nothing]]
+[[Note:] [this function resides in namespace `boost::this_task`]]
+]
+
+[endsect]
+
+
+[section:yield Non-member function `yield()`]
+
+``
+ #include <boost/task/utility.hpp>
+
+ void yield()
+``
+
+[variablelist
+[[Effects:] [yields the current task so that the worker-threadcan process another task in the meantime]]
 [[Throws:] [nothing]]
 [[Note:] [this function resides in namespace `boost::this_task`]]
 ]
 
+[endsect]
+
 
-[section:worker_id Non-member function `block()`]
+[section:interrupt Non-member function `interrupt()`]
 
 ``
         #include <boost/task/utility.hpp>
 
- bool block()
+ void interrupt()
 ``
 
 [variablelist
-[[Effects:] [blocks current context of execution and returns true if threadpool was shutdown]]
+[[Effects:] [task can request interruption for itself]]
 [[Throws:] [nothing]]
 [[Note:] [this function resides in namespace `boost::this_task`]]
 ]

Modified: sandbox/task/libs/task/doc/scheduler.qbk
==============================================================================
--- sandbox/task/libs/task/doc/scheduler.qbk (original)
+++ sandbox/task/libs/task/doc/scheduler.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -8,7 +8,7 @@
 
 [section:scheduling Scheduling]
 
-The scheduling policy determines how tasks are scheduled inside the __channel__.
+The scheduling policy determines how tasks are scheduled inside the __queue__.
 
 
 [heading fifo]
@@ -25,7 +25,7 @@
         // tasks with higher priority are
         // scheduled first
         boost::task::static_pool<
- boost::task::unbounded_channel<
+ boost::task::unbounded_queue<
                         boost::task::priority< int > >
> pool( boost::task::poolsize( 5) );
 
@@ -54,7 +54,7 @@
         // tasks with lower priority are
         // scheduled first
         boost::task::static_pool<
- boost::task::unbounded_channel<
+ boost::task::unbounded_queue<
                         boost::task::priority< int, std::less< int > >
>
> pool( boost::task::poolsize( 5) );
@@ -85,7 +85,7 @@
         }
 
         typedef boost::task::static_pool<
- boost::task::unbounded_channel<
+ boost::task::unbounded_queue<
                         boost::task::smart<
                                 int,
                                 std::less< int >,

Modified: sandbox/task/libs/task/doc/shutdown.qbk
==============================================================================
--- sandbox/task/libs/task/doc/shutdown.qbk (original)
+++ sandbox/task/libs/task/doc/shutdown.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -33,11 +33,7 @@
                 return k1;
         }
 
- typedef boost::task::static_pool<
- boost::task::unbounded_channel<
- boost::task::fifo
- >
- > pool_type;
+ typedef boost::task::static_pool< boost::task::unbounded_onelock_fifo > pool_type;
 
         void main()
         {
@@ -88,11 +84,7 @@
                 return k1;
         }
 
- typedef boost::task::static_pool<
- boost::task::unbounded_channel<
- boost::task::fifo
- >
- > pool_type;
+ typedef boost::task::static_pool< boost::task::unbounded_twolock_fifo > pool_type;
 
         void main()
         {

Modified: sandbox/task/libs/task/doc/static_pool.qbk
==============================================================================
--- sandbox/task/libs/task/doc/static_pool.qbk (original)
+++ sandbox/task/libs/task/doc/static_pool.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -13,10 +13,8 @@
 
 
 ``
- boost::task::_static_pool< // pool type
- boost::task::unbounded_channel< // queuing policy (unbounded_channel, bounded_channel)
- boost::task::fifo // scheduling policy (fifo, priority, smart)
- >
+ boost::task::_static_pool< // pool type
+ boost::task::unbounded_twolock_fifo // queue where application threads enqueue tasks
> pool(
                 boost::task::poolsize( 6), // pool with 6 pre-forked worker-threads
                 boost::posix_time::posix_time::milliseconds( 50), // time to sleep if no work-item available
@@ -27,17 +25,10 @@
 The first argument of the constructor specifies how many __worker_threads__ the pool will contain. The second
 and third argument are used by the [link_work_stealing __work_stealing__] algorithm.
 
-[note If __bounded_channel__ is used as queuing policy the constructor has two additional arguments . ]
+[note If __bounded_queue__ is used as queuing policy the constructor has two additional arguments . ]
 
 __static_pool__ provides functionality to check the status of the pool - __fn_closed__ returns true when the pool was
-shutdown and __fn_active__ as well as __fn_idle__ returning how many __worker_threads__ are active (executing a task) or idle.
-The size of the pool can be accessed over __fn_size__.
-
-For informational pruposes __fn_empty__ and __fn_pending__ can be used in order to know if the global task-queue is empty or
-how many tasks are waiting for execution. With __fn_clear__ all tasks are removed from the global-queue.
-
-[note __fn_pending__ does not count tasks in the local-queues of the __worker_threads__.]
-
+shutdown and __fn_size__returns the number of __worker_threads__.
 
 [endsect]
 

Modified: sandbox/task/libs/task/doc/task.qbk
==============================================================================
--- sandbox/task/libs/task/doc/task.qbk (original)
+++ sandbox/task/libs/task/doc/task.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -251,11 +251,7 @@
         void main()
         {
                 // create thread-pool with five worker-threads
- boost::task::static_pool<
- boost::task::unbounded_channel<
- boost::task::fifo
- >
- > pool( boost::task::poolsize( 5) );
+ boost::task::static_pool< boost::task::unbounded_twolock_fifo > pool( boost::task::poolsize( 5) );
 
                 // create task computing fibonacci-number for 10
                 boost::task::task< long > t(

Modified: sandbox/task/libs/task/doc/todo.qbk
==============================================================================
--- sandbox/task/libs/task/doc/todo.qbk (original)
+++ sandbox/task/libs/task/doc/todo.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -10,9 +10,7 @@
 
 [heading Optimizations]
  
-* finer-grained locking for bounded_channel and unbounded_channel using two-lock-queue
-
-* lock-free-queue with fifo ordering as channel
+* lock-free-queue with fifo ordering as queue
 
 
 [heading Dynamic thread-pool]

Modified: sandbox/task/libs/task/doc/user_defined_executor.qbk
==============================================================================
--- sandbox/task/libs/task/doc/user_defined_executor.qbk (original)
+++ sandbox/task/libs/task/doc/user_defined_executor.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -15,64 +15,14 @@
 
 * create an context (link between handle and task)
 
-* create an handle< R > via context and shared_future< R >
+* create an handle< R > passing shared_future< R > and context
 
-* create a callable via context an the moved task< R >
+* create a callable apply task< R > (move) and context to the ctor
 
 * pass the callable to the executor
 
 * return the handle
 
-In the sample code below the task is executed in a fiber (__boost_fiber__).
-
-
-``
- class new_fiber
- {
- private:
- fiber::scheduler & sched_;
-
- public:
- new_fiber( fiber::scheduler & sched)
- : sched_( sched)
- {}
-
- template< typename R >
- handle< R > operator()( task< R > t)
- {
- // get shared_future< R > from task< R >
- shared_future< R > f( t.get_future() );
-
- // create an context
- context ctx;
-
- // create an handle< R > out of the context and the future
- handle< R > h( ctx.get_handle( f) );
-
- // create an callable containing the moved task< R >
- callable ca( ctx.get_callable( boost::move( t) ) );
-
- // apply the callable to the executor == fiber-scheduler
- sched_.submit( ca);
-
- // return the handle
- return h;
- }
- };
-
-
- void main()
- {
- boost::fiber::scheduler sched;
-
- boost::task::handle< long > h1(
- boost::task::async(
- boost::make_task( ... ),
- sched);
-
- sched.run();
- }
-``
 
 [endsect]
  

Modified: sandbox/task/libs/task/doc/utilities.qbk
==============================================================================
--- sandbox/task/libs/task/doc/utilities.qbk (original)
+++ sandbox/task/libs/task/doc/utilities.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -12,6 +12,13 @@
 runs in a __thread_pool__).
 
 
+[heading reschedule_until]
+
+In the function `boost::this_task::reschedule_until( Pred const&)` allows to synchronize the task with other asynchronous events
+without blocking the __worker_threads__ (bool Pred::operator()() must not block). The current task will be rescheduled until the
+passed predicate becomes true.
+
+
 [heading get_pool]
 
 The pool in which the current code (__task__) is executed can be accessed via __fn_get_pool__. If hte code is not executed by a
@@ -28,4 +35,20 @@
 __fn_worker_id__ returns the __thread_id__ of the __worker_thread__ executing the current __task__.
 
 
+[heading delay]
+
+The execution of a __task__ can be delayed for a time-duration or until a specific time-point with __fn_delay__.
+
+
+[heading yield]
+
+If a __task__ detects that it would bould block it can yield itself with __fn_yield__ so that the __worker_thread__ can execute
+another __task__ in the meantime.
+
+
+[heading interrupt]
+
+A __task__ can interrupt itself via __fn_tt_interrupt__.
+
+
 [endsect]

Modified: sandbox/task/libs/task/doc/work_stealing.qbk
==============================================================================
--- sandbox/task/libs/task/doc/work_stealing.qbk (original)
+++ sandbox/task/libs/task/doc/work_stealing.qbk 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -21,7 +21,7 @@
 from the ['public end] (accessed by the other __worker_threads__). Synchronization is necessary when the queue is sufficiently small
 that private and public operations could conflict.
 
-The pool contains one global-queue (__bounded_channel__ or __unbounded_channel__) protected by a global-lock and each __worker_thread__
+The pool contains one global-queue (__bounded_queue__ or __unbounded_queue__) protected by a global-lock and each __worker_thread__
 has its own private local worker-queue. If work is enqueued by a __worker_thread__ the __task__ is stored in the worker queue. If the
 work is enqueued by a application thread it goes into the global queue. When __worker_threads__ are looking for work, they have
 following search order:

Modified: sandbox/task/libs/task/examples/Jamfile.v2
==============================================================================
--- sandbox/task/libs/task/examples/Jamfile.v2 (original)
+++ sandbox/task/libs/task/examples/Jamfile.v2 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -35,7 +35,6 @@
 exe no_deadlock_pool : no_deadlock_pool.cpp ;
 exe no_deadlock_pool2 : no_deadlock_pool2.cpp ;
 exe no_deadlock_pool3 : no_deadlock_pool3.cpp ;
-exe pending : pending.cpp ;
 exe priority : priority.cpp ;
 exe semaphore_thread : semaphore_thread.cpp ;
 exe semaphore_pool : semaphore_pool.cpp ;

Modified: sandbox/task/libs/task/examples/bind_to_processors.cpp
==============================================================================
--- sandbox/task/libs/task/examples/bind_to_processors.cpp (original)
+++ sandbox/task/libs/task/examples/bind_to_processors.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -18,7 +18,7 @@
 namespace pt = boost::posix_time;
 namespace tsk = boost::task;
 
-typedef tsk::static_pool< tsk::unbounded_channel< tsk::fifo > > pool_type;
+typedef tsk::static_pool< tsk::unbounded_onelock_fifo > pool_type;
 
 int serial_fib( int n)
 {

Modified: sandbox/task/libs/task/examples/buffer_multi.cpp
==============================================================================
--- sandbox/task/libs/task/examples/buffer_multi.cpp (original)
+++ sandbox/task/libs/task/examples/buffer_multi.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -18,7 +18,7 @@
 
 namespace tsk = boost::task;
 
-typedef tsk::static_pool< tsk::unbounded_channel< tsk::fifo > > pool_type;
+typedef tsk::static_pool< tsk::unbounded_twolock_fifo > pool_type;
 
 int serial_fib( int n)
 {

Modified: sandbox/task/libs/task/examples/buffer_multi2.cpp
==============================================================================
--- sandbox/task/libs/task/examples/buffer_multi2.cpp (original)
+++ sandbox/task/libs/task/examples/buffer_multi2.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -18,7 +18,7 @@
 
 namespace tsk = boost::task;
 
-typedef tsk::static_pool< tsk::unbounded_channel< tsk::fifo > > pool_type;
+typedef tsk::static_pool< tsk::unbounded_twolock_fifo > pool_type;
 
 int serial_fib( int n)
 {

Modified: sandbox/task/libs/task/examples/buffer_pool.cpp
==============================================================================
--- sandbox/task/libs/task/examples/buffer_pool.cpp (original)
+++ sandbox/task/libs/task/examples/buffer_pool.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -18,9 +18,7 @@
 {
         try
         {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 1) );
+ tsk::static_pool< tsk::unbounded_twolock_fifo > pool( tsk::poolsize( 1) );
 
                 int n = 5;
                 tsk::unbounded_buffer< std::string > buf_ping, buf_pong;

Modified: sandbox/task/libs/task/examples/buffer_pool_thread.cpp
==============================================================================
--- sandbox/task/libs/task/examples/buffer_pool_thread.cpp (original)
+++ sandbox/task/libs/task/examples/buffer_pool_thread.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -18,9 +18,7 @@
 {
         try
         {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 1) );
+ tsk::static_pool< tsk::unbounded_twolock_fifo > pool( tsk::poolsize( 1) );
 
                 int n = 10;
                 tsk::unbounded_buffer< std::string > buf_ping, buf_pong;

Modified: sandbox/task/libs/task/examples/fork_join.cpp
==============================================================================
--- sandbox/task/libs/task/examples/fork_join.cpp (original)
+++ sandbox/task/libs/task/examples/fork_join.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -17,7 +17,7 @@
 namespace pt = boost::posix_time;
 namespace tsk = boost::task;
 
-typedef tsk::static_pool< tsk::unbounded_channel< tsk::fifo > > pool_type;
+typedef tsk::static_pool< tsk::unbounded_twolock_fifo > pool_type;
 
 int serial_fib( int n)
 {

Modified: sandbox/task/libs/task/examples/interrupt.cpp
==============================================================================
--- sandbox/task/libs/task/examples/interrupt.cpp (original)
+++ sandbox/task/libs/task/examples/interrupt.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -17,7 +17,7 @@
 namespace pt = boost::posix_time;
 namespace tsk = boost::task;
 
-typedef tsk::static_pool< tsk::unbounded_channel< tsk::fifo > > pool_type;
+typedef tsk::static_pool< tsk::unbounded_twolock_fifo > pool_type;
 
 inline
 int fibonacci_fn( int n)
@@ -50,8 +50,6 @@
                         tsk::make_task( long_running_fn),
                         pool);
                 std::cout << "poolsize == " << pool.size() << std::endl;
- std::cout << "idle threads == " << pool.idle() << std::endl;
- std::cout << "active threads == " << pool.active() << std::endl;
                 tsk::handle< int > h(
                         tsk::async(
                                 tsk::make_task( fibonacci_fn, 10),

Modified: sandbox/task/libs/task/examples/no_deadlock_pool.cpp
==============================================================================
--- sandbox/task/libs/task/examples/no_deadlock_pool.cpp (original)
+++ sandbox/task/libs/task/examples/no_deadlock_pool.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -18,9 +18,7 @@
 
 namespace tsk = boost::task;
 
-typedef tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
-> pool_type;
+typedef tsk::static_pool< tsk::unbounded_twolock_fifo > pool_type;
 
 class event
 {

Modified: sandbox/task/libs/task/examples/no_deadlock_pool3.cpp
==============================================================================
--- sandbox/task/libs/task/examples/no_deadlock_pool3.cpp (original)
+++ sandbox/task/libs/task/examples/no_deadlock_pool3.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -18,9 +18,7 @@
 
 namespace tsk = boost::task;
 
-typedef tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
-> pool_type;
+typedef tsk::static_pool< tsk::unbounded_twolock_fifo > pool_type;
 
 class event
 {

Deleted: sandbox/task/libs/task/examples/pending.cpp
==============================================================================
--- sandbox/task/libs/task/examples/pending.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
+++ (empty file)
@@ -1,68 +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 <iostream>
-#include <cstdlib>
-#include <stdexcept>
-#include <vector>
-
-#include <boost/bind.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/ref.hpp>
-
-#include "boost/task.hpp"
-
-namespace pt = boost::posix_time;
-namespace tsk = boost::task;
-
-typedef tsk::static_pool< tsk::unbounded_channel< tsk::fifo > > pool_type;
-
-inline
-int fibonacci_fn( int n)
-{
- if ( n == 0) return 0;
- if ( n == 1) return 1;
- int k1( 1), k2( 0);
- for ( int i( 2); i <= n; ++i)
- {
- boost::this_thread::interruption_point();
- int tmp( k1);
- k1 = k1 + k2;
- k2 = tmp;
- }
- boost::this_thread::interruption_point();
- return k1;
-}
-
-inline
-void long_running_fn()
-{ boost::this_thread::sleep( pt::seconds( 1) ); }
-
-int main( int argc, char *argv[])
-{
- try
- {
- pool_type pool( tsk::poolsize( 5) );
-
- tsk::async(
- tsk::make_task( long_running_fn),
- pool);
- tsk::handle< int > h(
- tsk::async(
- tsk::make_task( fibonacci_fn, 10),
- pool) );
- std::cout << "pending tasks == " << pool.pending() << std::endl;
- std::cout << h.get() << std::endl;
-
- return EXIT_SUCCESS;
- }
- catch ( std::exception const& e)
- { std::cerr << "exception: " << e.what() << std::endl; }
- catch ( ... )
- { std::cerr << "unhandled" << std::endl; }
-
- return EXIT_FAILURE;
-}

Modified: sandbox/task/libs/task/examples/priority.cpp
==============================================================================
--- sandbox/task/libs/task/examples/priority.cpp (original)
+++ sandbox/task/libs/task/examples/priority.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -29,9 +29,7 @@
 {
         try
         {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::priority< int > >
- > pool( tsk::poolsize( 1) );
+ tsk::static_pool< tsk::unbounded_onelock_prio_queue< int > > pool( tsk::poolsize( 1) );
 
                 tsk::task< void > t1( long_running_fn);
                 tsk::task< void > t2( print_fn, "a text.\n");

Modified: sandbox/task/libs/task/examples/semaphore_pool.cpp
==============================================================================
--- sandbox/task/libs/task/examples/semaphore_pool.cpp (original)
+++ sandbox/task/libs/task/examples/semaphore_pool.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -21,9 +21,7 @@
 {
         try
         {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 1) );
+ tsk::static_pool< tsk::unbounded_twolock_fifo > pool( tsk::poolsize( 1) );
 
                 int n = 10;
                 tsk::semaphore sem_a( 0), sem_b( 0);

Modified: sandbox/task/libs/task/examples/semaphore_pool_thread.cpp
==============================================================================
--- sandbox/task/libs/task/examples/semaphore_pool_thread.cpp (original)
+++ sandbox/task/libs/task/examples/semaphore_pool_thread.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -21,9 +21,7 @@
 {
         try
         {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 1) );
+ tsk::static_pool< tsk::unbounded_twolock_fifo > pool( tsk::poolsize( 1) );
 
                 int n = 10;
                 tsk::semaphore sem_a( 0), sem_b( 0);

Modified: sandbox/task/libs/task/examples/shutdown_now.cpp
==============================================================================
--- sandbox/task/libs/task/examples/shutdown_now.cpp (original)
+++ sandbox/task/libs/task/examples/shutdown_now.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -40,9 +40,7 @@
 {
         try
         {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 1) );
+ tsk::static_pool< tsk::unbounded_onelock_fifo > pool( tsk::poolsize( 1) );
 
                 tsk::task< int > t( fibonacci_fn, 10);
                                 

Modified: sandbox/task/libs/task/examples/smart.cpp
==============================================================================
--- sandbox/task/libs/task/examples/smart.cpp (original)
+++ sandbox/task/libs/task/examples/smart.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -49,13 +49,9 @@
         try
         {
                 tsk::static_pool<
- tsk::unbounded_channel<
- tsk::smart<
+ tsk::unbounded_onelock_smart_queue<
                                         int,
- std::less< int >,
- tsk::replace_oldest,
- tsk::take_oldest
- >
+ std::less< int >
>
> pool( tsk::poolsize( 1) );
 

Modified: sandbox/task/libs/task/examples/submit.cpp
==============================================================================
--- sandbox/task/libs/task/examples/submit.cpp (original)
+++ sandbox/task/libs/task/examples/submit.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -35,10 +35,8 @@
 {
         try
         {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::priority< int > >
- > pool( tsk::poolsize( 3) );
-
+ tsk::static_pool< tsk::unbounded_onelock_prio_queue< int > > pool( tsk::poolsize( 3) );
+
                 tsk::task< int > t1( fibonacci_fn, 10);
                 tsk::task< int > t2( fibonacci_fn, 10);
                 tsk::task< int > t3( fibonacci_fn, 10);

Modified: sandbox/task/libs/task/src/callable.cpp
==============================================================================
--- sandbox/task/libs/task/src/callable.cpp (original)
+++ sandbox/task/libs/task/src/callable.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -26,10 +26,6 @@
 { impl_.reset(); }
 
 void
-callable::reset()
-{ impl_->reset(); }
-
-void
 callable::reset( shared_ptr< thread > const& thrd)
 { impl_->reset( thrd); }
 

Added: sandbox/task/libs/task/src/context.cpp
==============================================================================
--- (empty file)
+++ sandbox/task/libs/task/src/context.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -0,0 +1,81 @@
+
+// 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/task/context.hpp"
+
+#include <boost/assert.hpp>
+
+namespace boost { namespace task
+{
+
+void
+context::impl::reset_( shared_ptr< thread > const& thrd)
+{
+ thrd_ = thrd;
+ BOOST_ASSERT( thrd_);
+ if ( requested_)
+ if ( thrd_) thrd_->interrupt();
+}
+
+void
+context::impl::interrupt_()
+{
+ if ( ! requested_)
+ {
+ requested_ = true;
+ if ( thrd_) thrd_->interrupt();
+ }
+}
+
+context::impl::impl()
+:
+requested_( false),
+mtx_(),
+thrd_()
+{}
+
+void
+context::impl::reset( shared_ptr< thread > const& thrd)
+{
+ lock_guard< mutex > lk( mtx_);
+ reset_( thrd);
+}
+
+void
+context::impl::interrupt()
+{
+ lock_guard< mutex > lk( mtx_);
+ interrupt_();
+}
+
+bool
+context::impl::interruption_requested()
+{
+ lock_guard< mutex > lk( mtx_);
+ return requested_;
+}
+
+context::context()
+: impl_( new impl() )
+{}
+
+void
+context::reset( shared_ptr< thread > const& thrd)
+{ impl_->reset( thrd); }
+
+void
+context::interrupt()
+{ impl_->interrupt(); }
+
+bool
+context::interruption_requested()
+{ return impl_->interruption_requested(); }
+
+void
+context::swap( context & other)
+{ impl_.swap( other.impl_); }
+
+}}

Deleted: sandbox/task/libs/task/src/interrupter.cpp
==============================================================================
--- sandbox/task/libs/task/src/interrupter.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
+++ (empty file)
@@ -1,104 +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/task/detail/interrupter.hpp"
-
-#include <boost/assert.hpp>
-
-namespace boost { namespace task {
-namespace detail
-{
-
-void
-interrupter::impl::reset_( shared_ptr< thread > const& thrd)
-{
- thrd_ = thrd;
- BOOST_ASSERT( thrd_);
- if ( requested_)
- if ( thrd_) thrd_->interrupt();
-}
-
-void
-interrupter::impl::reset_()
-{
- thrd_.reset();
- try
- { this_thread::interruption_point(); }
- catch ( thread_interrupted const&)
- {}
- BOOST_ASSERT( ! this_thread::interruption_requested() );
-}
-
-void
-interrupter::impl::interrupt_()
-{
- if ( ! requested_)
- {
- requested_ = true;
- if ( thrd_) thrd_->interrupt();
- }
-}
-
-interrupter::impl::impl()
-:
-requested_( false),
-mtx_(),
-thrd_()
-{}
-
-void
-interrupter::impl::reset( shared_ptr< thread > const& thrd)
-{
- lock_guard< mutex > lk( mtx_);
- reset_( thrd);
-}
-
-void
-interrupter::impl::reset()
-{
- lock_guard< mutex > lk( mtx_);
- reset_();
-}
-
-void
-interrupter::impl::interrupt()
-{
- lock_guard< mutex > lk( mtx_);
- interrupt_();
-}
-
-bool
-interrupter::impl::interruption_requested()
-{
- lock_guard< mutex > lk( mtx_);
- return requested_;
-}
-
-interrupter::interrupter()
-: impl_( new impl() )
-{}
-
-void
-interrupter::reset( shared_ptr< thread > const& thrd)
-{ impl_->reset( thrd); }
-
-void
-interrupter::reset()
-{ impl_->reset(); }
-
-void
-interrupter::interrupt()
-{ impl_->interrupt(); }
-
-bool
-interrupter::interruption_requested()
-{ return impl_->interruption_requested(); }
-
-void
-interrupter::swap( interrupter & other)
-{ impl_.swap( other.impl_); }
-
-}}}

Modified: sandbox/task/libs/task/test/Jamfile.v2
==============================================================================
--- sandbox/task/libs/task/test/Jamfile.v2 (original)
+++ sandbox/task/libs/task/test/Jamfile.v2 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -29,7 +29,9 @@
     [ task-test test_task ]
     [ task-test test_own_thread ]
     [ task-test test_new_thread ]
- [ task-test test_unbounded_pool ]
- [ task-test test_bounded_pool ]
+ [ task-test test_unbounded_twolock_pool ]
+ [ task-test test_unbounded_onelock_pool ]
+ [ task-test test_bounded_twolock_pool ]
+ [ task-test test_bounded_onelock_pool ]
     [ task-test test_as_sub_task ]
     ;

Modified: sandbox/task/libs/task/test/test_as_sub_task.cpp
==============================================================================
--- sandbox/task/libs/task/test/test_as_sub_task.cpp (original)
+++ sandbox/task/libs/task/test/test_as_sub_task.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -16,7 +16,6 @@
 #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>
@@ -54,7 +53,7 @@
         void test_case_2()
         {
                 tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
+ tsk::unbounded_onelock_fifo
> pool( tsk::poolsize( 1) );
                 tsk::handle< bool > h(
                         tsk::async(

Added: sandbox/task/libs/task/test/test_bounded_onelock_pool.cpp
==============================================================================
--- (empty file)
+++ sandbox/task/libs/task/test/test_bounded_onelock_pool.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -0,0 +1,592 @@
+
+// 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/type_traits/is_same.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/task.hpp>
+
+#include "test_functions.hpp"
+
+namespace pt = boost::posix_time;
+namespace tsk = boost::task;
+
+class test_bounded_onelock_pool
+{
+public:
+ // check size and move op
+ void test_case_1()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool1(
+ tsk::poolsize( 3),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 5) );
+ BOOST_CHECK( pool1);
+ BOOST_CHECK_EQUAL( pool1.size(), std::size_t( 3) );
+ BOOST_CHECK_EQUAL( pool1.upper_bound(), std::size_t( 10) );
+ BOOST_CHECK_EQUAL( pool1.lower_bound(), std::size_t( 5) );
+
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool2;
+ BOOST_CHECK( ! pool2);
+ BOOST_CHECK_THROW( pool2.size(), tsk::pool_moved);
+ BOOST_CHECK_THROW( pool2.upper_bound(), tsk::pool_moved);
+ BOOST_CHECK_THROW( pool2.lower_bound(), tsk::pool_moved);
+
+ pool2 = boost::move( pool1);
+
+ BOOST_CHECK( ! pool1);
+ BOOST_CHECK_THROW( pool1.size(), tsk::pool_moved);
+ BOOST_CHECK_THROW( pool1.upper_bound(), tsk::pool_moved);
+ BOOST_CHECK_THROW( pool1.lower_bound(), tsk::pool_moved);
+
+ BOOST_CHECK( pool2);
+ BOOST_CHECK_EQUAL( pool2.size(), std::size_t( 3) );
+ BOOST_CHECK_EQUAL( pool2.upper_bound(), std::size_t( 10) );
+ BOOST_CHECK_EQUAL( pool2.lower_bound(), std::size_t( 5) );
+
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h(
+ tsk::async( boost::move( t), pool2) );
+ BOOST_CHECK_EQUAL( h.get(), 55);
+ }
+
+ // check submit
+ void test_case_2()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 1),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK_EQUAL( h.get(), 55);
+ }
+
+ // check assignment
+ void test_case_3()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h1;
+ tsk::handle< int > h2(
+ tsk::async( boost::move( t), pool) );
+ h1 = h2;
+ BOOST_CHECK_EQUAL( h1.get(), 55);
+ BOOST_CHECK_EQUAL( h2.get(), 55);
+ }
+
+ // check swap
+ void test_case_4()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< int > t1( fibonacci_fn, 5);
+ tsk::task< int > t2( fibonacci_fn, 10);
+ tsk::handle< int > h1(
+ tsk::async( boost::move( t1), pool) );
+ tsk::handle< int > h2(
+ tsk::async( boost::move( t2), pool) );
+ BOOST_CHECK_EQUAL( h1.get(), 5);
+ BOOST_CHECK_EQUAL( h2.get(), 55);
+ BOOST_CHECK_NO_THROW( h1.swap( h2) );
+ BOOST_CHECK_EQUAL( h1.get(), 55);
+ BOOST_CHECK_EQUAL( h2.get(), 5);
+ }
+
+ // check runs in pool
+ void test_case_5()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 1),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< bool > t( runs_in_pool_fn);
+ tsk::handle< bool > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK_EQUAL( h.get(), true);
+ }
+
+ // check shutdown
+ void test_case_6()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 1),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h(
+ tsk::async( boost::move( t), pool) );
+ pool.shutdown();
+ BOOST_CHECK( pool.closed() );
+ BOOST_CHECK_EQUAL( h.get(), 55);
+ }
+
+ // check runtime_error throw inside task
+ void test_case_7()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 1),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< void > t( throwing_fn);
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ pool.shutdown();
+ BOOST_CHECK_THROW( h.get(), std::runtime_error);
+ }
+
+ // check shutdown with task_rejected exception
+ void test_case_8()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 1),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ pool.shutdown();
+ BOOST_CHECK( pool.closed() );
+ BOOST_CHECK_THROW(
+ tsk::async( boost::move( t), pool),
+ tsk::task_rejected);
+ }
+
+ // check shutdown_now with thread_interrupted exception
+ void test_case_9()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 1),
+ tsk::high_watermark( 1),
+ tsk::low_watermark( 1) );
+ tsk::task< void > t( delay_fn, pt::millisec( 500) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ 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( 0) );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check wait
+ void test_case_10()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 1),
+ tsk::low_watermark( 1) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h(
+ tsk::async( boost::move( t), pool) );
+ h.wait();
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ BOOST_CHECK_EQUAL( h.get(), 55);
+ }
+
+ // check wait_for
+ void test_case_11()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 1),
+ tsk::low_watermark( 1) );
+ tsk::task< void > t( delay_fn, pt::seconds( 1) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( h.wait_for( pt::seconds( 3) ) );
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ }
+
+ // check wait_for
+ void test_case_12()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 1),
+ tsk::low_watermark( 1) );
+ tsk::task< void > t( delay_fn, pt::seconds( 3) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( ! h.wait_for( pt::seconds( 1) ) );
+ BOOST_CHECK( ! h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ }
+
+ // check wait_for
+ void test_case_13()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 1),
+ tsk::low_watermark( 1) );
+ tsk::task< void > t( delay_fn, pt::seconds( 1) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( h.wait_until( boost::get_system_time() + pt::seconds( 3) ) );
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ }
+
+ // check wait_for
+ void test_case_14()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 1),
+ tsk::low_watermark( 1) );
+ tsk::task< void > t( delay_fn, pt::seconds( 3) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( ! h.wait_until( boost::get_system_time() + pt::seconds( 1) ) );
+ BOOST_CHECK( ! h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ }
+
+ // check interrupt
+ void test_case_15()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< void > t( delay_fn, pt::seconds( 3) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ h.interrupt();
+ BOOST_CHECK( h.interruption_requested() );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check interrupt_all_worker
+ void test_case_16()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< void > t1( delay_fn, pt::seconds( 3) );
+ tsk::task< void > t2( delay_fn, pt::seconds( 3) );
+ tsk::task< void > t3( delay_fn, pt::seconds( 3) );
+ tsk::handle< void > h1(
+ tsk::async( boost::move( t1), pool) );
+ tsk::handle< void > h2(
+ tsk::async( boost::move( t2), pool) );
+ tsk::handle< void > h3(
+ tsk::async( boost::move( t3), pool) );
+ boost::this_thread::sleep( pt::millisec( 250) );
+ pool.interrupt_all_worker();
+ BOOST_CHECK( ! h1.interruption_requested() );
+ BOOST_CHECK( ! h2.interruption_requested() );
+ BOOST_CHECK( ! h3.interruption_requested() );
+ BOOST_CHECK_THROW( h1.get(), tsk::task_interrupted);
+ BOOST_CHECK_THROW( h2.get(), tsk::task_interrupted);
+ BOOST_CHECK_THROW( h3.get(), tsk::task_interrupted);
+ BOOST_CHECK_EQUAL( pool.size(), std::size_t( 5) );
+ }
+
+ // check interrupt_and_wait
+ void test_case_17()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ bool finished( false);
+ tsk::task< void > t( interrupt_fn, pt::seconds( 1), boost::ref( finished) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ h.interrupt_and_wait();
+ BOOST_CHECK( finished);
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( h.has_exception() );
+ BOOST_CHECK( h.interruption_requested() );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check interrupt_and_wait_for
+ void test_case_18()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ bool finished( false);
+ tsk::task< void > t( interrupt_fn, pt::seconds( 1), boost::ref( finished) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( h.interrupt_and_wait_for( pt::seconds( 3) ) );
+ BOOST_CHECK( finished);
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( h.has_exception() );
+ BOOST_CHECK( h.interruption_requested() );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check interrupt_and_wait_for
+ void test_case_19()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< void > t( non_interrupt_fn, 3);
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( ! h.interrupt_and_wait_for( pt::seconds( 1) ) );
+ }
+
+ // check interrupt_and_wait_until
+ void test_case_20()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ bool finished( false);
+ tsk::task< void > t(
+ interrupt_fn,
+ pt::seconds( 1),
+ boost::ref( finished) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 3) ) );
+ BOOST_CHECK( finished);
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( h.has_exception() );
+ BOOST_CHECK( h.interruption_requested() );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check interrupt_and_wait_until
+ void test_case_21()
+ {
+ tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< void > t( non_interrupt_fn, 3);
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( ! h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 1) ) );
+ }
+
+ // check fifo scheduling
+ void test_case_22()
+ {
+ typedef tsk::static_pool<
+ tsk::bounded_onelock_fifo
+ > pool_type;
+ BOOST_CHECK( ! tsk::has_attribute< pool_type >::value);
+ pool_type pool(
+ tsk::poolsize( 1),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ boost::barrier b( 2);
+ std::vector< int > buffer;
+ tsk::task< void > t1( barrier_fn, boost::ref( b) );
+ tsk::task< void > t2(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 10);
+ tsk::task< void > t3(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 0);
+ tsk::async( boost::move( t1), pool);
+ boost::this_thread::sleep( pt::millisec( 250) );
+ tsk::async( boost::move( t2), pool);
+ tsk::async( boost::move( t3), pool);
+ 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_23()
+ {
+ typedef tsk::static_pool<
+ tsk::bounded_onelock_prio_queue< int >
+ > pool_type;
+ BOOST_CHECK( tsk::has_attribute< pool_type >::value);
+ typedef boost::is_same< tsk::attribute_type< pool_type >::type, int > type;
+ BOOST_CHECK( type::value);
+ pool_type pool(
+ tsk::poolsize( 1),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ boost::barrier b( 2);
+ std::vector< int > buffer;
+ tsk::task< void > t1( barrier_fn, boost::ref( b) );
+ tsk::task< void > t2(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 10);
+ tsk::task< void > t3(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 0);
+ tsk::async( boost::move( t1), 0, pool);
+ boost::this_thread::sleep( pt::millisec( 250) );
+ tsk::async( boost::move( t2), 1, pool);
+ tsk::async( boost::move( t3), 0, pool);
+ 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 smart scheduling
+ void test_case_24()
+ {
+ typedef tsk::static_pool<
+ tsk::bounded_onelock_smart_queue< int, std::less< int > >
+ > pool_type;
+ BOOST_CHECK( tsk::has_attribute< pool_type >::value);
+ typedef boost::is_same< tsk::attribute_type< pool_type >::type, int > type;
+ BOOST_CHECK( type::value);
+ pool_type pool(
+ tsk::poolsize( 1),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ boost::barrier b( 2);
+ std::vector< int > buffer;
+ tsk::task< void > t1(
+ barrier_fn,
+ boost::ref( b) );
+ tsk::task< void > t2(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 10);
+ tsk::task< void > t3(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 0);
+ tsk::task< void > t4(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 1);
+ pool.submit( boost::move( t1), 0);
+ boost::this_thread::sleep( pt::millisec( 250) );
+ tsk::async( boost::move( t2), 2, pool);
+ tsk::async( boost::move( t3), 1, pool);
+ tsk::async( boost::move( t4), 2, pool);
+ 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_bounded_onelock_pool > instance( new test_bounded_onelock_pool() );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_1, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_2, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_3, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_4, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_5, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_6, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_7, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_8, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_9, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_10, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_11, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_12, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_13, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_14, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_15, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_16, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_17, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_18, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_19, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_20, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_21, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_22, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_23, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_onelock_pool::test_case_24, instance) );
+
+ return test;
+}
+

Deleted: sandbox/task/libs/task/test/test_bounded_pool.cpp
==============================================================================
--- sandbox/task/libs/task/test/test_bounded_pool.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
+++ (empty file)
@@ -1,639 +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 <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/type_traits/is_same.hpp>
-#include <boost/utility.hpp>
-
-#include <boost/task.hpp>
-
-#include "test_functions.hpp"
-
-namespace pt = boost::posix_time;
-namespace tsk = boost::task;
-
-class test_bounded_pool
-{
-public:
- // check size, active, idle
- void test_case_1()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool1(
- tsk::poolsize( 3),
- tsk::high_watermark( 10),
- tsk::low_watermark( 5) );
- BOOST_CHECK( pool1);
- BOOST_CHECK_EQUAL( pool1.size(), std::size_t( 3) );
- BOOST_CHECK_EQUAL( pool1.idle(), std::size_t( 3) );
- BOOST_CHECK_EQUAL( pool1.active(), std::size_t( 0) );
- BOOST_CHECK_EQUAL( pool1.upper_bound(), std::size_t( 10) );
- BOOST_CHECK_EQUAL( pool1.lower_bound(), std::size_t( 5) );
-
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool2;
- BOOST_CHECK( ! pool2);
- BOOST_CHECK_THROW( pool2.size(), tsk::pool_moved);
- BOOST_CHECK_THROW( pool2.idle(), tsk::pool_moved);
- BOOST_CHECK_THROW( pool2.active(), tsk::pool_moved);
- BOOST_CHECK_THROW( pool2.upper_bound(), tsk::pool_moved);
- BOOST_CHECK_THROW( pool2.lower_bound(), tsk::pool_moved);
-
- pool2 = boost::move( pool1);
-
- BOOST_CHECK( ! pool1);
- BOOST_CHECK_THROW( pool1.size(), tsk::pool_moved);
- BOOST_CHECK_THROW( pool1.idle(), tsk::pool_moved);
- BOOST_CHECK_THROW( pool1.active(), tsk::pool_moved);
- BOOST_CHECK_THROW( pool1.upper_bound(), tsk::pool_moved);
- BOOST_CHECK_THROW( pool1.lower_bound(), tsk::pool_moved);
-
- BOOST_CHECK( pool2);
- BOOST_CHECK_EQUAL( pool2.size(), std::size_t( 3) );
- BOOST_CHECK_EQUAL( pool2.idle(), std::size_t( 3) );
- BOOST_CHECK_EQUAL( pool2.active(), std::size_t( 0) );
- BOOST_CHECK_EQUAL( pool2.upper_bound(), std::size_t( 10) );
- BOOST_CHECK_EQUAL( pool2.lower_bound(), std::size_t( 5) );
-
- tsk::task< int > t( fibonacci_fn, 10);
- tsk::handle< int > h(
- tsk::async( boost::move( t), pool2) );
- BOOST_CHECK_EQUAL( h.get(), 55);
- }
-
- // check submit
- void test_case_2()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 1),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- tsk::task< int > t( fibonacci_fn, 10);
- tsk::handle< int > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK_EQUAL( h.get(), 55);
- }
-
- // check assignment
- void test_case_3()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 5),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- tsk::task< int > t( fibonacci_fn, 10);
- tsk::handle< int > h1;
- tsk::handle< int > h2(
- tsk::async( boost::move( t), pool) );
- h1 = h2;
- BOOST_CHECK_EQUAL( h1.get(), 55);
- BOOST_CHECK_EQUAL( h2.get(), 55);
- }
-
- // check swap
- void test_case_4()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 5),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- tsk::task< int > t1( fibonacci_fn, 5);
- tsk::task< int > t2( fibonacci_fn, 10);
- tsk::handle< int > h1(
- tsk::async( boost::move( t1), pool) );
- tsk::handle< int > h2(
- tsk::async( boost::move( t2), pool) );
- BOOST_CHECK_EQUAL( h1.get(), 5);
- BOOST_CHECK_EQUAL( h2.get(), 55);
- BOOST_CHECK_NO_THROW( h1.swap( h2) );
- BOOST_CHECK_EQUAL( h1.get(), 55);
- BOOST_CHECK_EQUAL( h2.get(), 5);
- }
-
- // check runs in pool
- void test_case_5()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 1),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- tsk::task< bool > t( runs_in_pool_fn);
- tsk::handle< bool > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK_EQUAL( h.get(), true);
- }
-
- // check shutdown
- void test_case_6()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 1),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- tsk::task< int > t( fibonacci_fn, 10);
- tsk::handle< int > h(
- tsk::async( boost::move( t), pool) );
- pool.shutdown();
- BOOST_CHECK( pool.closed() );
- BOOST_CHECK_EQUAL( h.get(), 55);
- }
-
- // check runtime_error throw inside task
- void test_case_7()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 1),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- tsk::task< void > t( throwing_fn);
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- pool.shutdown();
- BOOST_CHECK_THROW( h.get(), std::runtime_error);
- }
-
- // check shutdown with task_rejected exception
- void test_case_8()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 1),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- tsk::task< int > t( fibonacci_fn, 10);
- pool.shutdown();
- BOOST_CHECK( pool.closed() );
- BOOST_CHECK_THROW(
- tsk::async( boost::move( t), pool),
- tsk::task_rejected);
- }
-
- // check shutdown_now with thread_interrupted exception
- void test_case_9()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 1),
- tsk::high_watermark( 1),
- tsk::low_watermark( 1) );
- tsk::task< void > t( delay_fn, pt::millisec( 500) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- 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( 0) );
- BOOST_CHECK_EQUAL( pool.idle(), std::size_t( 0) );
- BOOST_CHECK_EQUAL( pool.active(), std::size_t( 0) );
- BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
- }
-
- // check pending
- void test_case_10()
- {
- typedef tsk::static_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::task< void > t1(
- barrier_fn,
- boost::ref( b) );
- tsk::task< int > t2(
- fibonacci_fn,
- 10);
- tsk::task< int > t3(
- fibonacci_fn,
- 10);
- tsk::handle< void > h1(
- tsk::async( boost::move( t1), pool) );
- boost::this_thread::sleep( pt::millisec( 250) );
- BOOST_CHECK_EQUAL( pool.pending(), std::size_t( 0) );
- tsk::handle< int > h2(
- tsk::async( boost::move( t2), pool) );
- boost::this_thread::sleep( pt::millisec(250) );
- BOOST_CHECK_EQUAL( pool.pending(), std::size_t( 1) );
- tsk::handle< int > h3(
- tsk::async( boost::move( t3), pool) );
- 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 wait
- void test_case_11()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 5),
- tsk::high_watermark( 1),
- tsk::low_watermark( 1) );
- tsk::task< int > t( fibonacci_fn, 10);
- tsk::handle< int > h(
- tsk::async( boost::move( t), pool) );
- h.wait();
- BOOST_CHECK( h.is_ready() );
- BOOST_CHECK( h.has_value() );
- BOOST_CHECK( ! h.has_exception() );
- BOOST_CHECK_EQUAL( h.get(), 55);
- }
-
- // check wait_for
- void test_case_12()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 5),
- tsk::high_watermark( 1),
- tsk::low_watermark( 1) );
- tsk::task< void > t( delay_fn, pt::seconds( 1) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK( h.wait_for( pt::seconds( 3) ) );
- BOOST_CHECK( h.is_ready() );
- BOOST_CHECK( h.has_value() );
- BOOST_CHECK( ! h.has_exception() );
- }
-
- // check wait_for
- void test_case_13()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 5),
- tsk::high_watermark( 1),
- tsk::low_watermark( 1) );
- tsk::task< void > t( delay_fn, pt::seconds( 3) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK( ! h.wait_for( pt::seconds( 1) ) );
- BOOST_CHECK( ! h.is_ready() );
- BOOST_CHECK( ! h.has_value() );
- BOOST_CHECK( ! h.has_exception() );
- }
-
- // check wait_for
- void test_case_14()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 5),
- tsk::high_watermark( 1),
- tsk::low_watermark( 1) );
- tsk::task< void > t( delay_fn, pt::seconds( 1) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK( h.wait_until( boost::get_system_time() + pt::seconds( 3) ) );
- BOOST_CHECK( h.is_ready() );
- BOOST_CHECK( h.has_value() );
- BOOST_CHECK( ! h.has_exception() );
- }
-
- // check wait_for
- void test_case_15()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 5),
- tsk::high_watermark( 1),
- tsk::low_watermark( 1) );
- tsk::task< void > t( delay_fn, pt::seconds( 3) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK( ! h.wait_until( boost::get_system_time() + pt::seconds( 1) ) );
- BOOST_CHECK( ! h.is_ready() );
- BOOST_CHECK( ! h.has_value() );
- BOOST_CHECK( ! h.has_exception() );
- }
-
- // check interrupt
- void test_case_16()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 5),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- tsk::task< void > t( delay_fn, pt::seconds( 3) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- h.interrupt();
- BOOST_CHECK( h.interruption_requested() );
- BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
- }
-
- // check interrupt_all_worker
- void test_case_17()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 5),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- tsk::task< void > t1( delay_fn, pt::seconds( 3) );
- tsk::task< void > t2( delay_fn, pt::seconds( 3) );
- tsk::task< void > t3( delay_fn, pt::seconds( 3) );
- tsk::handle< void > h1(
- tsk::async( boost::move( t1), pool) );
- tsk::handle< void > h2(
- tsk::async( boost::move( t2), pool) );
- tsk::handle< void > h3(
- tsk::async( boost::move( t3), pool) );
- boost::this_thread::sleep( pt::millisec( 250) );
- pool.interrupt_all_worker();
- BOOST_CHECK( ! h1.interruption_requested() );
- BOOST_CHECK( ! h2.interruption_requested() );
- BOOST_CHECK( ! h3.interruption_requested() );
- BOOST_CHECK_THROW( h1.get(), tsk::task_interrupted);
- BOOST_CHECK_THROW( h2.get(), tsk::task_interrupted);
- BOOST_CHECK_THROW( h3.get(), tsk::task_interrupted);
- BOOST_CHECK_EQUAL( pool.size(), std::size_t( 5) );
- }
-
- // check interrupt_and_wait
- void test_case_18()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 5),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- bool finished( false);
- tsk::task< void > t( interrupt_fn, pt::seconds( 1), boost::ref( finished) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- h.interrupt_and_wait();
- BOOST_CHECK( finished);
- BOOST_CHECK( h.is_ready() );
- BOOST_CHECK( ! h.has_value() );
- BOOST_CHECK( h.has_exception() );
- BOOST_CHECK( h.interruption_requested() );
- BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
- }
-
- // check interrupt_and_wait_for
- void test_case_19()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 5),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- bool finished( false);
- tsk::task< void > t( interrupt_fn, pt::seconds( 1), boost::ref( finished) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK( h.interrupt_and_wait_for( pt::seconds( 3) ) );
- BOOST_CHECK( finished);
- BOOST_CHECK( h.is_ready() );
- BOOST_CHECK( ! h.has_value() );
- BOOST_CHECK( h.has_exception() );
- BOOST_CHECK( h.interruption_requested() );
- BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
- }
-
- // check interrupt_and_wait_for
- void test_case_20()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 5),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- tsk::task< void > t( non_interrupt_fn, 3);
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK( ! h.interrupt_and_wait_for( pt::seconds( 1) ) );
- }
-
- // check interrupt_and_wait_until
- void test_case_21()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 5),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- bool finished( false);
- tsk::task< void > t(
- interrupt_fn,
- pt::seconds( 1),
- boost::ref( finished) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK( h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 3) ) );
- BOOST_CHECK( finished);
- BOOST_CHECK( h.is_ready() );
- BOOST_CHECK( ! h.has_value() );
- BOOST_CHECK( h.has_exception() );
- BOOST_CHECK( h.interruption_requested() );
- BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
- }
-
- // check interrupt_and_wait_until
- void test_case_22()
- {
- tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool(
- tsk::poolsize( 5),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- tsk::task< void > t( non_interrupt_fn, 3);
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK( ! h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 1) ) );
- }
-
- // check fifo scheduling
- void test_case_23()
- {
- typedef tsk::static_pool<
- tsk::bounded_channel< tsk::fifo >
- > pool_type;
- BOOST_CHECK( ! tsk::has_attribute< pool_type >::value);
- pool_type pool(
- tsk::poolsize( 1),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- boost::barrier b( 2);
- std::vector< int > buffer;
- tsk::task< void > t1( barrier_fn, boost::ref( b) );
- tsk::task< void > t2(
- buffer_fibonacci_fn,
- boost::ref( buffer),
- 10);
- tsk::task< void > t3(
- buffer_fibonacci_fn,
- boost::ref( buffer),
- 0);
- tsk::async( boost::move( t1), pool);
- tsk::async( boost::move( t2), pool);
- tsk::async( boost::move( t3), pool);
- 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_24()
- {
- typedef tsk::static_pool<
- tsk::bounded_channel< tsk::priority< int > >
- > pool_type;
- BOOST_CHECK( tsk::has_attribute< pool_type >::value);
- typedef boost::is_same< tsk::attribute_type< pool_type >::type, int > type;
- BOOST_CHECK( type::value);
- pool_type pool(
- tsk::poolsize( 1),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- boost::barrier b( 2);
- std::vector< int > buffer;
- tsk::task< void > t1( barrier_fn, boost::ref( b) );
- tsk::task< void > t2(
- buffer_fibonacci_fn,
- boost::ref( buffer),
- 10);
- tsk::task< void > t3(
- buffer_fibonacci_fn,
- boost::ref( buffer),
- 0);
- tsk::async( boost::move( t1), 0, pool);
- tsk::async( boost::move( t2), 1, pool);
- tsk::async( boost::move( t3), 0, pool);
- 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 smart scheduling
- void test_case_25()
- {
- typedef tsk::static_pool<
- tsk::bounded_channel< tsk::smart< int, std::less< int >, tsk::replace_oldest, tsk::take_oldest > >
- > pool_type;
- BOOST_CHECK( tsk::has_attribute< pool_type >::value);
- typedef boost::is_same< tsk::attribute_type< pool_type >::type, int > type;
- BOOST_CHECK( type::value);
- pool_type pool(
- tsk::poolsize( 1),
- tsk::high_watermark( 10),
- tsk::low_watermark( 10) );
- boost::barrier b( 2);
- std::vector< int > buffer;
- tsk::task< void > t1(
- barrier_fn,
- boost::ref( b) );
- tsk::task< void > t2(
- buffer_fibonacci_fn,
- boost::ref( buffer),
- 10);
- tsk::task< void > t3(
- buffer_fibonacci_fn,
- boost::ref( buffer),
- 0);
- tsk::task< void > t4(
- buffer_fibonacci_fn,
- boost::ref( buffer),
- 1);
- tsk::async( boost::move( t1), 0, pool);
- tsk::async( boost::move( t2), 2, pool);
- tsk::async( boost::move( t3), 1, pool);
- tsk::async( boost::move( t4), 2, pool);
- 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_bounded_pool > instance( new test_bounded_pool() );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_1, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_2, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_3, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_4, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_5, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_6, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_7, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_8, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_9, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_10, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_11, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_12, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_13, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_14, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_15, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_16, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_17, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_18, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_19, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_20, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_21, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_22, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_23, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_24, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_bounded_pool::test_case_25, instance) );
-
- return test;
-}
-

Added: sandbox/task/libs/task/test/test_bounded_twolock_pool.cpp
==============================================================================
--- (empty file)
+++ sandbox/task/libs/task/test/test_bounded_twolock_pool.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -0,0 +1,513 @@
+
+// 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/type_traits/is_same.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/task.hpp>
+
+#include "test_functions.hpp"
+
+namespace pt = boost::posix_time;
+namespace tsk = boost::task;
+
+class test_bounded_twolock_pool
+{
+public:
+ // check size and move op
+ void test_case_1()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool1(
+ tsk::poolsize( 3),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 5) );
+ BOOST_CHECK( pool1);
+ BOOST_CHECK_EQUAL( pool1.size(), std::size_t( 3) );
+ BOOST_CHECK_EQUAL( pool1.upper_bound(), std::size_t( 10) );
+ BOOST_CHECK_EQUAL( pool1.lower_bound(), std::size_t( 5) );
+
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool2;
+ BOOST_CHECK( ! pool2);
+ BOOST_CHECK_THROW( pool2.size(), tsk::pool_moved);
+ BOOST_CHECK_THROW( pool2.upper_bound(), tsk::pool_moved);
+ BOOST_CHECK_THROW( pool2.lower_bound(), tsk::pool_moved);
+
+ pool2 = boost::move( pool1);
+
+ BOOST_CHECK( ! pool1);
+ BOOST_CHECK_THROW( pool1.size(), tsk::pool_moved);
+ BOOST_CHECK_THROW( pool1.upper_bound(), tsk::pool_moved);
+ BOOST_CHECK_THROW( pool1.lower_bound(), tsk::pool_moved);
+
+ BOOST_CHECK( pool2);
+ BOOST_CHECK_EQUAL( pool2.size(), std::size_t( 3) );
+ BOOST_CHECK_EQUAL( pool2.upper_bound(), std::size_t( 10) );
+ BOOST_CHECK_EQUAL( pool2.lower_bound(), std::size_t( 5) );
+
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h(
+ tsk::async( boost::move( t), pool2) );
+ BOOST_CHECK_EQUAL( h.get(), 55);
+ }
+
+ // check submit
+ void test_case_2()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 1),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK_EQUAL( h.get(), 55);
+ }
+
+ // check assignment
+ void test_case_3()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h1;
+ tsk::handle< int > h2(
+ tsk::async( boost::move( t), pool) );
+ h1 = h2;
+ BOOST_CHECK_EQUAL( h1.get(), 55);
+ BOOST_CHECK_EQUAL( h2.get(), 55);
+ }
+
+ // check swap
+ void test_case_4()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< int > t1( fibonacci_fn, 5);
+ tsk::task< int > t2( fibonacci_fn, 10);
+ tsk::handle< int > h1(
+ tsk::async( boost::move( t1), pool) );
+ tsk::handle< int > h2(
+ tsk::async( boost::move( t2), pool) );
+ BOOST_CHECK_EQUAL( h1.get(), 5);
+ BOOST_CHECK_EQUAL( h2.get(), 55);
+ BOOST_CHECK_NO_THROW( h1.swap( h2) );
+ BOOST_CHECK_EQUAL( h1.get(), 55);
+ BOOST_CHECK_EQUAL( h2.get(), 5);
+ }
+
+ // check runs in pool
+ void test_case_5()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 1),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< bool > t( runs_in_pool_fn);
+ tsk::handle< bool > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK_EQUAL( h.get(), true);
+ }
+
+ // check shutdown
+ void test_case_6()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 1),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h(
+ tsk::async( boost::move( t), pool) );
+ pool.shutdown();
+ BOOST_CHECK( pool.closed() );
+ BOOST_CHECK_EQUAL( h.get(), 55);
+ }
+
+ // check runtime_error throw inside task
+ void test_case_7()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 1),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< void > t( throwing_fn);
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ pool.shutdown();
+ BOOST_CHECK_THROW( h.get(), std::runtime_error);
+ }
+
+ // check shutdown with task_rejected exception
+ void test_case_8()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 1),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ pool.shutdown();
+ BOOST_CHECK( pool.closed() );
+ BOOST_CHECK_THROW(
+ tsk::async( boost::move( t), pool),
+ tsk::task_rejected);
+ }
+
+ // check shutdown_now with thread_interrupted exception
+ void test_case_9()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 1),
+ tsk::high_watermark( 1),
+ tsk::low_watermark( 1) );
+ tsk::task< void > t( delay_fn, pt::millisec( 500) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ 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( 0) );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check wait
+ void test_case_10()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 1),
+ tsk::low_watermark( 1) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h(
+ tsk::async( boost::move( t), pool) );
+ h.wait();
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ BOOST_CHECK_EQUAL( h.get(), 55);
+ }
+
+ // check wait_for
+ void test_case_11()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 1),
+ tsk::low_watermark( 1) );
+ tsk::task< void > t( delay_fn, pt::seconds( 1) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( h.wait_for( pt::seconds( 3) ) );
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ }
+
+ // check wait_for
+ void test_case_12()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 1),
+ tsk::low_watermark( 1) );
+ tsk::task< void > t( delay_fn, pt::seconds( 3) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( ! h.wait_for( pt::seconds( 1) ) );
+ BOOST_CHECK( ! h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ }
+
+ // check wait_for
+ void test_case_13()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 1),
+ tsk::low_watermark( 1) );
+ tsk::task< void > t( delay_fn, pt::seconds( 1) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( h.wait_until( boost::get_system_time() + pt::seconds( 3) ) );
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ }
+
+ // check wait_for
+ void test_case_14()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 1),
+ tsk::low_watermark( 1) );
+ tsk::task< void > t( delay_fn, pt::seconds( 3) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( ! h.wait_until( boost::get_system_time() + pt::seconds( 1) ) );
+ BOOST_CHECK( ! h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ }
+
+ // check interrupt
+ void test_case_15()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< void > t( delay_fn, pt::seconds( 3) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ h.interrupt();
+ BOOST_CHECK( h.interruption_requested() );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check interrupt_all_worker
+ void test_case_16()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< void > t1( delay_fn, pt::seconds( 3) );
+ tsk::task< void > t2( delay_fn, pt::seconds( 3) );
+ tsk::task< void > t3( delay_fn, pt::seconds( 3) );
+ tsk::handle< void > h1(
+ tsk::async( boost::move( t1), pool) );
+ tsk::handle< void > h2(
+ tsk::async( boost::move( t2), pool) );
+ tsk::handle< void > h3(
+ tsk::async( boost::move( t3), pool) );
+ boost::this_thread::sleep( pt::millisec( 250) );
+ pool.interrupt_all_worker();
+ BOOST_CHECK( ! h1.interruption_requested() );
+ BOOST_CHECK( ! h2.interruption_requested() );
+ BOOST_CHECK( ! h3.interruption_requested() );
+ BOOST_CHECK_THROW( h1.get(), tsk::task_interrupted);
+ BOOST_CHECK_THROW( h2.get(), tsk::task_interrupted);
+ BOOST_CHECK_THROW( h3.get(), tsk::task_interrupted);
+ BOOST_CHECK_EQUAL( pool.size(), std::size_t( 5) );
+ }
+
+ // check interrupt_and_wait
+ void test_case_17()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ bool finished( false);
+ tsk::task< void > t( interrupt_fn, pt::seconds( 1), boost::ref( finished) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ h.interrupt_and_wait();
+ BOOST_CHECK( finished);
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( h.has_exception() );
+ BOOST_CHECK( h.interruption_requested() );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check interrupt_and_wait_for
+ void test_case_18()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ bool finished( false);
+ tsk::task< void > t( interrupt_fn, pt::seconds( 1), boost::ref( finished) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( h.interrupt_and_wait_for( pt::seconds( 3) ) );
+ BOOST_CHECK( finished);
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( h.has_exception() );
+ BOOST_CHECK( h.interruption_requested() );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check interrupt_and_wait_for
+ void test_case_19()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< void > t( non_interrupt_fn, 3);
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( ! h.interrupt_and_wait_for( pt::seconds( 1) ) );
+ }
+
+ // check interrupt_and_wait_until
+ void test_case_20()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ bool finished( false);
+ tsk::task< void > t(
+ interrupt_fn,
+ pt::seconds( 1),
+ boost::ref( finished) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 3) ) );
+ BOOST_CHECK( finished);
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( h.has_exception() );
+ BOOST_CHECK( h.interruption_requested() );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check interrupt_and_wait_until
+ void test_case_21()
+ {
+ tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool(
+ tsk::poolsize( 5),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ tsk::task< void > t( non_interrupt_fn, 3);
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( ! h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 1) ) );
+ }
+
+ // check fifo scheduling
+ void test_case_22()
+ {
+ typedef tsk::static_pool<
+ tsk::bounded_twolock_fifo
+ > pool_type;
+ BOOST_CHECK( ! tsk::has_attribute< pool_type >::value);
+ pool_type pool(
+ tsk::poolsize( 1),
+ tsk::high_watermark( 10),
+ tsk::low_watermark( 10) );
+ boost::barrier b( 2);
+ std::vector< int > buffer;
+ tsk::task< void > t1( barrier_fn, boost::ref( b) );
+ tsk::task< void > t2(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 10);
+ tsk::task< void > t3(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 0);
+ tsk::async( boost::move( t1), pool);
+ boost::this_thread::sleep( pt::millisec( 250) );
+ tsk::async( boost::move( t2), pool);
+ tsk::async( boost::move( t3), pool);
+ 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) );
+ }
+};
+
+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_bounded_twolock_pool > instance( new test_bounded_twolock_pool() );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_1, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_2, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_3, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_4, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_5, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_6, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_7, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_8, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_9, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_10, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_11, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_12, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_13, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_14, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_15, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_16, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_17, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_18, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_19, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_20, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_21, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_bounded_twolock_pool::test_case_22, instance) );
+
+ return test;
+}
+

Modified: sandbox/task/libs/task/test/test_new_thread.cpp
==============================================================================
--- sandbox/task/libs/task/test/test_new_thread.cpp (original)
+++ sandbox/task/libs/task/test/test_new_thread.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -16,7 +16,6 @@
 #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>

Modified: sandbox/task/libs/task/test/test_own_thread.cpp
==============================================================================
--- sandbox/task/libs/task/test/test_own_thread.cpp (original)
+++ sandbox/task/libs/task/test/test_own_thread.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -16,7 +16,6 @@
 #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>

Modified: sandbox/task/libs/task/test/test_task.cpp
==============================================================================
--- sandbox/task/libs/task/test/test_task.cpp (original)
+++ sandbox/task/libs/task/test/test_task.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -16,7 +16,6 @@
 #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>

Added: sandbox/task/libs/task/test/test_unbounded_onelock_pool.cpp
==============================================================================
--- (empty file)
+++ sandbox/task/libs/task/test/test_unbounded_onelock_pool.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -0,0 +1,515 @@
+
+// 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/type_traits/is_same.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/task.hpp>
+
+#include "test_functions.hpp"
+
+namespace pt = boost::posix_time;
+namespace tsk = boost::task;
+
+class test_unbounded_onelock_pool
+{
+public:
+ // check size and move op
+ void test_case_1()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool1( tsk::poolsize( 3) );
+ BOOST_CHECK( pool1);
+ BOOST_CHECK_EQUAL( pool1.size(), std::size_t( 3) );
+
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool2;
+ BOOST_CHECK( ! pool2);
+ BOOST_CHECK_THROW( pool2.size(), tsk::pool_moved);
+
+ pool2 = boost::move( pool1);
+
+ BOOST_CHECK( ! pool1);
+ BOOST_CHECK_THROW( pool1.size(), tsk::pool_moved);
+
+ BOOST_CHECK( pool2);
+ BOOST_CHECK_EQUAL( pool2.size(), std::size_t( 3) );
+
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h(
+ tsk::async( boost::move( t), pool2) );
+ BOOST_CHECK_EQUAL( h.get(), 55);
+ }
+
+ // check submit
+ void test_case_2()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK_EQUAL( h.get(), 55);
+ }
+
+ // check assignment
+ void test_case_3()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h1;
+ tsk::handle< int > h2(
+ tsk::async( boost::move( t), pool) );
+ h1 = h2;
+ BOOST_CHECK_EQUAL( h1.get(), 55);
+ BOOST_CHECK_EQUAL( h2.get(), 55);
+ }
+
+ // check swap
+ void test_case_4()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< int > t1( fibonacci_fn, 5);
+ tsk::task< int > t2( fibonacci_fn, 10);
+ tsk::handle< int > h1(
+ tsk::async( boost::move( t1), pool) );
+ tsk::handle< int > h2(
+ tsk::async( boost::move( t2), pool) );
+ BOOST_CHECK_EQUAL( h1.get(), 5);
+ BOOST_CHECK_EQUAL( h2.get(), 55);
+ BOOST_CHECK_NO_THROW( h1.swap( h2) );
+ BOOST_CHECK_EQUAL( h1.get(), 55);
+ BOOST_CHECK_EQUAL( h2.get(), 5);
+ }
+
+ // check runs in pool
+ void test_case_5()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 1) );
+ tsk::task< bool > t( runs_in_pool_fn);
+ tsk::handle< bool > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK_EQUAL( h.get(), true);
+ }
+
+ // check shutdown
+ void test_case_6()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 1) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h(
+ tsk::async( boost::move( t), pool) );
+ pool.shutdown();
+ BOOST_CHECK( pool.closed() );
+ BOOST_CHECK_EQUAL( h.get(), 55);
+ }
+
+ // check runtime_error throw inside task
+ void test_case_7()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 1) );
+ tsk::task< void > t( throwing_fn);
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ pool.shutdown();
+ BOOST_CHECK_THROW( h.get(), std::runtime_error);
+ }
+
+ // check shutdown with task_rejected exception
+ void test_case_8()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 1) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ pool.shutdown();
+ BOOST_CHECK( pool.closed() );
+ BOOST_CHECK_THROW(
+ tsk::async( boost::move( t), pool),
+ tsk::task_rejected);
+ }
+
+ // check shutdown_now with thread_interrupted exception
+ void test_case_9()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 1) );
+ tsk::task< void > t( delay_fn, pt::millisec( 500) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ 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( 0) );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check wait
+ void test_case_10()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h(
+ tsk::async( boost::move( t), pool) );
+ h.wait();
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ BOOST_CHECK_EQUAL( h.get(), 55);
+ }
+
+ // check wait_for
+ void test_case_11()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< void > t( delay_fn, pt::seconds( 1) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( h.wait_for( pt::seconds( 3) ) );
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ }
+
+ // check wait_for
+ void test_case_12()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< void > t( delay_fn, pt::seconds( 3) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( ! h.wait_for( pt::seconds( 1) ) );
+ BOOST_CHECK( ! h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ }
+
+ // check wait_until
+ void test_case_13()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< void > t( delay_fn, pt::seconds( 1) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( h.wait_until( boost::get_system_time() + pt::seconds( 3) ) );
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ }
+
+ // check wait_until
+ void test_case_14()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< void > t( delay_fn, pt::seconds( 3) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( ! h.wait_until( boost::get_system_time() + pt::seconds( 1) ) );
+ BOOST_CHECK( ! h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ }
+
+ // check interrupt
+ void test_case_15()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< void > t( delay_fn, pt::seconds( 3) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ h.interrupt();
+ BOOST_CHECK( h.interruption_requested() );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check interrupt_all_worker
+ void test_case_16()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 5) );
+ tsk::task< void > t1( delay_fn, pt::seconds( 3) );
+ tsk::task< void > t2( delay_fn, pt::seconds( 3) );
+ tsk::task< void > t3( delay_fn, pt::seconds( 3) );
+ tsk::handle< void > h1(
+ tsk::async( boost::move( t1), pool) );
+ tsk::handle< void > h2(
+ tsk::async( boost::move( t2), pool) );
+ tsk::handle< void > h3(
+ tsk::async( boost::move( t3), pool) );
+ boost::this_thread::sleep( pt::millisec( 250) );
+ pool.interrupt_all_worker();
+ BOOST_CHECK( ! h1.interruption_requested() );
+ BOOST_CHECK( ! h2.interruption_requested() );
+ BOOST_CHECK( ! h3.interruption_requested() );
+ BOOST_CHECK_THROW( h1.get(), tsk::task_interrupted);
+ BOOST_CHECK_THROW( h2.get(), tsk::task_interrupted);
+ BOOST_CHECK_THROW( h3.get(), tsk::task_interrupted);
+ BOOST_CHECK_EQUAL( pool.size(), std::size_t( 5) );
+ }
+
+ // check interrupt_and_wait
+ void test_case_17()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 3) );
+ bool finished( false);
+ tsk::task< void > t(
+ interrupt_fn,
+ pt::seconds( 1),
+ boost::ref( finished) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ h.interrupt_and_wait();
+ BOOST_CHECK( finished);
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( h.has_exception() );
+ BOOST_CHECK( h.interruption_requested() );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check interrupt_and_wait_for
+ void test_case_18()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 3) );
+ bool finished( false);
+ tsk::task< void > t(
+ interrupt_fn,
+ pt::seconds( 1),
+ boost::ref( finished) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( h.interrupt_and_wait_for( pt::seconds( 3) ) );
+ BOOST_CHECK( finished);
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( h.has_exception() );
+ BOOST_CHECK( h.interruption_requested() );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check interrupt_and_wait_for
+ void test_case_19()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< void > t( non_interrupt_fn, 3);
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( ! h.interrupt_and_wait_for( pt::seconds( 1) ) );
+ }
+
+ // check interrupt_and_wait_until
+ void test_case_20()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 3) );
+ bool finished( false);
+ tsk::task< void > t(
+ interrupt_fn,
+ pt::seconds( 1),
+ boost::ref( finished) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 3) ) );
+ BOOST_CHECK( finished);
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( h.has_exception() );
+ BOOST_CHECK( h.interruption_requested() );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check interrupt_and_wait_until
+ void test_case_21()
+ {
+ tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< void > t( non_interrupt_fn, 3);
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( ! h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 1) ) );
+ }
+
+ // check fifo scheduling
+ void test_case_22()
+ {
+ typedef tsk::static_pool<
+ tsk::unbounded_onelock_fifo
+ > pool_type;
+ BOOST_CHECK( ! tsk::has_attribute< pool_type >::value);
+ pool_type pool( tsk::poolsize( 1) );
+ boost::barrier b( 2);
+ std::vector< int > buffer;
+ tsk::task< void > t1( barrier_fn, boost::ref( b) );
+ tsk::task< void > t2(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 10);
+ tsk::task< void > t3(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 0);
+ tsk::async( boost::move( t1), pool);
+ boost::this_thread::sleep( pt::millisec( 250) );
+ tsk::async( boost::move( t2), pool);
+ tsk::async( boost::move( t3), pool);
+ 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_23()
+ {
+ typedef tsk::static_pool<
+ tsk::unbounded_onelock_prio_queue< int >
+ > pool_type;
+ BOOST_CHECK( tsk::has_attribute< pool_type >::value);
+ typedef boost::is_same< tsk::attribute_type< pool_type >::type, int > type;
+ BOOST_CHECK( type::value);
+ pool_type pool( tsk::poolsize( 1) );
+ boost::barrier b( 2);
+ std::vector< int > buffer;
+ tsk::task< void > t1( barrier_fn, boost::ref( b) );
+ tsk::task< void > t2(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 10) ;
+ tsk::task< void > t3(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 0);
+ tsk::async( boost::move( t1), 0, pool);
+ boost::this_thread::sleep( pt::millisec( 250) );
+ tsk::async( boost::move( t2), 1, pool);
+ tsk::async( boost::move( t3), 0, pool);
+ 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 smart scheduling
+ void test_case_24()
+ {
+ typedef tsk::static_pool<
+ tsk::unbounded_onelock_smart_queue< int, std::less< int > >
+ > pool_type;
+ BOOST_CHECK( tsk::has_attribute< pool_type >::value);
+ typedef boost::is_same< tsk::attribute_type< pool_type >::type, int > type;
+ BOOST_CHECK( type::value);
+ pool_type pool( tsk::poolsize( 1) );
+ boost::barrier b( 2);
+ std::vector< int > buffer;
+ tsk::task< void > t1( barrier_fn, boost::ref( b) );
+ tsk::task< void > t2(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 10);
+ tsk::task< void > t3(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 0);
+ tsk::task< void > t4(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 1);
+ pool.submit( boost::move( t1), 0);
+ boost::this_thread::sleep( pt::millisec( 250) );
+ tsk::async( boost::move( t2), 2, pool);
+ tsk::async( boost::move( t3), 1, pool);
+ tsk::async( boost::move( t4), 2, pool);
+ 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_unbounded_onelock_pool > instance( new test_unbounded_onelock_pool() );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_1, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_2, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_3, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_4, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_5, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_6, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_7, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_8, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_9, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_10, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_11, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_12, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_13, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_14, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_15, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_16, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_17, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_18, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_19, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_20, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_21, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_22, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_23, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_onelock_pool::test_case_24, instance) );
+
+ return test;
+}

Deleted: sandbox/task/libs/task/test/test_unbounded_pool.cpp
==============================================================================
--- sandbox/task/libs/task/test/test_unbounded_pool.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
+++ (empty file)
@@ -1,553 +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 <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/type_traits/is_same.hpp>
-#include <boost/utility.hpp>
-
-#include <boost/task.hpp>
-
-#include "test_functions.hpp"
-
-namespace pt = boost::posix_time;
-namespace tsk = boost::task;
-
-class test_unbounded_pool
-{
-public:
- // check size, active, idle
- void test_case_1()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool1( tsk::poolsize( 3) );
- BOOST_CHECK( pool1);
- BOOST_CHECK_EQUAL( pool1.size(), std::size_t( 3) );
- BOOST_CHECK_EQUAL( pool1.idle(), std::size_t( 3) );
- BOOST_CHECK_EQUAL( pool1.active(), std::size_t( 0) );
-
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool2;
- BOOST_CHECK( ! pool2);
- BOOST_CHECK_THROW( pool2.size(), tsk::pool_moved);
- BOOST_CHECK_THROW( pool2.idle(), tsk::pool_moved);
- BOOST_CHECK_THROW( pool2.active(), tsk::pool_moved);
-
- pool2 = boost::move( pool1);
-
- BOOST_CHECK( ! pool1);
- BOOST_CHECK_THROW( pool1.size(), tsk::pool_moved);
- BOOST_CHECK_THROW( pool1.idle(), tsk::pool_moved);
- BOOST_CHECK_THROW( pool1.active(), tsk::pool_moved);
-
- BOOST_CHECK( pool2);
- BOOST_CHECK_EQUAL( pool2.size(), std::size_t( 3) );
- BOOST_CHECK_EQUAL( pool2.idle(), std::size_t( 3) );
- BOOST_CHECK_EQUAL( pool2.active(), std::size_t( 0) );
-
- tsk::task< int > t( fibonacci_fn, 10);
- tsk::handle< int > h(
- tsk::async( boost::move( t), pool2) );
- BOOST_CHECK_EQUAL( h.get(), 55);
- }
-
- // check submit
- void test_case_2()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 3) );
- tsk::task< int > t( fibonacci_fn, 10);
- tsk::handle< int > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK_EQUAL( h.get(), 55);
- }
-
- // check assignment
- void test_case_3()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 3) );
- tsk::task< int > t( fibonacci_fn, 10);
- tsk::handle< int > h1;
- tsk::handle< int > h2(
- tsk::async( boost::move( t), pool) );
- h1 = h2;
- BOOST_CHECK_EQUAL( h1.get(), 55);
- BOOST_CHECK_EQUAL( h2.get(), 55);
- }
-
- // check swap
- void test_case_4()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 3) );
- tsk::task< int > t1( fibonacci_fn, 5);
- tsk::task< int > t2( fibonacci_fn, 10);
- tsk::handle< int > h1(
- tsk::async( boost::move( t1), pool) );
- tsk::handle< int > h2(
- tsk::async( boost::move( t2), pool) );
- BOOST_CHECK_EQUAL( h1.get(), 5);
- BOOST_CHECK_EQUAL( h2.get(), 55);
- BOOST_CHECK_NO_THROW( h1.swap( h2) );
- BOOST_CHECK_EQUAL( h1.get(), 55);
- BOOST_CHECK_EQUAL( h2.get(), 5);
- }
-
- // check runs in pool
- void test_case_5()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 1) );
- tsk::task< bool > t( runs_in_pool_fn);
- tsk::handle< bool > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK_EQUAL( h.get(), true);
- }
-
- // check shutdown
- void test_case_6()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 1) );
- tsk::task< int > t( fibonacci_fn, 10);
- tsk::handle< int > h(
- tsk::async( boost::move( t), pool) );
- pool.shutdown();
- BOOST_CHECK( pool.closed() );
- BOOST_CHECK_EQUAL( h.get(), 55);
- }
-
- // check runtime_error throw inside task
- void test_case_7()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 1) );
- tsk::task< void > t( throwing_fn);
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- pool.shutdown();
- BOOST_CHECK_THROW( h.get(), std::runtime_error);
- }
-
- // check shutdown with task_rejected exception
- void test_case_8()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 1) );
- tsk::task< int > t( fibonacci_fn, 10);
- pool.shutdown();
- BOOST_CHECK( pool.closed() );
- BOOST_CHECK_THROW(
- tsk::async( boost::move( t), pool),
- tsk::task_rejected);
- }
-
- // check shutdown_now with thread_interrupted exception
- void test_case_9()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 1) );
- tsk::task< void > t( delay_fn, pt::millisec( 500) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- 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( 0) );
- BOOST_CHECK_EQUAL( pool.idle(), std::size_t( 0) );
- BOOST_CHECK_EQUAL( pool.active(), std::size_t( 0) );
- BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
- }
-
- // check pending
- void test_case_10()
- {
- typedef tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool_type;
- pool_type pool( tsk::poolsize( 1) );
- boost::barrier b( 2);
- tsk::task< void > t1( barrier_fn, boost::ref( b) );
- tsk::task< int > t2( fibonacci_fn, 10);
- tsk::task< int > t3( fibonacci_fn, 10);
- tsk::handle< void > h1(
- tsk::async( boost::move( t1), pool) );
- boost::this_thread::sleep( pt::millisec( 250) );
- BOOST_CHECK_EQUAL( pool.pending(), std::size_t( 0) );
- tsk::handle< int > h2(
- tsk::async( boost::move( t2), pool) );
- boost::this_thread::sleep( pt::millisec(250) );
- BOOST_CHECK_EQUAL( pool.pending(), std::size_t( 1) );
- tsk::handle< int > h3(
- tsk::async( boost::move( t3), pool) );
- 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 wait
- void test_case_11()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 3) );
- tsk::task< int > t( fibonacci_fn, 10);
- tsk::handle< int > h(
- tsk::async( boost::move( t), pool) );
- h.wait();
- BOOST_CHECK( h.is_ready() );
- BOOST_CHECK( h.has_value() );
- BOOST_CHECK( ! h.has_exception() );
- BOOST_CHECK_EQUAL( h.get(), 55);
- }
-
- // check wait_for
- void test_case_12()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 3) );
- tsk::task< void > t( delay_fn, pt::seconds( 1) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK( h.wait_for( pt::seconds( 3) ) );
- BOOST_CHECK( h.is_ready() );
- BOOST_CHECK( h.has_value() );
- BOOST_CHECK( ! h.has_exception() );
- }
-
- // check wait_for
- void test_case_13()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 3) );
- tsk::task< void > t( delay_fn, pt::seconds( 3) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK( ! h.wait_for( pt::seconds( 1) ) );
- BOOST_CHECK( ! h.is_ready() );
- BOOST_CHECK( ! h.has_value() );
- BOOST_CHECK( ! h.has_exception() );
- }
-
- // check wait_until
- void test_case_14()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 3) );
- tsk::task< void > t( delay_fn, pt::seconds( 1) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK( h.wait_until( boost::get_system_time() + pt::seconds( 3) ) );
- BOOST_CHECK( h.is_ready() );
- BOOST_CHECK( h.has_value() );
- BOOST_CHECK( ! h.has_exception() );
- }
-
- // check wait_until
- void test_case_15()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 3) );
- tsk::task< void > t( delay_fn, pt::seconds( 3) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK( ! h.wait_until( boost::get_system_time() + pt::seconds( 1) ) );
- BOOST_CHECK( ! h.is_ready() );
- BOOST_CHECK( ! h.has_value() );
- BOOST_CHECK( ! h.has_exception() );
- }
-
- // check interrupt
- void test_case_16()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 3) );
- tsk::task< void > t( delay_fn, pt::seconds( 3) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- h.interrupt();
- BOOST_CHECK( h.interruption_requested() );
- BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
- }
-
- // check interrupt_all_worker
- void test_case_17()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 5) );
- tsk::task< void > t1( delay_fn, pt::seconds( 3) );
- tsk::task< void > t2( delay_fn, pt::seconds( 3) );
- tsk::task< void > t3( delay_fn, pt::seconds( 3) );
- tsk::handle< void > h1(
- tsk::async( boost::move( t1), pool) );
- tsk::handle< void > h2(
- tsk::async( boost::move( t2), pool) );
- tsk::handle< void > h3(
- tsk::async( boost::move( t3), pool) );
- boost::this_thread::sleep( pt::millisec( 250) );
- pool.interrupt_all_worker();
- BOOST_CHECK( ! h1.interruption_requested() );
- BOOST_CHECK( ! h2.interruption_requested() );
- BOOST_CHECK( ! h3.interruption_requested() );
- BOOST_CHECK_THROW( h1.get(), tsk::task_interrupted);
- BOOST_CHECK_THROW( h2.get(), tsk::task_interrupted);
- BOOST_CHECK_THROW( h3.get(), tsk::task_interrupted);
- BOOST_CHECK_EQUAL( pool.size(), std::size_t( 5) );
- }
-
- // check interrupt_and_wait
- void test_case_18()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 3) );
- bool finished( false);
- tsk::task< void > t(
- interrupt_fn,
- pt::seconds( 1),
- boost::ref( finished) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- h.interrupt_and_wait();
- BOOST_CHECK( finished);
- BOOST_CHECK( h.is_ready() );
- BOOST_CHECK( ! h.has_value() );
- BOOST_CHECK( h.has_exception() );
- BOOST_CHECK( h.interruption_requested() );
- BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
- }
-
- // check interrupt_and_wait_for
- void test_case_19()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 3) );
- bool finished( false);
- tsk::task< void > t(
- interrupt_fn,
- pt::seconds( 1),
- boost::ref( finished) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK( h.interrupt_and_wait_for( pt::seconds( 3) ) );
- BOOST_CHECK( finished);
- BOOST_CHECK( h.is_ready() );
- BOOST_CHECK( ! h.has_value() );
- BOOST_CHECK( h.has_exception() );
- BOOST_CHECK( h.interruption_requested() );
- BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
- }
-
- // check interrupt_and_wait_for
- void test_case_20()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 3) );
- tsk::task< void > t( non_interrupt_fn, 3);
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK( ! h.interrupt_and_wait_for( pt::seconds( 1) ) );
- }
-
- // check interrupt_and_wait_until
- void test_case_21()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 3) );
- bool finished( false);
- tsk::task< void > t(
- interrupt_fn,
- pt::seconds( 1),
- boost::ref( finished) );
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK( h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 3) ) );
- BOOST_CHECK( finished);
- BOOST_CHECK( h.is_ready() );
- BOOST_CHECK( ! h.has_value() );
- BOOST_CHECK( h.has_exception() );
- BOOST_CHECK( h.interruption_requested() );
- BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
- }
-
- // check interrupt_and_wait_until
- void test_case_22()
- {
- tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool( tsk::poolsize( 3) );
- tsk::task< void > t( non_interrupt_fn, 3);
- tsk::handle< void > h(
- tsk::async( boost::move( t), pool) );
- BOOST_CHECK( ! h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 1) ) );
- }
-
- // check fifo scheduling
- void test_case_23()
- {
- typedef tsk::static_pool<
- tsk::unbounded_channel< tsk::fifo >
- > pool_type;
- BOOST_CHECK( ! tsk::has_attribute< pool_type >::value);
- pool_type pool( tsk::poolsize( 1) );
- boost::barrier b( 2);
- std::vector< int > buffer;
- tsk::task< void > t1( barrier_fn, boost::ref( b) );
- tsk::task< void > t2(
- buffer_fibonacci_fn,
- boost::ref( buffer),
- 10);
- tsk::task< void > t3(
- buffer_fibonacci_fn,
- boost::ref( buffer),
- 0);
- tsk::async( boost::move( t1), pool);
- tsk::async( boost::move( t2), pool);
- tsk::async( boost::move( t3), pool);
- 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_24()
- {
- typedef tsk::static_pool<
- tsk::unbounded_channel< tsk::priority< int > >
- > pool_type;
- BOOST_CHECK( tsk::has_attribute< pool_type >::value);
- typedef boost::is_same< tsk::attribute_type< pool_type >::type, int > type;
- BOOST_CHECK( type::value);
- pool_type pool( tsk::poolsize( 1) );
- boost::barrier b( 2);
- std::vector< int > buffer;
- tsk::task< void > t1( barrier_fn, boost::ref( b) );
- tsk::task< void > t2(
- buffer_fibonacci_fn,
- boost::ref( buffer),
- 10) ;
- tsk::task< void > t3(
- buffer_fibonacci_fn,
- boost::ref( buffer),
- 0);
- tsk::async( boost::move( t1), 0, pool);
- tsk::async( boost::move( t2), 1, pool);
- tsk::async( boost::move( t3), 0, pool);
- 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 smart scheduling
- void test_case_25()
- {
- typedef tsk::static_pool<
- tsk::unbounded_channel< tsk::smart< int, std::less< int >, tsk::replace_oldest, tsk::take_oldest > >
- > pool_type;
- BOOST_CHECK( tsk::has_attribute< pool_type >::value);
- typedef boost::is_same< tsk::attribute_type< pool_type >::type, int > type;
- BOOST_CHECK( type::value);
- pool_type pool( tsk::poolsize( 1) );
- boost::barrier b( 2);
- std::vector< int > buffer;
- tsk::task< void > t1( barrier_fn, boost::ref( b) );
- tsk::task< void > t2(
- buffer_fibonacci_fn,
- boost::ref( buffer),
- 10);
- tsk::task< void > t3(
- buffer_fibonacci_fn,
- boost::ref( buffer),
- 0);
- tsk::task< void > t4(
- buffer_fibonacci_fn,
- boost::ref( buffer),
- 1);
- pool.submit( boost::move( t1), 0);
- tsk::async( boost::move( t2), 2, pool);
- tsk::async( boost::move( t3), 1, pool);
- tsk::async( boost::move( t4), 2, pool);
- 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_unbounded_pool > instance( new test_unbounded_pool() );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_1, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_2, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_3, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_4, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_5, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_6, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_7, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_8, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_9, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_10, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_11, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_12, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_13, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_14, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_15, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_16, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_17, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_18, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_19, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_20, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_21, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_22, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_23, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_24, instance) );
- test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_pool::test_case_25, instance) );
-
- return test;
-}

Added: sandbox/task/libs/task/test/test_unbounded_twolock_pool.cpp
==============================================================================
--- (empty file)
+++ sandbox/task/libs/task/test/test_unbounded_twolock_pool.cpp 2009-09-19 15:06:44 EDT (Sat, 19 Sep 2009)
@@ -0,0 +1,444 @@
+
+// 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/type_traits/is_same.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/task.hpp>
+
+#include "test_functions.hpp"
+
+namespace pt = boost::posix_time;
+namespace tsk = boost::task;
+
+class test_unbounded_twolock_pool
+{
+public:
+ // check size and move op
+ void test_case_1()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool1( tsk::poolsize( 3) );
+ BOOST_CHECK( pool1);
+ BOOST_CHECK_EQUAL( pool1.size(), std::size_t( 3) );
+
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool2;
+ BOOST_CHECK( ! pool2);
+ BOOST_CHECK_THROW( pool2.size(), tsk::pool_moved);
+
+ pool2 = boost::move( pool1);
+
+ BOOST_CHECK( ! pool1);
+ BOOST_CHECK_THROW( pool1.size(), tsk::pool_moved);
+
+ BOOST_CHECK( pool2);
+ BOOST_CHECK_EQUAL( pool2.size(), std::size_t( 3) );
+
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h(
+ tsk::async( boost::move( t), pool2) );
+ BOOST_CHECK_EQUAL( h.get(), 55);
+ }
+
+ // check submit
+ void test_case_2()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK_EQUAL( h.get(), 55);
+ }
+
+ // check assignment
+ void test_case_3()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h1;
+ tsk::handle< int > h2(
+ tsk::async( boost::move( t), pool) );
+ h1 = h2;
+ BOOST_CHECK_EQUAL( h1.get(), 55);
+ BOOST_CHECK_EQUAL( h2.get(), 55);
+ }
+
+ // check swap
+ void test_case_4()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< int > t1( fibonacci_fn, 5);
+ tsk::task< int > t2( fibonacci_fn, 10);
+ tsk::handle< int > h1(
+ tsk::async( boost::move( t1), pool) );
+ tsk::handle< int > h2(
+ tsk::async( boost::move( t2), pool) );
+ BOOST_CHECK_EQUAL( h1.get(), 5);
+ BOOST_CHECK_EQUAL( h2.get(), 55);
+ BOOST_CHECK_NO_THROW( h1.swap( h2) );
+ BOOST_CHECK_EQUAL( h1.get(), 55);
+ BOOST_CHECK_EQUAL( h2.get(), 5);
+ }
+
+ // check runs in pool
+ void test_case_5()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 1) );
+ tsk::task< bool > t( runs_in_pool_fn);
+ tsk::handle< bool > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK_EQUAL( h.get(), true);
+ }
+
+ // check shutdown
+ void test_case_6()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 1) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h(
+ tsk::async( boost::move( t), pool) );
+ pool.shutdown();
+ BOOST_CHECK( pool.closed() );
+ BOOST_CHECK_EQUAL( h.get(), 55);
+ }
+
+ // check runtime_error throw inside task
+ void test_case_7()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 1) );
+ tsk::task< void > t( throwing_fn);
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ pool.shutdown();
+ BOOST_CHECK_THROW( h.get(), std::runtime_error);
+ }
+
+ // check shutdown with task_rejected exception
+ void test_case_8()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 1) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ pool.shutdown();
+ BOOST_CHECK( pool.closed() );
+ BOOST_CHECK_THROW(
+ tsk::async( boost::move( t), pool),
+ tsk::task_rejected);
+ }
+
+ // check shutdown_now with thread_interrupted exception
+ void test_case_9()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 1) );
+ tsk::task< void > t( delay_fn, pt::millisec( 500) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ 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( 0) );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check wait
+ void test_case_10()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< int > t( fibonacci_fn, 10);
+ tsk::handle< int > h(
+ tsk::async( boost::move( t), pool) );
+ h.wait();
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ BOOST_CHECK_EQUAL( h.get(), 55);
+ }
+
+ // check wait_for
+ void test_case_11()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< void > t( delay_fn, pt::seconds( 1) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( h.wait_for( pt::seconds( 3) ) );
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ }
+
+ // check wait_for
+ void test_case_12()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< void > t( delay_fn, pt::seconds( 3) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( ! h.wait_for( pt::seconds( 1) ) );
+ BOOST_CHECK( ! h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ }
+
+ // check wait_until
+ void test_case_13()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< void > t( delay_fn, pt::seconds( 1) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( h.wait_until( boost::get_system_time() + pt::seconds( 3) ) );
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ }
+
+ // check wait_until
+ void test_case_14()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< void > t( delay_fn, pt::seconds( 3) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( ! h.wait_until( boost::get_system_time() + pt::seconds( 1) ) );
+ BOOST_CHECK( ! h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( ! h.has_exception() );
+ }
+
+ // check interrupt
+ void test_case_15()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< void > t( delay_fn, pt::seconds( 3) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ h.interrupt();
+ BOOST_CHECK( h.interruption_requested() );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check interrupt_all_worker
+ void test_case_16()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 5) );
+ tsk::task< void > t1( delay_fn, pt::seconds( 3) );
+ tsk::task< void > t2( delay_fn, pt::seconds( 3) );
+ tsk::task< void > t3( delay_fn, pt::seconds( 3) );
+ tsk::handle< void > h1(
+ tsk::async( boost::move( t1), pool) );
+ tsk::handle< void > h2(
+ tsk::async( boost::move( t2), pool) );
+ tsk::handle< void > h3(
+ tsk::async( boost::move( t3), pool) );
+ boost::this_thread::sleep( pt::millisec( 250) );
+ pool.interrupt_all_worker();
+ BOOST_CHECK( ! h1.interruption_requested() );
+ BOOST_CHECK( ! h2.interruption_requested() );
+ BOOST_CHECK( ! h3.interruption_requested() );
+ BOOST_CHECK_THROW( h1.get(), tsk::task_interrupted);
+ BOOST_CHECK_THROW( h2.get(), tsk::task_interrupted);
+ BOOST_CHECK_THROW( h3.get(), tsk::task_interrupted);
+ BOOST_CHECK_EQUAL( pool.size(), std::size_t( 5) );
+ }
+
+ // check interrupt_and_wait
+ void test_case_17()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 3) );
+ bool finished( false);
+ tsk::task< void > t(
+ interrupt_fn,
+ pt::seconds( 1),
+ boost::ref( finished) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ h.interrupt_and_wait();
+ BOOST_CHECK( finished);
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( h.has_exception() );
+ BOOST_CHECK( h.interruption_requested() );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check interrupt_and_wait_for
+ void test_case_18()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 3) );
+ bool finished( false);
+ tsk::task< void > t(
+ interrupt_fn,
+ pt::seconds( 1),
+ boost::ref( finished) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( h.interrupt_and_wait_for( pt::seconds( 3) ) );
+ BOOST_CHECK( finished);
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( h.has_exception() );
+ BOOST_CHECK( h.interruption_requested() );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check interrupt_and_wait_for
+ void test_case_19()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< void > t( non_interrupt_fn, 3);
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( ! h.interrupt_and_wait_for( pt::seconds( 1) ) );
+ }
+
+ // check interrupt_and_wait_until
+ void test_case_20()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 3) );
+ bool finished( false);
+ tsk::task< void > t(
+ interrupt_fn,
+ pt::seconds( 1),
+ boost::ref( finished) );
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 3) ) );
+ BOOST_CHECK( finished);
+ BOOST_CHECK( h.is_ready() );
+ BOOST_CHECK( ! h.has_value() );
+ BOOST_CHECK( h.has_exception() );
+ BOOST_CHECK( h.interruption_requested() );
+ BOOST_CHECK_THROW( h.get(), tsk::task_interrupted);
+ }
+
+ // check interrupt_and_wait_until
+ void test_case_21()
+ {
+ tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool( tsk::poolsize( 3) );
+ tsk::task< void > t( non_interrupt_fn, 3);
+ tsk::handle< void > h(
+ tsk::async( boost::move( t), pool) );
+ BOOST_CHECK( ! h.interrupt_and_wait_until( boost::get_system_time() + pt::seconds( 1) ) );
+ }
+
+ // check fifo scheduling
+ void test_case_22()
+ {
+ typedef tsk::static_pool<
+ tsk::unbounded_twolock_fifo
+ > pool_type;
+ BOOST_CHECK( ! tsk::has_attribute< pool_type >::value);
+ pool_type pool( tsk::poolsize( 1) );
+ boost::barrier b( 2);
+ std::vector< int > buffer;
+ tsk::task< void > t1( barrier_fn, boost::ref( b) );
+ tsk::task< void > t2(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 10);
+ tsk::task< void > t3(
+ buffer_fibonacci_fn,
+ boost::ref( buffer),
+ 0);
+ tsk::async( boost::move( t1), pool);
+ boost::this_thread::sleep( pt::millisec( 250) );
+ tsk::async( boost::move( t2), pool);
+ tsk::async( boost::move( t3), pool);
+ 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) );
+ }
+};
+
+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_unbounded_twolock_pool > instance( new test_unbounded_twolock_pool() );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_1, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_2, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_3, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_4, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_5, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_6, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_7, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_8, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_9, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_10, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_11, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_12, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_13, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_14, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_15, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_16, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_17, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_18, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_19, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_20, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_21, instance) );
+ test->add( BOOST_CLASS_TEST_CASE( & test_unbounded_twolock_pool::test_case_22, instance) );
+
+ 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