Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r50591 - sandbox/interthreads/libs/interthreads/doc
From: vicente.botet_at_[hidden]
Date: 2009-01-14 12:49:40


Author: viboes
Date: 2009-01-14 12:49:38 EST (Wed, 14 Jan 2009)
New Revision: 50591
URL: http://svn.boost.org/trac/boost/changeset/50591

Log:
interthreads version 0.2
Adding threader/joiner
Adding Asynchronous Executors fmk
Text files modified:
   sandbox/interthreads/libs/interthreads/doc/Jamfile.v2 | 2
   sandbox/interthreads/libs/interthreads/doc/acknowledgements.qbk | 7
   sandbox/interthreads/libs/interthreads/doc/appendices.qbk | 38 ++
   sandbox/interthreads/libs/interthreads/doc/case_studies.qbk | 39 +-
   sandbox/interthreads/libs/interthreads/doc/changes.qbk | 29 +
   sandbox/interthreads/libs/interthreads/doc/getting_started.qbk | 26 -
   sandbox/interthreads/libs/interthreads/doc/implementation.qbk | 2
   sandbox/interthreads/libs/interthreads/doc/installation.qbk | 50 +++
   sandbox/interthreads/libs/interthreads/doc/interthreads.qbk | 5
   sandbox/interthreads/libs/interthreads/doc/introduction.qbk | 233 ++++++-----------
   sandbox/interthreads/libs/interthreads/doc/overview.qbk | 2
   sandbox/interthreads/libs/interthreads/doc/rationale.qbk | 2
   sandbox/interthreads/libs/interthreads/doc/reference.qbk | 525 +++++++++++++++++++++++++++++++++++++--
   sandbox/interthreads/libs/interthreads/doc/tutorial.qbk | 2
   sandbox/interthreads/libs/interthreads/doc/users_guide.qbk | 4
   15 files changed, 708 insertions(+), 258 deletions(-)

Modified: sandbox/interthreads/libs/interthreads/doc/Jamfile.v2
==============================================================================
--- sandbox/interthreads/libs/interthreads/doc/Jamfile.v2 (original)
+++ sandbox/interthreads/libs/interthreads/doc/Jamfile.v2 2009-01-14 12:49:38 EST (Wed, 14 Jan 2009)
@@ -1,5 +1,5 @@
 
-# (C) Copyright 2008 Vicente J Botet Escriba.
+# (C) Copyright 2008-20009 Vicente J Botet Escriba.
 #
 # 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)

Modified: sandbox/interthreads/libs/interthreads/doc/acknowledgements.qbk
==============================================================================
--- sandbox/interthreads/libs/interthreads/doc/acknowledgements.qbk (original)
+++ sandbox/interthreads/libs/interthreads/doc/acknowledgements.qbk 2009-01-14 12:49:38 EST (Wed, 14 Jan 2009)
@@ -1,5 +1,5 @@
 [/
- (C) Copyright 2008 Vicente J Botet Escriba.
+ (C) Copyright 2008-20009 Vicente J Botet Escriba.
   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).
@@ -13,6 +13,9 @@
 
 Thanks also must go to Jochen Heckl for the ideas given respect to the thread_tuple::wait_first implementation.
 
-You can help me to make this library better! Any feedback is very welcome.
+The Threader/Joiner design is taken from [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1883.pdf N1833 - Preliminary Threading Library Proposal for TR2]
+Many thanks to Kevlin Henney to make evident to me the separation between asynchonous executors, and asynchronous completion tokens.
+
+You can help me to make this library better! Any feedback is very welcome.
 
 [endsect]

Modified: sandbox/interthreads/libs/interthreads/doc/appendices.qbk
==============================================================================
--- sandbox/interthreads/libs/interthreads/doc/appendices.qbk (original)
+++ sandbox/interthreads/libs/interthreads/doc/appendices.qbk 2009-01-14 12:49:38 EST (Wed, 14 Jan 2009)
@@ -1,6 +1,6 @@
 [/
 [/
- (C) Copyright 2008 Vicente J. Botet Escriba
+ (C) Copyright 2008-20009 Vicente J. Botet Escriba
   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).
@@ -25,12 +25,14 @@
 [heading Tasks to do before review]
 [variablelist
 
-[[Add tests] [Currently there are only some examples. There is yet a long way before been able to review the library.]]
+[[Use set_once to implement wait_for_any] [The current implementation uses the Boost.Futures
+wait_for_any to implement this feauture, which add an superflous constraint be able to get a future to all the AE/ACT.]]
+
+[[Complete the tests] [Even if the current release incluse more test here is yet a long way before been able to review the library.]]
 
 [[Add C++0x move semantics on compilers supporting it and use the Boost.Move emulation otherwise] [.]]
-[[Use C++0x variadic templates on compilers supporting it and the Use the preprocesor otherwise] [.]]
 
-[[Add a practical example using thread_tuple, thread_tuple_once] [.]]
+[[Use C++0x variadic templates on compilers supporting it and the Use the preprocesor otherwise] [.]]
 
 [[Complete the STM example] [.]]
 
@@ -39,11 +41,28 @@
 ]
 
 [heading For later releases]
+
 [variablelist
+[
+ [Add Message queues] [Messages queue are the next step concerning the communication between threads on the InterThreads library.]
+]
+[
+ [Add Rendez-vous]
+ [Concurrent components may interact in different ways: they may access the same objects by, for example,
+ executing functions of these objects; or they may communicate directly by executing functions of each other.
+ These library will provide the so-called rendezvous mechanism for handling direct communication between active objects.]
+]
+[
+ [Add a daemon controlling all the keep alive controller threads] [This daemon will send regular keep_alive messages and kill the process when dead]
+]
+[
+ [Generalize both specific pointers in a template class basic_thread_specific_ptr] []
+]
+
+]
 
-[[Generalize both specific pointers in a template class basic_thread_specific_ptr] [
 
-[*Domain Features]
+[section `basic_thread_specific_ptr` Domain Features]
 
 [variablelist
 
@@ -108,14 +127,11 @@
 others keys.
 
 Configuration the fixed/variable/mixed key range, ordered/unordered map, intrusive/extrusive map, shared/exclusive locking.
-]]
 
-[[Add Message queues] [Messages queue are the next step concerning the communication between threads on the InterThreads library.]]
-[[Add a daemon controlling all the keep alive controller threads] [This daemon will send regular keep_alive messages and kill the process when dead]]
-
-]
 
 [endsect]
+[endsect]
 
 [endsect]
 
+

Modified: sandbox/interthreads/libs/interthreads/doc/case_studies.qbk
==============================================================================
--- sandbox/interthreads/libs/interthreads/doc/case_studies.qbk (original)
+++ sandbox/interthreads/libs/interthreads/doc/case_studies.qbk 2009-01-14 12:49:38 EST (Wed, 14 Jan 2009)
@@ -1,5 +1,5 @@
 [/
- (C) Copyright 2008 Vicente J. Botet Escriba
+ (C) Copyright 2008-20009 Vicente J. Botet Escriba
   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).
@@ -29,13 +29,6 @@
 
 [endsect]
 
-[/==================================]
-[section Any ideas on a thread_tuple, thread_tuple_once practical example are welcome?]
-[/==================================]
-
-
-[endsect]
-
 
 [/==================================]
 [section Thread safe deferred traces]
@@ -53,6 +46,7 @@
 This mutex could be the bottleneck of the system. Onle one mutex resource for all the user threads.
 
 [pre
+
         U U
          \ /
           \ /
@@ -63,7 +57,7 @@
 ]
 
 
-[$images/star.png]
+[/$images/star.png]
 
 Another approach could be to use a queue of output stream buffers for each thread.
 Each buffer is timestamped with the creation date and there is concentrator that takes one by one the elements ordered by the timestamp.
@@ -72,9 +66,10 @@
 In this context we can ensure thread safety without locking as far as
 the queue has at least two messages.
 
-[$images/fourche.png]
+[/$images/fourche.png]
 
 [pre
+
     U ----- R ------+
                      \
     U ----- R ------\ \
@@ -104,7 +99,7 @@
 
     cout_ << "Hello World!" << std::endl ;
 
-All the magic is in the template class boost::iostreams::stream<>. The parameter must be a model of a sink (See the boost.Iostreams library).
+All the magic is in the `template class boost::iostreams::stream<>`. The parameter must be a model of a sink (See the Boost.Iostreams library).
 Here it is.
 
     namespace detail {
@@ -122,7 +117,7 @@
         };
     }
 
-This class declares the just minimum in order to model a sink. In addition as in order to mask the implementation the Piml idiom is used.
+This class declares the just minimum in order to model a sink. In addition as in order to mask the implementation the PImpl idiom is used.
 The implementation of these function is straiforward:
 
     async_ostream::async_ostream(std::ostream& os)
@@ -160,12 +155,13 @@
         static void loop(impl* that);
     };
 
-Of course we need to store a reference to the final ostreanm.
-The thread_specific_shared_ptr tsss_ is used to encapsulate the logic specific to each thread.
+Of course we need to store a reference to the final ostream.
+
+The `thread_specific_shared_ptr tsss_` is used to encapsulate the logic specific to each thread.
 
     typedef thread_specific_shared_ptr<async_ostream_thread_ctx> tsss_type;
 
-A priority queue queue_ will be used the concentrator thread to order the stringstreams by date.
+A priority queue `queue_` will be used the concentrator thread to order the stringstreams by date.
 
     template <typename T>
     struct detail::timestamped {
@@ -188,7 +184,7 @@
     typedef timestamped<std::stringstream> element_type;
     typedef std::priority_queue<queue_type*, std::deque<element_type*>, element_type::ptr_comparator_gt> priority_queue_type;
 
-In addition to the timestamp date_ we need a sequence number to order the stringstreams pushed without enough time granularity, e.g. on the same microsecond.
+In addition to the timestamp `date_` we need a sequence number to order the stringstreams pushed without enough time granularity, e.g. on the same microsecond.
 
 To finish the field declaration there is the concentrator thread implemented by the loop function.
 
@@ -212,7 +208,7 @@
         }
 
 The central sink function is write. Here instead to lock a mutex the function forwards to
-the thread specific shared pointer. We will see above the how async_ostream_thread_ctx handles this call.
+the thread specific shared pointer. We will see above the how `async_ostream_thread_ctx` handles this call.
 
         std::streamsize write(const char* s, std::streamsize n) {
             return tsss_->write(s, n);
@@ -242,7 +238,7 @@
             return n;
         }
 
-Once the user do a flush the current element is enqueued on the queue. The sec_ integer is used as monotonic sequence in conjuntion with the timestamp.
+Once the user do a flush the current element is enqueued on the queue. The `sec_` integer is used as monotonic sequence in conjuntion with the timestamp.
 
         void flush() {
             current_->reset_date(seq_);
@@ -309,11 +305,10 @@
 [endsect]
 
 [/============================]
-[section Proposed Case Studies]
+[section Case Studies]
 [/============================]
 
-This section do not includes a complete examples using the library, but some case studies that could use in some way the library.
-Some case studies, though tricky, are not huge and would be suitable for someone who has a limited time to spend on them.
+This section do not includes a complete examples using the library, but a case studies that could use in some way the library.
 I'm curently working on the STM case study.
 
 [/========================]
@@ -586,4 +581,4 @@
 
 [endsect]
 
-[endsect]
\ No newline at end of file
+[endsect]

Modified: sandbox/interthreads/libs/interthreads/doc/changes.qbk
==============================================================================
--- sandbox/interthreads/libs/interthreads/doc/changes.qbk (original)
+++ sandbox/interthreads/libs/interthreads/doc/changes.qbk 2009-01-14 12:49:38 EST (Wed, 14 Jan 2009)
@@ -1,5 +1,5 @@
 [/
- (C) Copyright 2008 Vicente J Botet Escriba.
+ (C) Copyright 2008-20009 Vicente J Botet Escriba.
   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).
@@ -7,19 +7,28 @@
 
 [section:changes Appendix A: History]
 
-[heading [*Version 0.2, December 07, 2008] ['Movable thread tuples, Threader and test on more toolsets]]
+[heading [*Version 0.2, December 07, 2009] Asynchronous execution and test on more toolsets]
 
 [*Features:]
 
-* Make movable thread_tuple_once and thread_group_once
-* Threader/joiner classes
+* Asynchronous executors (AE) and asynchronous completion token (ACT) framework
+ * fork and fork_all functions
+ * wait_for_all, wait_for_any functions
+ * get_all, join_all, ...
+* unique/shared threader (AE) and unique/shared joiner(ACT) classes
+* basic_threader(AE) class
+* unique/shared launcher(AE) class
+* scheduler(AE) class (working with tp::pool(AE) and tp::task (ACT))
+* thread_decorator can now decorate a nullary function in addition to a callable function
+* asynchronous_executor_decorator mixin allows to decorate the functions launched by an asynchronous executor
+* Boost.Typeof registration for the ACT classes
+* The AE/ACT framework comes with significant tests
 
 [*Toolsets:]
 
-* Tested with static and shared lib.
 * Tested on Linux gcc 3.4.6.
 * Tested on Linux gcc 4.1.2.
-* Modification helping Windows.
+* Modification helping Windows (not tested)
 
 [*Bugs:]
 
@@ -36,7 +45,13 @@
  
 [heading [*Bugs:]]
 
-[*v0.1#1: basic_keep_alive example do not link.]
+[*v0.2#2: Some trouble with the use of tp::pool firectly, use scheduler instead.]
+
+[*v0.2#1: get_all do not work yet, use set_all instead.]
+get_all do not work because fusion transform sequence function can not take non const sequences.
+Maybe we can emulate it using set_all and a mpl a transformation for a tuple of ACT to a tuple of result_type.
+
+CLOSED [*v0.1#1: basic_keep_alive example do not link.]
 
 
 

Modified: sandbox/interthreads/libs/interthreads/doc/getting_started.qbk
==============================================================================
--- sandbox/interthreads/libs/interthreads/doc/getting_started.qbk (original)
+++ sandbox/interthreads/libs/interthreads/doc/getting_started.qbk 2009-01-14 12:49:38 EST (Wed, 14 Jan 2009)
@@ -1,6 +1,6 @@
 [/
 [/
- (C) Copyright 2008 Vicente J. Botet Escriba
+ (C) Copyright 2008-20009 Vicente J. Botet Escriba
   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).
@@ -188,6 +188,12 @@
     }
     
     int main() {
+ bith::shared_threader_decorator ae;
+ bith::wait_for_all(ae, my_thread, my_thread);
+ return 0;
+ }
+
+ int main() {
         boost::thread th1(bith::make_decorator(my_thread));
         boost::thread th2(bith::make_decorator(my_thread));
         sleep(2);
@@ -205,10 +211,6 @@
 [pre
 ]
 
- int main() {
- bith::wait_for_all(basic_threader_decorator, my_thread, my_thread);
- return 0;
- }
 
 [endsect]
 
@@ -218,9 +220,8 @@
 
 This example shows how to launch several algorithms and wait only for the more efficient.
 
- #include <boost/interthreads/thread_tuple_once.hpp>
- #include <boost/interthreads/thread_and_join.hpp>
- #include <boost/thread.hpp>
+ #include <boost/interthreads/typeof/threader.hpp>
+ #include <boost/interthreads/wait_for_any.hpp>
     #include <iostream>
         
     namespace bith = boost::interthreads;
@@ -236,8 +237,9 @@
     }
 
     int main() {
- unsigned res = bith::conc_join_any(basic_threader(), my_thread1, my_thread2);
- std::cout << "Algotithm " << res+1 << "finished the first" << std::endl;
+ bith::shared_threader ae;
+ BOOST_AUTO(res,bith::wait_for_any(ae, my_thread, my_thread));
+ std::cout << "Algotithm " << res.first+1 << " finished the first" << std::endl;
         return 0;
     }
 
@@ -246,10 +248,6 @@
 [pre
 ]
 
- int main() {
- std::pair<unsigned,void> res = bith::wait_for_any(launcher, my_thread, my_thread);
- return 0;
- }
 
 [endsect]
 

Modified: sandbox/interthreads/libs/interthreads/doc/implementation.qbk
==============================================================================
--- sandbox/interthreads/libs/interthreads/doc/implementation.qbk (original)
+++ sandbox/interthreads/libs/interthreads/doc/implementation.qbk 2009-01-14 12:49:38 EST (Wed, 14 Jan 2009)
@@ -1,5 +1,5 @@
 [/
- (C) Copyright 2008 Vicente J Botet Escriba.
+ (C) Copyright 2008-20009 Vicente J Botet Escriba.
   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).

Modified: sandbox/interthreads/libs/interthreads/doc/installation.qbk
==============================================================================
--- sandbox/interthreads/libs/interthreads/doc/installation.qbk (original)
+++ sandbox/interthreads/libs/interthreads/doc/installation.qbk 2009-01-14 12:49:38 EST (Wed, 14 Jan 2009)
@@ -1,5 +1,5 @@
 [/
- (C) Copyright 2008 Vicente J. Botet Escriba
+ (C) Copyright 2008-20009 Vicente J. Botet Escriba
   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).
@@ -35,19 +35,56 @@
 
 [variablelist
 [
- [[@http://www.boost.org/libs/thread [*Boost.Threads]]] [for thread, thread_specific_ptr, call_once, mutex, ...]
+ [[@http://www.boost.org/libs/array [*Boost.Array]]] [for array, ...]
 ]
 [
- [[@http://www.boost.org/libs/smart_ptr [*Boost.SmartPtr]]] [for shared_ptr, ...]
+ [[@http://www.boost.org/libs/bind [*Boost.Bind]]] [for bind, ...]
+]
+[
+ [[@http://www.boost.org/libs/config [*Boost.Config]]] [for ??? and abi_prefic_sufix, ...]
 ]
 [
     [[@http://www.boost.org/libs/function [*Boost.Function]]] [for function, ...]
 ]
 [
- [[@http://www.boost.org/libs/bind [*Boost.Bind]]] [for bind, ...]
+ [[@http://www.boost.org/libs/fusion [*Boost.Fusion]]] [for tuples, and sequence algorithms ...]
+]
+[
+ [[@http://www.boost.org/libs/mpl [*Boost.MPL]]] [for transform, ...]
 ]
 [
- [[@http://www.boost.org/libs [*Boost.Preprocesor]]] [to implement variadic thread_tuples, ...]
+ [[@http://www.boost.org/libs [*Boost.Preprocesor]]] [to simulate variadic templates , ...]
+]
+[
+ [[@http://www.boost.org/libs/smart_ptr [*Boost.SmartPtr]]] [for shared_ptr, ...]
+]
+[
+ [[@http://www.boost.org/libs/thread [*Boost.Threads]]] [for thread, thread_specific_ptr, call_once, mutex, ...]
+]
+[
+ [[@http://www.boost.org/libs/typeof [*Boost.TypeOf]]] [to register the ACT types.]
+]
+[
+ [[@http://www.boost.org/libs/type_traits [*Boost.TypeTrais]]] [for is_void, remove_references, ...]
+]
+[
+ [[@http://www.boost.org/libs [*Boost.Utility]]] [for result_of, enable_if...]
+]
+]
+
+In addition it depends on the following libraries that are not accepted yet on Boost
+[variablelist
+[
+ [[@http://www.boost.org/libs/chrono [*Boost.Chrono]]] [for time and duration]
+]
+[
+ [[@http://www.boost.org/libs/futures [*Boost.Futures]]] [for futures]
+]
+[
+ [[@http://www.boost.org/libs/move [*Boost.Move]]] [to emulate the move semantic.]
+]
+[
+ [[@http://www.boost.org/libs/tp [*Boost.ThreadPool]]] [for pool and task, whne you use the scheduler class]
 ]
 ]
 
@@ -63,11 +100,12 @@
 [/====================]
 
 All functions in the library are exception-safe except:
-
+To be completed:
 
 [/=======================]
 [heading Tested compilers]
 [/=======================]
+
 Currently, __Boost_InterThreads__ has been tested in the following compilers/platforms:
 
 * GCC 3.4.4 Cygwin

Modified: sandbox/interthreads/libs/interthreads/doc/interthreads.qbk
==============================================================================
--- sandbox/interthreads/libs/interthreads/doc/interthreads.qbk (original)
+++ sandbox/interthreads/libs/interthreads/doc/interthreads.qbk 2009-01-14 12:49:38 EST (Wed, 14 Jan 2009)
@@ -1,6 +1,6 @@
 [/
 [/
- (C) Copyright 2008 Vicente J. Botet Escriba
+ (C) Copyright 2008-20009 Vicente J. Botet Escriba
   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).
@@ -9,8 +9,9 @@
 [article InterThreads
     [quickbook 1.4]
     [authors [Botet Escriba, Vicente J.]]
- [copyright 2008 Vicente J. Botet Escriba]
+ [copyright 2008-20009 Vicente J. Botet Escriba]
     [purpose C++ Library extending the Boost.Thread library adding some inter threads mechanisms as
+ asynchronous executors and asyncronous completion tokes framework with threaders/joiners, launcher.
     thread decorator, specific shared pointers and keep alive mechanism]
     [category text]
     [license

Modified: sandbox/interthreads/libs/interthreads/doc/introduction.qbk
==============================================================================
--- sandbox/interthreads/libs/interthreads/doc/introduction.qbk (original)
+++ sandbox/interthreads/libs/interthreads/doc/introduction.qbk 2009-01-14 12:49:38 EST (Wed, 14 Jan 2009)
@@ -1,5 +1,5 @@
 [/
- (C) Copyright 2008 Vicente J Botet Escriba.
+ (C) Copyright 2008-20009 Vicente J Botet Escriba.
   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).
@@ -14,7 +14,8 @@
 [/=======================================================================]
 
 In [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1883.pdf N1833 - Preliminary Threading Library Proposal for TR2]
-Kevlin Henney introduce the concept of threader and a function thread that evaluate a function asynchronously and returns a joiner handle.
+Kevlin Henney introduce the concept of threader an asynchronous executor and a function thread that evaluate a function
+asynchronously and returns an asynchronous completion token joiner, able to join but also to to get the value of the function result.
 
 In [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2185.html N2185 - Proposed Text for Parallel Task Execution]
 Peter Dimov introduce a fork function able to evaluate a function asynchronously and
@@ -66,7 +67,7 @@
 
     template <typename AE, typename T>
     struct asynchronous_completion_token {
- typedef typename AE::handle<T>::type type;
+ typedef typename AE::template handle<T>::type type;
     };
 
 The result of forking a nullary function by an asynchronous executor is given by the metafunction result_of::fork<AE,F>
@@ -74,15 +75,15 @@
     namespace result_of {
         template <typename AE,typename F>
         struct fork {
- typedef typename asynchronous_completion_token<AE,
- typename result_of<F()>::type>::type type;
+ typedef typename boost::result_of<F()>::type result_type;
+ typedef typename asynchronous_completion_token<AE, result_type>::type type;
         };
     }
 
 The default implementation of fork delegates on fork asynchronous executor function.
 
     template< typename AE, typename F >
- result_of::fork<AE, F>::type fork( AE& ae, F fn ) {
+ typename result_of::fork<AE, F>::type fork( AE& ae, F fn ) {
         return ae.fork(fn);
     }
 
@@ -90,9 +91,9 @@
 
     template< typename AE, typename F, typename A1, ..., typename An >
     typename asynchronous_completion_token<AE,
- typename result_of<F(A1,..., An)>::type >::type
+ typename boost::result_of<F(A1,..., An)>::type >::type
     fork( AE& ae, F fn, A1 a1, ..., An an ) {
- return launcher.fork( bind( fn, a1, ..., an ) );
+ return ae.fork( bind( fn, a1, ..., an ) );
     }
 
 We can define a basic_threader which just returns a new thread as follows:
@@ -111,7 +112,7 @@
         }
     };
 
-The library includes a launcher class that creates a thread and returns a unique_future when forking.
+The library includes also a launcher class that creates a thread and returns a unique_future when forking
 
     class launcher {
     public:
@@ -122,7 +123,7 @@
         template <typename F>
         unique_future<typename result_of<F()>::type>
         fork(F f) {
- typedef typename result_of<F()>::type result_type;
+ typedef typename boost::result_of<F()>::type result_type;
             packaged_task<result_type> tsk(f);
             unique_future<result_type> res = tsk.get_future();
             thread th(boost::move(tsk));
@@ -130,6 +131,7 @@
         }
     };
 
+and a shared_launcher class that creates a thread and returns a shared_future when forking
 
 Given the sequential example:
 
@@ -172,14 +174,14 @@
 
 The library include also a threader class based on the Kevlin proposal:
 
- class threader {
+ class unique_threader {
     public:
         template <typename T>
         struct handle {
- typedef joiner<T> type;
+ typedef unique_joiner<T> type;
         };
         template <typename F>
- joiner<typename result_of<F()>::type>
+ unique_joiner<typename result_of<F()>::type>
         fork(F f) {
             typedef typename result_of<F()>::type result_type;
             return joiner<result_type>(f);
@@ -191,18 +193,56 @@
 the Boost.ThreadPool library. We need to specialize the template class
 asynchronous_completion_token
 
+ namespace boost { namespace interthreads {
+
     template <typename Channel, typename T>
     struct asynchronous_completion_token<boost::tp::pool<Channel>,T> {
         typedef boost::tp::task<T> type;
     };
+
+ }}
 
 and function fork function.
  
+ namespace boost { namespace interthreads {
+
     template< typename Channel, typename F >
     result_of::fork<boost::tp::pool<Channel>, F>::type
     fork<boost::tp::pool<Channel>,F>( boost::tp::pool<Channel>& ae, F fn ) {
         return ae.submit(fn);
     }
+ }
+ }
+
+As the preceding is ilegal in C++03 we need to use an auxiliary class to define the default behaviour of fork
+
+ namespace boost { namespace interthreads {
+ template< typename AE, typename F >
+ struct fork_aux {
+ static typename result_of::fork<AE,F>::type fork(AE& ae, F fn ) {
+ return ae.fork(fn);
+ }
+ };
+
+ template< typename AE, typename F >
+ typename result_of::fork<AE,F>::type
+ fork( AE& ae, F fn ) {
+ return fork_aux<AE,F>::fork(ae,fn);
+ }
+ }
+ }
+
+And specialize partially the fork_auc class
+
+ template< typename Channel, typename F >
+ struct fork_aux<boost::tp::pool<Channel>,F> {
+ typename result_of::fork<boost::tp::pool<Channel>, F>::type
+ fork( boost::tp::pool<Channel>& ae, F fn ) {
+ return ae.submit(fn);
+ }
+ };
+
+
 
 Note that the single fork function that needs specialization is the one taking a nullary
 function as parameter.
@@ -212,7 +252,7 @@
     template < typename AE>
     void do(AE& ae)
     {
- typedef bith::result_of::fork<AE, f, tuple<double, int> >::type auto_type;
+ typedef bith::result_of::fork<AE, int(*)(double, int) >::type auto_type;
         auto_type fm1 = bith::fork(ae, f, 1.0, 1000000 );
         auto_type fm2 = bith::fork(ae, f, 1.0, 5000000 );
         auto_type fm3 = bith::fork(ae, f, 2.2, 1000000 );
@@ -237,7 +277,7 @@
 
 The library allows also to fork several functions at the same time
 
- result_of::fork_all<AE, f, g, h>::type handles = bith::fork_all(ae, f, g, h);
+ result_of::fork_all<AE, int(*)(), int(*)(), int(*)()>::type handles = bith::fork_all(ae, f, g, h);
     std::cout << get<1>(res).get() - get<0>(res).get() + get<2>(res).get() << std::endl;
 
 
@@ -247,7 +287,7 @@
     bool b = fusion::none(handles, fct::interruption_requested());
 
 The asynchronous completion token models follows two interfaces, the thread interface and the
-unique_future interface.
+unique_/shared_future interface.
 
 To make common tasks easier the library provide some functors in the name space fct:
 for the thread interface as
@@ -280,8 +320,8 @@
         };
     }
 
-In addition the library provides some non member functions that are the result of applying a
-these functior to the tuple using a fusion algorithm:
+In addition the library provides some non member functions that are the result of applying
+these functors to the tuple using a fusion algorithm:
 
 * join_all
 * join_all_until
@@ -301,7 +341,7 @@
 Next follows how get_all is defined.
 
     template <typename MovableTuple>
- typename result_of::get_all<MovableTuple>::type
+ typename result_of::get_all<Sequence>::type
     get_all(Sequence& t) {
         return fusion::transform(t, fct::get());
     }
@@ -319,13 +359,13 @@
 
 So the user can do the following
 
- result_of::fork_all<AE, f, g, h>::type res = bith::fork_all(ae, f, g, h);
- result_of::get_all<result_of::fork_all<AE, f, g, h>::type>::type values
+ result_of::fork_all<AE, int(*)(), int(*)(), int(*)()>::type res = bith::fork_all(ae, f, g, h);
+ result_of::get_all<result_of::fork_all<AE, int(*)(), int(*)(), int(*)()>::type>::type values
         = bith::get_all(handles);
 
 or using a typedef
 
- typedef result_of::fork_all<AE, f, g, h>::type auto_type;
+ typedef result_of::fork_all<AE, int(*)(), int(*)(), int(*)()>::type auto_type;
     auto_type handles = bith::fork_all(ae, f, g, h);
     result_of::get_all<auto_type>::type values= bith::get_all(handles);
 
@@ -337,15 +377,29 @@
 Last but not least the library provides also some sugaring functions like
 wait_for_all that forks and wait for the result.
 
- result_of::wait_for_all<AE, f, g, h>::type res = bith::wait_for_all(ae, f, g, h);
+ result_of::wait_for_all<AE, int(*)(), int(*)(), int(*)()>::type res = bith::wait_for_all(ae, f, g, h);
     std::cout << get<1>(res) - get<0>(res) + get<2>(res) << std::endl;
 
 and wait_for_any which works with functions that return the same type or are convertible to the same type.
 
- result_of::wait_for_any<AE, f, g, h>::type res = bith::wait_for_any(ae, f, g, h);
+ result_of::wait_for_any<AE, int(*)(), int(*)(), int(*)()>::type res = bith::wait_for_any(ae, f, g, h);
     std::cout << "function " << res.first << " finshed first with result=" << res.second << std::endl;
 
-So the simple way to define a new AsynchronousExecutor is to define a class as
+The current implementation use the wait_for_any function so any AE must provide a way to get a
+unique|shared_future from its ACT.
+
+The library defines a functor allowing the user to specialize it
+
+ template <typename AE>
+ struct get_future {
+ template <typename T>
+ shared_future<T>& operator()(typename asynchronous_completion_token<AE,T>::type& act)
+ { return act.get_future(); }
+ };
+
+Future versions will use the set_once synchronization.
+
+Resuming a simple way to define a new AsynchronousExecutor is to define a class as
 
     struct AsynchronousExecutor {
         template <typename T>
@@ -366,132 +420,11 @@
 [section Threader/Joiner]
 [/=============================================================================]
 
-Boost.Threads does offer a
-starting point, and with only a few considerations and changes it is relatively
-easy to evolve to the design described below from it.
-
-Threading in Boost.Threads is currently based on the idea that a thread is
-identified with an object that launches it. This notion is somewhat confused by
-the idea that on destruction the thread object is destroyed but the thread is not
-- in other words the thread is not identified the thread object... except when it
-is.
-
-Another appropriate separation is the distinction between initialization and
-execution. These are significantly different concepts but they are conflated in
-the existing thread-launching interface: the constructor is responsible both for
-preparing the thread and launching it, which means that it is not possible for
-one piece of code to set up a thread and another to initiate it separately at its
-own discretion, e.g. thread pools. Separating the two roles into constructor and
-executor function clears up both the technical and the conceptual issue. The
-executor function can be reasonably expressed as an overloaded function-call
-operator, or a start function.
-
- void task();
- ...
- thread async_function;
- ...
- asynch_functiont(task);
-
-The separation also offers a simple and non-intrusive avenue for platform specific
-extension of how a thread is to execute: configuration details such as
-scheduling policy, stack size, security attributes, etc, can be added as
-parameters to t without intruding on the signatures of any other function in the
-threading interface:
-
- size_t stack_size = ...;
- security_attributes security(...);
- thread async_function(stack_size, security);
-
-The default constructor could be the feature standardized, and the Boost
-implementation could add additional constructors as appropriate.
-
-Given that the same configuration might be used to launch other threads, and
-given the identity confusion of a thread being an object except when it's not, we
-can consider the interface not to be the interface of a thread but to be the
-interface of a thread launcher, i.e. an executor. A thread initiator can submit
-zero-argument functions and function objects to an executor for execution:
-
- threader run;
- ...
- run(first_task);
- run(second_task);
-
-Boost.InterThreads offers several asynchronous executors types and variables, but as
-a concept an asynchronous executor could be implemented in a variety of ways that still
-conform to the same basic launching interface, i.e. the function-call operator..
-
-Given that a threader can be used to launch multiple threads, there is the
-obvious question of how to join with each separately run thread. Instead of
-returning void, the threader returns an object whose primary purpose is to
-represent the ability to join with the completion of a separately executing thread
-of control.
-
- joiner wait = run(first_task);
-
-The role played by the joiner in this fragment is that of an asynchronous
-completion token, a common pattern for synchronizing with and controlling
-asynchronous tasks. Via the joiner the initiator can poll or wait
-for the completion of the running thread, and control it in other ways, some of
-which may be platform specific extensions.
-
-joiner is Movable. Its principal action, the act of joining, can be expressed as a function
-call:
-joiner join = run(first_task);
-...
-join();
-
-If there are no joiners for a given thread, that thread is considered detached, a
-role currently played in Boost.Threads by the thread destructor:
-
- run(second_task); // runs detached because return value ignored
-
-Boost.Threads does
-not return a value from a completed thread when joined. For many threaded
-tasks this makes sense, but where a thread is working towards a result then the
-idea that an asynchronously executed function can return a value for later
-collection should not be discarded. With a void-returning interface the
-programmer is forced to set up an arrangement for the threaded task to
-communicate a value to the party that wants the one-time result. This is tedious
-for such a simple case, and can be readily catered for by making the joiner a
-proper future variable that proxies the result. This leads to the threader
-interface looking like the following:
-
- class threader
- {
- public:
- threader();
-
- template<typename nullary_function>
- joiner<result_of<nullary_function()>::type> operator()(nullary_function);
- ...
- };
-
-For the common default configured threader, a wrapper function, fork, can be
-provided:
-
- template<typename nullary_function>
- joiner<result_of<nullary_function>::type> fork(nullary_function);
-
-And use it as follows:
-
- void void_task();
- int int_task();
- ...
- joiner<void> t1 = fork(void_task);
- joiner<int> t2 = fork(int_task);
- ...
- int result = t1.get();
- t2.join();
-
-The benefit of programming with futures is that for a certain class of code that
-would use end-of-thread synchronization to pick up results, programmers are
-not presented with unnecessarily low-level synchronization APIs. The function based
-model is applied consistently.
-
-When the application needs only the result it seems interesting to return only
-the future value associated to the unary function result..
+See the [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1883.pdf N1833 - Preliminary Threading Library Proposal for TR2]
+where Kevlin Henney introduce the concept of threader an asynchronous executor and a function thread that evaluate a function
+asynchronously and returns an asynchronous completion token joiner, able to join but also to to get the value of the function result.
 
- unique_future<int> t3 = launch(int_task);
+The main specifcities is that here we make a difference between unique_joiner (move-only) and shared_joiner and as consequence unique_threader and shared_threader.
 
 
 [endsect]

Modified: sandbox/interthreads/libs/interthreads/doc/overview.qbk
==============================================================================
--- sandbox/interthreads/libs/interthreads/doc/overview.qbk (original)
+++ sandbox/interthreads/libs/interthreads/doc/overview.qbk 2009-01-14 12:49:38 EST (Wed, 14 Jan 2009)
@@ -1,5 +1,5 @@
 [/
- (C) Copyright 2008 Vicente J Botet Escriba.
+ (C) Copyright 2008-20009 Vicente J Botet Escriba.
   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).

Modified: sandbox/interthreads/libs/interthreads/doc/rationale.qbk
==============================================================================
--- sandbox/interthreads/libs/interthreads/doc/rationale.qbk (original)
+++ sandbox/interthreads/libs/interthreads/doc/rationale.qbk 2009-01-14 12:49:38 EST (Wed, 14 Jan 2009)
@@ -1,5 +1,5 @@
 [/
- (C) Copyright 2008 Vicente J Botet Escriba.
+ (C) Copyright 2008-20009 Vicente J Botet Escriba.
   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).

Modified: sandbox/interthreads/libs/interthreads/doc/reference.qbk
==============================================================================
--- sandbox/interthreads/libs/interthreads/doc/reference.qbk (original)
+++ sandbox/interthreads/libs/interthreads/doc/reference.qbk 2009-01-14 12:49:38 EST (Wed, 14 Jan 2009)
@@ -1,5 +1,5 @@
 [/
- (C) Copyright 2008 Vicente J Botet Escriba.
+ (C) Copyright 2008-20009 Vicente J Botet Escriba.
   (See accompanying file LICENSE_1_0.txt or copy at
   http://www.boost.org/LICENSE_1_0.txt).
 ]
@@ -292,6 +292,7 @@
 
 [variablelist
 [[Returns:] [The result of the AE::get().]]
+[[Throws:] [if AE::get() throws.]]
 ]
 
 [endsect]
@@ -339,9 +340,9 @@
 
 
 [variablelist
-[[Returns:] [a fusion tuple of the result of applying get to each one of the asynchronous executors handles in the sequence.]]
-[[Effect:] [Blocks until all the AE handles are ready.]]
-
+[[Returns:] [a fusion tuple of the result of applying `get` to each one of the asynchronous completion token handles in the sequence.]]
+[[Effect:] [Blocks until all the ACT handles in the Sequence are ready.]]
+[[Throws:] [if some of the ACT::get operation throws]]
 ]
 
 [endsect]
@@ -518,6 +519,7 @@
     namespace boost {
     namespace interthreads {
         class launcher;
+ class shared_launcher;
     }
     }
 
@@ -541,7 +543,7 @@
         fork(F f);
     };
 
-[section Member function `lancher::attributes`]
+[section Member function `launcher::attributes`]
 [/==========================================================================================]
 
 Reference to the thread attributes accesor.
@@ -594,6 +596,80 @@
 
 [endsect]
 
+[section Class `shared_launcher `]
+[/==========================================================================================]
+
+Thread shared_launcher using a common configuration managed with the thread attributes and
+returning on the fork operation a unique_future to the resulting type of the call to the threaded function.
+
+ class shared_launcher {
+ public:
+ thread::native_handle_attr_type& attr();
+
+ template <typename T>
+ struct handle {
+ typedef unique_future<T> > type;
+ };
+
+ template <typename F>
+ unique_future<typename result_of<F()>::type>
+ fork(F f);
+ };
+
+[section Member function `shared_launcher::attributes`]
+[/==========================================================================================]
+
+Reference to the thread attributes accesor.
+
+ thread::native_handle_attr_type& attributes();
+
+[variablelist
+[[Returns:] [A reference to the thread attributes.]]
+[[Complexity:] [constant.]]
+]
+
+
+[endsect]
+[section Metafunction `shared_launcher::handle<>`]
+[/==========================================================================================]
+
+Metafunction that returns the result type of the fork function applied to a shared_launcher and the value type.
+
+ template <typename T>
+ struct handle {
+ typedef unique_future<T> > type;
+ };
+
+[variablelist
+[[Expression:] [L::handle<T>::type]]
+[[Return type:] [A unique_future<T>.]]
+[[Complexity:] [constant.]]
+
+]
+
+[endsect]
+
+[section Member function `lancher::fork`]
+[/==========================================================================================]
+
+ template <typename F>
+ unique_future<typename result_of<F()>::type>
+ fork(F f);
+
+[variablelist
+[[Returns:] [A unique_future to the result of calling a function F.]]
+[[Effects:] [create a thread executing the function f.
+ The result of the function will be stored on the resulting future.]]
+
+]
+
+
+[endsect]
+
+
+[endsect]
+
+
 [endsect]
 
 [/==========================================================================================]
@@ -604,38 +680,411 @@
     namespace boost {
     namespace interthreads {
         template <typename ResultType>
- class joiner;
+ class unique_joiner;
 
         template <typename ResultType>
- void swap(joiner<ResultType>& lhs,joiner<ResultType>& rhs);
+ void swap(unique_joiner<ResultType>& lhs, unique_joiner<ResultType>& rhs);
+
+ class unique_threader;
+
+ template <typename ResultType>
+ class shared_joiner;
 
- class threader;
+ template <typename ResultType>
+ void swap(shared_joiner<ResultType>& lhs, shared_joiner<ResultType>& rhs);
+
+ class shared_threader;
     }
     }
 
 [/==================================================]
-[section Template Class `joiner`]
+[section Template Class `unique_joiner<>`]
+[/==========================================================================================]
+
+
+template <typename ResultType>
+class unique_joiner {
+ typedef unique_joiner this_type;
+public:
+ unique_joiner(const unique_joiner& rhs) = delete;
+ unique_joiner& operator=(const unique_joiner& rhs) = delete;
+
+ typedef ResultType result_type;
+
+ template <typename Nullary>
+ unique_joiner(thread::native_handle_attr_type& attr, Nullary f);
+ template <typename Nullary>
+ unique_joiner(Nullary f);
+
+ unique_joiner(boost::detail::thread_move_t<unique_joiner> x);
+ unique_joiner& operator=(boost::detail::thread_move_t<unique_joiner> x);
+ operator boost::detail::thread_move_t<unique_joiner>();
+ boost::detail::thread_move_t<unique_joiner> move();
+
+ void swap(this_type& x);
+
+ bool joinable() const;
+ void join();
+ bool join_until(const system_time& abs_time);
+ template<typename TimeDuration>
+ inline bool join_for(TimeDuration const& rel_time);
+
+ result_type get();
+ result_type operator()();
+
+ bool is_ready() const;
+ bool has_exception() const;
+ bool has_value() const;
+
+ void wait() const;
+ bool wait_until(const system_time& abs_time) const;
+ template<typename TimeDuration>
+ inline bool wait_for(TimeDuration const& rel_time) const;
+
+ thread::id get_id() const;
+ void detach();
+ void interrupt();
+ bool interruption_requested() const;
+
+ typedef platform-specific-type native_handle_type;
+ native_handle_type native_handle();
+
+ unique_future<result_type> get_future();
+
+};
+
+
+[section:destructor unique_joiner Destructor]
+[/==========================================================================================]
+
+ ~unique_joiner();
+
+[variablelist
+[[Effects:] [If `*this` has an associated thread of execution, calls __detach__. Destroys `*this`.]]
+[[Throws:] [Nothing.]]
+]
+
+[endsect]
+
+[section:swap Member function `swap()`]
+
+ void swap(unique_joiner& other);
+
+[variablelist
+[[Effects:] [Exchanges the threads of execution associated with `*this` and `other`, so `*this` is associated with the thread of
+execution associated with `other` prior to the call, and vice-versa.]]
+[[Postconditions:] [`this->get_id()` returns the same value as `other.get_id()` prior to the call. `other.get_id()` returns the same
+value as `this->get_id()` prior to the call.]]
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+
+[section Member Function `get()|operator()()`]
+[/==========================================================================================]
+
+ result_type get();
+ result_type operator()();
+
+[variablelist
+[[Effects:] [Retrieves the value returned by the Nullary function.]]
+[[Sychronization:][The completion of the call to the operator()() the Nullary function happens before get() returns.]]
+[[Returns:] [If the result type R is a reference, returns the stored reference.
+If R is void, there is no return value.
+Otherwise, returns an rvalue-reference to the value stored in the asynchronous result.]]
+[[Throws:] [the stored exception, if an exception was stored and not retrieved before.]]
+[[Postconditions:] [It is unspecified what happens when get() is called a second time on the same unique_joiner.]]
+[[Thread safety:][unsafe]]
+]
+[endsect]
+
+
+[section Member Function `is_ready()`]
+[/==========================================================================================]
+
+ bool is_ready() const;
+
+[variablelist
+[[Returns:] [true only if the associated state holds a value or an exception ready for retrieval.]]
+[[Remark:] [the return value is unspecified after a call to get().]]
+]
+[endsect]
+
+[section Member Function `has_exception()`]
+[/==========================================================================================]
+
+ bool has_exception() const;
+
+[variablelist
+[[Returns:] [true only if is_ready() == true and the associated state contains an exception.]]
+]
+[endsect]
+
+[section Member Function `has_value()`]
+[/==========================================================================================]
+
+ bool has_value() const;
+
+[variablelist
+[[Returns:] [true only if is_ready() == true and the associated state contains a value.]]
+]
+[endsect]
+
+[section Member Function `wait()`]
+[/==========================================================================================]
+
+ void wait();
+
+[variablelist
+[[Effects:] [Blocks until the Nullariry function ends.]]
+[[Sychronization:][The completion of the call to the operator()() the Nullary function happens before wait() returns.]]
+[[Throws:] [the stored exception, if an exception was stored and not retrieved before.]]
+[[Postconditions:] [is_ready() == true.]]
+[[Thread safety:][unsafe]]
+]
+[endsect]
+
+[section Member Function `wait_until()|wait_for()`]
+[/==========================================================================================]
+
+ bool wait_until(const system_time& abs_time);
+ template<typename TimeDuration>
+ bool wait_for(TimeDuration const& rel_time);
+
+
+[variablelist
+[[Effects:] [Blocks until the Nullariry function ends.]]
+[[Sychronization:][The completion of the call to the operator()() the Nullary function happens before wait() returns.]]
+[[Returns:] [If the result type R is a reference, returns the stored reference.
+If R is void, there is no return value.
+Otherwise, returns an rvalue-reference to the value stored in the asynchronous result.]]
+[[Throws:] [the stored exception, if an exception was stored and not retrieved before.]]
+[[Postconditions:] [is_ready() == true.]]
+[[Thread safety:][unsafe]]
+]
+[endsect]
+
+
+
+[section:joinable Member function `joinable()`]
+[/==========================================================================================]
+
+ bool joinable() const;
+
+[variablelist
+[[Returns:] [`true` if `*this` refers to a thread of execution, `false` otherwise.]]
+[[Throws:] [Nothing]]
+]
+
+[endsect]
+
+[section:join Member function `join()`]
+[/==========================================================================================]
+
+ void join();
+
+[variablelist
+[[Preconditions:] [`this->get_id()!=boost::this_thread::get_id()`]]
+[[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete.]]
+[[Postconditions:] [If `*this` refers to a thread of execution on entry, that thread of execution has completed. `*this` no longer refers to any thread of execution.]]
+[[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]
+[[Notes:] [`join()` is one of the predefined __interruption_points__.]]
+]
+
+[endsect]
+
+[section Member function `join_until()|join_for()`]
+[/==========================================================================================]
+
+ bool join_until(const system_time& wait_until);
+
+ template<typename TimeDuration>
+ bool join_for(TimeDuration const& rel_time);
+
+[variablelist
+[[Preconditions:] [`this->get_id()!=boost::this_thread::get_id()`]]
+[[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete, the time `wait_until` has
+been reach or the specified duration `rel_time` has elapsed. If `*this` doesn't refer to a thread of execution, returns immediately.]]
+[[Returns:] [`true` if `*this` refers to a thread of execution on entry, and that thread of execution has completed before the call
+times out, `false` otherwise.]]
+[[Postconditions:] [If `*this` refers to a thread of execution on entry, and `timed_join` returns `true`, that thread of execution
+has completed, and `*this` no longer refers to any thread of execution. If this call to `timed_join` returns `false`, `*this` is
+unchanged.]]
+[[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]
+[[Notes:] [`timed_join()` is one of the predefined __interruption_points__.]]
+]
+
+[endsect]
+
+[section:detach Member function `detach()`]
+[/==========================================================================================]
+
+ void detach();
+
+[variablelist
+[[Effects:] [If `*this` refers to a thread of execution, that thread of execution becomes detached, and no longer has an associated __thread__ object.]]
+[[Postconditions:] [`*this` no longer refers to any thread of execution.]]
+[[Throws:] [Nothing]]
+]
+
+[endsect]
+
+
+[section:get_id Member function `get_id()`]
+[/==========================================================================================]
+
+ thread::id get_id() const;
+
+[variablelist
+[[Returns:] [If `*this` refers to a thread of execution, an instance of __thread_id__ that represents that thread. Otherwise returns
+a default-constructed __thread_id__.]]
+[[Throws:] [Nothing]]
+]
+
+[endsect]
+
+[section:interrupt Member function `interrupt()`]
+[/==========================================================================================]
+
+ void interrupt();
+
+[variablelist
+[[Effects:] [If `*this` refers to a thread of execution, request that the thread will be interrupted the next time it enters one of
+the predefined __interruption_points__ with interruption enabled, or if it is currently __blocked__ in a call to one of the
+predefined __interruption_points__ with interruption enabled .]]
+[[Throws:] [Nothing]]
+]
+
+
+[endsect]
+
+
+[section:nativehandle Member function `native_handle()`]
+[/==========================================================================================]
+
+ typedef platform-specific-type native_handle_type;
+ native_handle_type native_handle();
+
+[variablelist
+[[Effects:] [Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying
+implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.]]
+[[Throws:] [Nothing.]]
+]
+
+[endsect]
+
+
+
+[endsect]
+[section:non_member_swap Non-member function `swap()`]
+
+ void swap(unique_joiner& lhs,unique_joiner& rhs);
+
+[variablelist
+
+[[Effects:] [[link thread.thread_management.thread.swap `lhs.swap(rhs)`].]]
+
+]
+
+[endsect]
+
+[/==================================================]
+[section Template Class `unique_threader`]
+[/==========================================================================================]
+
+ class unique_threader {
+ public:
+ thread::native_handle_attr_type& attributes();
+
+ template <typename T>
+ struct handle {
+ typedef unique_joiner<T> type;
+ };
+
+ template <typename F>
+ unique_joiner<typename result_of<F()>::type>
+ fork(F f);
+
+ };
+
+[section Member function `unique_threader::attributes()`]
+[/==========================================================================================]
+
+Reference to the thread attributes accesor.
+
+ thread::native_handle_attr_type& attributes();
+
+[variablelist
+[[Returns:] [A reference to the thread attributes.]]
+[[Complexity:] [constant.]]
+]
+
+
+[endsect]
+[section Metafunction `unique_threader::handle<>`]
+[/==========================================================================================]
+
+Metafunction that returns the result type of the fork function applied to a unique_threader and the value type.
+
+ template <typename T>
+ struct handle {
+ typedef unique_joiner<T> type;
+ };
+
+
+[variablelist
+[[Expression:] [L::handle<T>::type]]
+[[Return type:] [A unique_joiner<T>.]]
+[[Complexity:] [constant.]]
+
+]
+
+[endsect]
+
+[section Member function `unique_threader::fork`]
+[/==========================================================================================]
+
+ template <typename F>
+ unique_joiner<typename result_of<F()>::type>
+ fork(F f);
+
+[variablelist
+[[Returns:] [A unique_joiner to the result of calling a function F.]]
+[[Effects:] [create a thread executing the function f.
+ The result of the function will be stored on the resulting unique_joiner.]]
+
+]
+
+
+[endsect]
+
+[endsect]
+
+[/==================================================]
+[section Template Class `shared_joiner<>`]
 [/==========================================================================================]
 
 
 template <typename ResultType>
-class joiner {
- typedef joiner this_type;
+class shared_joiner {
+ typedef shared_joiner this_type;
 public:
- joiner(const joiner& rhs) = delete;
- joiner& operator=(const joiner& rhs) = delete;
+ shared_joiner(const shared_joiner& rhs);
+ shared_joiner& operator=(const shared_joiner& rhs);
 
     typedef ResultType result_type;
 
     template <typename Nullary>
- joiner(thread::native_handle_attr_type& attr, Nullary f);
+ shared_joiner(thread::native_handle_attr_type& attr, Nullary f);
     template <typename Nullary>
- joiner(Nullary f);
+ shared_joiner(Nullary f);
 
- joiner(boost::detail::thread_move_t<joiner> x);
- joiner& operator=(boost::detail::thread_move_t<joiner> x);
- operator boost::detail::thread_move_t<joiner>();
- boost::detail::thread_move_t<joiner> move();
+ shared_joiner(boost::detail::thread_move_t<shared_joiner> x);
+ shared_joiner& operator=(boost::detail::thread_move_t<shared_joiner> x);
+ operator boost::detail::thread_move_t<shared_joiner>();
+ boost::detail::thread_move_t<shared_joiner> move();
        
     void swap(this_type& x);
         
@@ -665,13 +1114,14 @@
     typedef platform-specific-type native_handle_type;
     native_handle_type native_handle();
 
+ shared_future<result_type> get_future();
 };
 
 
-[section:destructor Joiner Destructor]
+[section:destructor shared_joiner Destructor]
 [/==========================================================================================]
 
- ~joiner();
+ ~shared_joiner();
 
 [variablelist
 [[Effects:] [If `*this` has an associated thread of execution, calls __detach__. Destroys `*this`.]]
@@ -682,7 +1132,7 @@
 
 [section:swap Member function `swap()`]
 
- void swap(joiner& other);
+ void swap(shared_joiner& other);
 
 [variablelist
 [[Effects:] [Exchanges the threads of execution associated with `*this` and `other`, so `*this` is associated with the thread of
@@ -709,7 +1159,7 @@
 If R is void, there is no return value.
 Otherwise, returns an rvalue-reference to the value stored in the asynchronous result.]]
 [[Throws:] [the stored exception, if an exception was stored and not retrieved before.]]
-[[Postconditions:] [It is unspecified what happens when get() is called a second time on the same joiner.]]
+[[Postconditions:] [It is unspecified what happens when get() is called a second time on the same shared_joiner.]]
 [[Thread safety:][unsafe]]
 ]
 [endsect]
@@ -894,7 +1344,7 @@
 [endsect]
 [section:non_member_swap Non-member function `swap()`]
 
- void swap(joiner& lhs,joiner& rhs);
+ void swap(shared_joiner& lhs,shared_joiner& rhs);
 
 [variablelist
 
@@ -905,25 +1355,25 @@
 [endsect]
 
 [/==================================================]
-[section Template Class `threader`]
+[section Template Class `shared_threader`]
 [/==========================================================================================]
 
- class threader {
+ class shared_threader {
     public:
         thread::native_handle_attr_type& attributes();
 
         template <typename T>
         struct handle {
- typedef joiner<T> type;
+ typedef shared_joiner<T> type;
         };
 
         template <typename F>
- joiner<typename result_of<F()>::type>
+ shared_joiner<typename result_of<F()>::type>
         fork(F f);
 
     };
 
-[section Member function `threader::attributes()`]
+[section Member function `shared_threader::attributes()`]
 [/==========================================================================================]
 
 Reference to the thread attributes accesor.
@@ -937,37 +1387,37 @@
 
 
 [endsect]
-[section Metafunction `threader::handle<>`]
+[section Metafunction `shared_threader::handle<>`]
 [/==========================================================================================]
 
-Metafunction that returns the result type of the fork function applied to a threader and the value type.
+Metafunction that returns the result type of the fork function applied to a shared_threader and the value type.
 
         template <typename T>
         struct handle {
- typedef joiner<T> type;
+ typedef shared_joiner<T> type;
         };
 
 
 [variablelist
 [[Expression:] [L::handle<T>::type]]
-[[Return type:] [A joiner<T>.]]
+[[Return type:] [A shared_joiner<T>.]]
 [[Complexity:] [constant.]]
 
 ]
 
 [endsect]
 
-[section Member function `threader::fork`]
+[section Member function `shared_threader::fork`]
 [/==========================================================================================]
 
         template <typename F>
- joiner<typename result_of<F()>::type>
+ shared_joiner<typename result_of<F()>::type>
         fork(F f);
 
 [variablelist
-[[Returns:] [A joiner to the result of calling a function F.]]
+[[Returns:] [A shared_joiner to the result of calling a function F.]]
 [[Effects:] [create a thread executing the function f.
- The result of the function will be stored on the resulting joiner.]]
+ The result of the function will be stored on the resulting shared_joiner.]]
 
 ]
 
@@ -2767,5 +3217,4 @@
 [endsect]
 
 
-
 [endsect]

Modified: sandbox/interthreads/libs/interthreads/doc/tutorial.qbk
==============================================================================
--- sandbox/interthreads/libs/interthreads/doc/tutorial.qbk (original)
+++ sandbox/interthreads/libs/interthreads/doc/tutorial.qbk 2009-01-14 12:49:38 EST (Wed, 14 Jan 2009)
@@ -1,5 +1,5 @@
 [/
- (C) Copyright 2008 Vicente J Botet Escriba.
+ (C) Copyright 2008-20009 Vicente J Botet Escriba.
   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).

Modified: sandbox/interthreads/libs/interthreads/doc/users_guide.qbk
==============================================================================
--- sandbox/interthreads/libs/interthreads/doc/users_guide.qbk (original)
+++ sandbox/interthreads/libs/interthreads/doc/users_guide.qbk 2009-01-14 12:49:38 EST (Wed, 14 Jan 2009)
@@ -1,6 +1,6 @@
 [/
 [/
- (C) Copyright 2008 Vicente J. Botet Escriba
+ (C) Copyright 2008-20009 Vicente J. Botet Escriba
   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).
@@ -33,6 +33,8 @@
 
 [variablelist
 
+[[AE] [Asynchronous executor]]
+[[ACT] [Asynchronous completion token]]
 [[alive (thread)] [a thread is considered alive when not dead.]]
 [[cleanup decoration] [function called at thread exit.]]
 [[dead (thread)] [a thread is considered dead when has not done enough keep alive check points for a given duration.]]


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