|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r53690 - in sandbox/rendez_vous: boost boost/rendez_vous boost/rendez_vous/detail libs libs/rendez_vous libs/rendez_vous/doc libs/rendez_vous/doc/reference libs/rendez_vous/doc/tutorial libs/rendez_vous/example libs/rendez_vous/test
From: vicente.botet_at_[hidden]
Date: 2009-06-06 10:35:31
Author: viboes
Date: 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
New Revision: 53690
URL: http://svn.boost.org/trac/boost/changeset/53690
Log:
TBoost.RendezVous v0.1
Added:
sandbox/rendez_vous/boost/
sandbox/rendez_vous/boost/rendez_vous/
sandbox/rendez_vous/boost/rendez_vous/conc_tuple.hpp (contents, props changed)
sandbox/rendez_vous/boost/rendez_vous/concurrent_component.hpp (contents, props changed)
sandbox/rendez_vous/boost/rendez_vous/detail/
sandbox/rendez_vous/libs/
sandbox/rendez_vous/libs/rendez_vous/
sandbox/rendez_vous/libs/rendez_vous/doc/
sandbox/rendez_vous/libs/rendez_vous/doc/Jamfile.v2 (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/acknowledgements.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/appendices.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/case_studies.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/getting_started.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/history.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/implementation.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/index.html (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/installation.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/introduction.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/overview.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/rationale.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/reference/
sandbox/rendez_vous/libs/rendez_vous/doc/reference.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/reference/concurrent_component.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/references.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/rendez_vous.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/tests.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/tickets.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/tutorial/
sandbox/rendez_vous/libs/rendez_vous/doc/tutorial.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/tutorial/rendezvous.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/doc/users_guide.qbk (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/example/
sandbox/rendez_vous/libs/rendez_vous/example/Histogram.cpp (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/example/HotelReservation.cpp (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/example/Master_Slave.cpp (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/example/QualifiedSingleBuf.cpp (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/example/SingleBuf.cpp (contents, props changed)
sandbox/rendez_vous/libs/rendez_vous/test/
sandbox/rendez_vous/libs/rendez_vous/test/Jamfile.v2 (contents, props changed)
Added: sandbox/rendez_vous/boost/rendez_vous/conc_tuple.hpp
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/boost/rendez_vous/conc_tuple.hpp 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,190 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-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)
+//
+// See http://www.boost.org/libs/rendez_vous for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_RENDEZ_VOUS_CONC_TUPLE__HPP
+#define BOOST_RENDEZ_VOUS_CONC_TUPLE__HPP
+
+#include <boost/thread.hpp>
+#include <boost/ref.hpp>
+#include <boost/bind.hpp>
+
+namespace boost { namespace rendez_vous {
+struct none{};
+#if BOOST_HAS_VARIADIC_TMPl
+template <
+ typename S...
+>
+struct conc_tuple;
+
+template <
+ typename Head, Tail...
+>
+struct conc_tuple;
+{
+ Head& head_;
+ boost::thread thr_head_;
+ conc_tuple<Tail> tail_;
+public:
+ conc_tuple(Head& head, Tail... tail) : head_(head), tail_(...tail) {};
+ void operator()() {
+ head_();
+ tail_();
+ }
+ void join() {
+ thr_head_.join();
+ tail_.join();
+ }
+ void interrupt() {
+ thr_head_.interrupt();
+ tail_.interrupt();
+ }
+ int size() const {return 1;}
+};
+#endif
+
+//[conc_tuple
+template <
+ typename S1
+>
+struct conc_tuple_1 {
+// BOOST_CONCEPT_ASSERT((ConcurrentComponentConcept<S1>));
+ S1& s1_;
+ boost::thread thr1_;
+public:
+ conc_tuple_1(S1& s1) : s1_(s1) {};
+ void operator()() {
+ thr1_= boost::thread(boost::ref(s1_));
+ }
+ void join() {
+ thr1_.join();
+ }
+ void interrupt() {
+ thr1_.interrupt();
+ }
+ int size() const {return 1;}
+};
+
+template <
+ typename S1,
+ typename S2
+>
+struct conc_tuple_2 {
+// BOOST_CONCEPT_ASSERT((ConcurrentComponentConcept<S1>));
+ conc_tuple_1<S1> s1_;
+ conc_tuple_1<S2> s2_;
+// S1& s1_; S2& s2_;
+// boost::thread thr1_;
+// boost::thread thr2_;
+public:
+ conc_tuple_2(S1& s1, S2& s2) : s1_(s1), s2_(s2) {};
+ void operator()() {
+ s1_();
+ s2_();
+ }
+ void join() {
+ s1_.join();
+ s2_.join();
+ }
+ void interrupt() {
+ s1_.interrupt();
+ s2_.interrupt();
+ }
+ int size() const {return 2;}
+};
+template <
+ typename S1,
+ typename S2,
+ typename S3
+>
+struct conc_tuple_3 {
+ conc_tuple_1<S1> s1_;
+ conc_tuple_2<S2, S3> s23_;
+public:
+ conc_tuple_3(S1& s1, S2& s2, S3& s3) : s1_(s1), s23_(s2, s3) {};
+ void operator()() {
+ s1_();
+ s23_();
+ }
+ void join() {
+ s1_.join();
+ s23_.join();
+ }
+ void interrupt() {
+ s1_.interrupt();
+ s23_.interrupt();
+ }
+ int size() const {return 3;}
+};
+template <
+ typename S1,
+ typename S2,
+ typename S3,
+ typename S4
+>
+struct conc_tuple_4 {
+ conc_tuple_2<S1, S2> s12_;
+ conc_tuple_2<S3, S4> s34_;
+public:
+ conc_tuple_4(S1& s1, S2& s2, S3& s3, S4& s4) : s12_(s1, s2), s34_(s3, s4) {};
+ void operator()() {
+ s12_();
+ s34_();
+ }
+ void join() {
+ s12_.join();
+ s34_.join();
+ }
+ void interrupt() {
+ s12_.interrupt();
+ s34_.interrupt();
+ }
+ int size() const {return 4;}
+};
+//]
+
+template <
+ typename S1,
+ typename S2,
+ typename S3=none,
+ typename S4=none,
+ typename S5=none
+>
+struct conc_tuple;
+
+template <
+ typename S1,
+ typename S2,
+ typename S3,
+ typename S4
+>
+struct conc_tuple<S1, S2, S3, S4, none> : conc_tuple_4<S1, S2, S3, S4> {
+ conc_tuple(S1& s1, S2& s2, S3& s3, S4& s4) : conc_tuple_4<S1, S2, S3, S4>(s1, s2, s3, s4) {};
+};
+
+template <
+ typename S1,
+ typename S2,
+ typename S3
+>
+struct conc_tuple<S1, S2, S3, none, none> : conc_tuple_3<S1, S2, S3>{
+ conc_tuple(S1& s1, S2& s2, S3& s3) : conc_tuple_3<S1, S2, S3>(s1, s2, s3) {};
+};
+
+template <
+ typename S1,
+ typename S2
+>
+struct conc_tuple<S1, S2, none, none, none> : conc_tuple_2<S1, S2>{
+ conc_tuple(S1& s1, S2& s2) : conc_tuple_2<S1, S2>(s1, s2) {};
+};
+
+}
+}
+#endif
Added: sandbox/rendez_vous/boost/rendez_vous/concurrent_component.hpp
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/boost/rendez_vous/concurrent_component.hpp 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,284 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-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)
+//
+// See http://www.boost.org/libs/rendez_vous for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_RENDEZ_VOUS_CONC_SYSTEM__HPP
+#define BOOST_RENDEZ_VOUS_CONC_SYSTEM__HPP
+
+#include <boost/synchro/semaphore.hpp>
+#include <boost/bind.hpp>
+#include <boost/ref.hpp>
+#include <typeinfo>
+
+namespace boost { namespace rendez_vous {
+
+struct concurrent_component_base {};
+struct bad_sender {};
+struct bad_type {};
+
+
+namespace detail {
+template <typename T>
+class concurrent_component_synchro
+{
+public:
+ concurrent_component_synchro()
+ : signaled_(false)
+ {
+ }
+
+ T wait()
+ {
+ boost::mutex::scoped_lock lock(mutex_);
+ cond_.wait(lock);
+ return val_;
+ }
+
+ bool post(T val)
+ {
+ boost::mutex::scoped_lock lock(mutex_);
+ if (!signaled_) { /*< first post assigns the current thread id >*/
+ signaled_=true;
+ val_ = val;
+ cond_.notify_one();
+ return true;
+ } else { /*< the other post do nothing >*/
+ return false;
+ }
+ }
+ void clear()
+ {
+ boost::mutex::scoped_lock lock(mutex_);
+ signaled_=false;
+ }
+
+private:
+ mutex mutex_;
+ condition_variable cond_;
+ bool signaled_;
+ T val_;
+};
+}
+
+class concurrent_component : public concurrent_component_base {
+protected:
+//[port
+ struct port {
+ friend class concurrent_component;
+ port() : accept_call_(0), until_end_(0) {
+ }
+ ~port() {
+ }
+ struct synchronizer {
+ port& that_;
+ synchronizer(port& that) : that_(that) {
+#if 0
+ for (;;) {
+ that.accept_call_.wait();
+ if (that_.common_.post(1, that.accept_call_)) break;
+ that.accept_call_.post();
+ }
+#else
+ that.accept_call_.wait();
+#endif
+ }
+ ~synchronizer() {
+ that_.until_end_.post();
+ }
+ };
+ private:
+ void accept() {
+ accept_call_.post();
+ until_end_.wait();
+ }
+#if 0
+ void accept_one(port& common) {
+ common_ = &common;
+ }
+#endif
+ void accept_begin() {
+ accept_call_.post();
+ }
+ void accept_end() {
+ until_end_.wait();
+ }
+
+#if 0
+ bool accept(const boost::posix_time::ptime &abs_time) {
+ accept_call_.post();
+ this_thread::sleep(abs_time);
+ if (accept_call_.try_wait()) return false;
+ until_end_.wait();
+ return true;
+ }
+
+ static void accept(port& p, const boost::posix_time::ptime &abs_time) {
+ p.accept(abs_time);
+ }
+#endif
+ synchro::semaphore accept_call_;
+ synchro::semaphore until_end_;
+ };
+ static void accept(port& p) {
+// accept_call_.common_.post(1);
+ p.accept();
+ }
+ static void accept(port& p1, port& p2) {
+ p1.accept_begin();
+ p2.accept_begin();
+// p1.accept_call_.common_.wait();
+ p1.accept_end();
+ p2.accept_end();
+ }
+#if 0
+
+ static void accept_one(port& p1, port& p2) {
+ }
+#endif
+//]
+//[object_port
+ struct object_port {
+ friend class concurrent_component;
+ object_port() : accept_call_(0), until_end_(0) {
+ }
+ ~object_port() {
+ }
+ struct synchronizer {
+ object_port& that_;
+ synchronizer(object_port& that, const concurrent_component_base* snd) : that_(that) {
+ if (snd!= that_.sender_) {
+// std::cout<<"bad_sender "<<snd << "!="<< that_.sender_<< std::endl;
+ throw bad_sender();
+ }
+ that.accept_call_.wait();
+ }
+ ~synchronizer() {
+ that_.until_end_.post();
+ }
+ };
+ private:
+ void accept(const concurrent_component_base* snd) {
+ sender_=snd;
+ accept_call_.post();
+ until_end_.wait();
+ }
+ synchro::semaphore accept_call_;
+ synchro::semaphore until_end_;
+ const concurrent_component_base* sender_;
+ };
+ static void accept(object_port& that, const concurrent_component_base* snd) {
+ that.accept(snd);
+ }
+ static void accept_from(object_port& that, const concurrent_component_base* snd) {
+ that.accept(snd);
+ }
+//]
+//[qualified_port
+ template <typename TYPE>
+ struct qualified_port {
+ friend class concurrent_component;
+ qualified_port() : accept_call_(0), until_end_(0){
+ }
+ ~qualified_port() {
+ }
+ struct synchronizer {
+ qualified_port& that_;
+ synchronizer(qualified_port& that, const TYPE* snd) : that_(that) {
+ that.accept_call_.wait();
+ }
+ ~synchronizer() {
+ that_.until_end_.post();
+ }
+ };
+ private:
+ void accept() {
+// type_=&typeid(*snd);
+ accept_call_.post();
+ until_end_.wait();
+ }
+// static void accept(object_port& that, const concurrent_component_base* snd) {
+// that.accept(snd);
+// }
+ synchro::semaphore accept_call_;
+ synchro::semaphore until_end_;
+// const std::type_info* type_;
+ };
+ template <typename TYPE>
+ static void accept(qualified_port<TYPE>& that) {
+ that.accept();
+ }
+//]
+};
+#if EXAMPLES
+//[synchronized_communication_between_components_schema
+class R;
+class S : concurrent_component<> {
+public:
+ S(R& r);
+ void operator()()
+ {
+ // ...
+ e2 = r_.m(e1);
+ }
+};
+
+class R : concurrent_component<> {
+public:
+ void m() {
+ // ...
+ }
+ void operator()()
+ {
+ // ...
+ }
+};
+//]
+//[synchronized_communication_between_components
+class R;
+class S : concurrent_component<> {
+public:
+ S(R& r);
+ void operator()()
+ {
+ // ...
+ e2 = r_.m(e1);
+ }
+};
+
+class R : concurrent_component<> {
+ port p;
+public:
+ void m() {
+ port::synchronizer _(p);
+ // ...
+ }
+ void operator()()
+ {
+ // ...
+ port::accept(p);
+ }
+};
+//]
+#endif
+}
+#if 0
+namespace async {
+namespace partial_specialization_workaround {
+template< typename AE, typename CC >
+struct fork<AE,CC&> {
+ static typename result_of::fork<AE,CC>::type
+ apply(AE& ae, CC& cc ) {
+ return ae.fork(boost::bind(boost::ref(cc)));
+ }
+};
+}
+}
+#endif
+}
+#endif
Added: sandbox/rendez_vous/libs/rendez_vous/doc/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/Jamfile.v2 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,72 @@
+# Boost.LUID library documentation Jamfile ---------------------------------
+#
+# Copyright Vicente J. Botet Escriba 2008. Use, modification and
+# distribution is subject to 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)
+#
+# See http://www.boost.org for updates, documentation, and revision history.
+
+#import doxygen ;
+import quickbook ;
+
+#doxygen autodoc
+# :
+# [ glob ../../../boost/interprocess/*.hpp ]
+# [ glob ../../../boost/interprocess/allocators/*.hpp ]
+# :
+# <doxygen:param>EXTRACT_ALL=NO
+# <doxygen:param>HIDE_UNDOC_MEMBERS=YES
+# <doxygen:param>EXTRACT_PRIVATE=NO
+# <doxygen:param>EXPAND_ONLY_PREDEF=YES
+# <doxygen:param>PREDEFINED=BOOST_INTERPROCESS_DOXYGEN_INVOKED
+# <xsl:param>"boost.doxygen.reftitle=Boost.Interprocess Reference"
+# ;
+
+xml rendez_vous : rendez_vous.qbk ;
+
+boostbook standalone
+ :
+ rendez_vous
+ :
+ # HTML options first:
+ # Use graphics not text for navigation:
+ <xsl:param>navig.graphics=1
+ # How far down we chunk nested sections, basically all of them:
+ <xsl:param>chunk.section.depth=2
+ # Don't put the first section on the same page as the TOC:
+ <xsl:param>chunk.first.sections=1
+ # How far down sections get TOC's
+ <xsl:param>toc.section.depth=4
+ # Max depth in each TOC:
+ <xsl:param>toc.max.depth=2
+ # How far down we go with TOC's
+ <xsl:param>generate.section.toc.level=10
+ # Path for links to Boost:
+ <xsl:param>boost.root=../../../..
+ # Path for libraries index:
+ <xsl:param>boost.libraries=../../../../libs/libraries.htm
+ # Use the main Boost stylesheet:
+ <xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
+
+ # PDF Options:
+ # TOC Generation: this is needed for FOP-0.9 and later:
+ #<xsl:param>fop1.extensions=1
+ # Or enable this if you're using XEP:
+ <xsl:param>xep.extensions=1
+ # TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9!
+ <xsl:param>fop.extensions=0
+ # No indent on body text:
+ <xsl:param>body.start.indent=0pt
+ # Margin size:
+ <xsl:param>page.margin.inner=0.5in
+ # Margin size:
+ <xsl:param>page.margin.outer=0.5in
+ # Yes, we want graphics for admonishments:
+ <xsl:param>admon.graphics=1
+ # Set this one for PDF generation *only*:
+ # default pnd graphics are awful in PDF form,
+ # better use SVG's instead:
+ <format>pdf:<xsl:param>admon.graphics.extension=".svg"
+ <format>pdf:<xsl:param>admon.graphics.path=$(boost-images)/
+ ;
Added: sandbox/rendez_vous/libs/rendez_vous/doc/acknowledgements.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/acknowledgements.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,12 @@
+[/
+ / Copyright (c) 2008 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)
+ /]
+
+[section:acknowledgements Appendix D: Acknowledgements]
+
+TBC
+
+[endsect]
Added: sandbox/rendez_vous/libs/rendez_vous/doc/appendices.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/appendices.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,38 @@
+[/
+[/
+ (C) Copyright 2008 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).
+]
+
+[/=================]
+[section Appendices]
+[/=================]
+
+[include history.qbk]
+
+[include rationale.qbk]
+
+[include implementation.qbk]
+
+[include acknowledgements.qbk]
+
+[include tests.qbk]
+
+[include tickets.qbk]
+
+
+[/=====================================]
+[section:todo Appendix E: Future plans]
+[/=====================================]
+
+[heading Tasks to do before review]
+
+
+[heading For later releases]
+
+[endsect]
+
+[endsect]
+
Added: sandbox/rendez_vous/libs/rendez_vous/doc/case_studies.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/case_studies.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,15 @@
+[/
+ (C) Copyright 2008 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).
+]
+
+[/============================]
+[section Examples]
+[/============================]
+
+This section includes complete examples using the library.
+
+
+[endsect]
\ No newline at end of file
Added: sandbox/rendez_vous/libs/rendez_vous/doc/getting_started.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/getting_started.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,25 @@
+[/
+[/
+ (C) Copyright 2008 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).
+]
+
+
+[/======================================]
+[section:getting_started Getting Started]
+[/======================================]
+
+[include installation.qbk]
+
+[/=============================]
+[section Hello World! ]
+[/=============================]
+
+
+[endsect]
+
+[endsect]
+
+
Added: sandbox/rendez_vous/libs/rendez_vous/doc/history.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/history.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,19 @@
+[/
+ / Copyright (c) 2008 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)
+ /]
+
+[section:history Appendix A: History]
+
+[section [*Version 0.1.0, may 24, 2009] ['Announcement of Rendez-Vous]]
+
+[*Features:]
+
+* High-level abstractions for handling more complicated synchronization problems, including
+ * a so-called rendezvous mechanism for handling direct communication between objects `concurrent_components` via `ports` using an accept-synchronize protocol based on the design of the concurrency library in the Beta language.
+
+
+[endsect]
+[endsect]
Added: sandbox/rendez_vous/libs/rendez_vous/doc/implementation.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/implementation.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,14 @@
+[/
+ / Copyright (c) 2008 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)
+ /]
+
+[section:implementation Appendix C: Implementation Notes]
+
+
+TBC
+
+
+[endsect]
Added: sandbox/rendez_vous/libs/rendez_vous/doc/index.html
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/index.html 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,9 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=html/index.html">
+</head>
+<body>
+Automatic redirection failed, please go to
+../../doc/html/rendez_vous.html
+</body>
+</html>
Added: sandbox/rendez_vous/libs/rendez_vous/doc/installation.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/installation.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,82 @@
+[/
+ (C) Copyright 2008 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).
+]
+
+
+[/======================================]
+[section:install Installing Rendez-Vous]
+[/======================================]
+
+[/=================================]
+[heading Getting Boost.Rendez-Vous]
+[/=================================]
+
+You can get the last stable release of Boost.Rendez-Vous by downloading [^rendez_vous.zip] from the
+[@http://www.boost-consulting.com/vault/index.php?directory=Concurrent%20Programming Boost Vault]
+
+You can also access the latest (unstable?) state from the [@https://svn.boost.org/svn/boost/sandbox/rendez_vous Boost Sandbox].
+
+[/=================================]
+[heading Building Boost.Rendez-Vous]
+[/=================================]
+
+There is no need to compile [*Boost.Rendez-Vous], since it's
+a header only library. Just include your Boost header directory in your
+compiler include path.
+
+[/=========================]
+[heading Requirements]
+[/=========================]
+
+[*Boost.Rendez-Vous] depends on Boost. You must use either Boost version 1.38.x
+or the version in SVN trunk (even if Boost version 1.35.x should works also).
+In particular, [*Boost.Rendez-Vous] depends on:
+
+
+[variablelist
+[
+ [[@http://www.boost.org/libs/interprocess [*Boost.Interprocess]]]
+ [interprocess synchronization primitives]
+]
+[
+ [[@http://www.boost.org/libs/mpl [*Boost.MPL]]]
+ [for all the meta programing task]
+]
+[
+ [[@http://www.boost.org/libs/thread [*Boost.Thread]]]
+ [thread synchronization primitives]
+]
+]
+
+
+[/========================]
+[heading Exceptions safety]
+[/========================]
+
+All functions in the library are exception-neutral and provide strong guarantee of exception safety as long as
+the underlying parameters provide it.
+
+[/====================]
+[heading Thread safety]
+[/====================]
+
+All functions in the library are thread-unsafe except when noted explicitly.
+
+
+[/=======================]
+[heading Tested compilers]
+[/=======================]
+Currently, [*Boost.Rendez-Vous] has been tested in the following compilers/platforms:
+
+* GCC 3.4.4 Cygwin
+* GCC 3.4.6 Linux
+[/* GCC 4.3.2 Cygwin]
+* GCC 4.1.2 Linux
+
+[note Please send any questions, comments and bug reports to boost <at> lists <dot> boost <dot> org.]
+
+[endsect]
+
Added: sandbox/rendez_vous/libs/rendez_vous/doc/introduction.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/introduction.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,20 @@
+[/
+ / Copyright (c) 2008 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)
+ /]
+
+[section:intro Introduction]
+
+
+[section:conc Concurrent components]
+
+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.
+
+Concurrent execution of objects requires a mechanism for synchronizing the access to shared objects, just as direct communication between objects may require synchronization. The basic mechanism for synchronization in Boost.Threads and Boost.Interprocess are the well known mutex and condition_variables. Mutexes and condition variables are, however, only useful for very simple synchronization problems. The Rendez-Vous library therefore introduce high-level abstractions for handling more complicated synchronization problems, including a so-called rendezvous mechanism for handling direct communication between objects. All the concurrency abstractions being introduced are defined by means of mutexes an conditions.
+
+[endsect]
+
+
+[endsect]
\ No newline at end of file
Added: sandbox/rendez_vous/libs/rendez_vous/doc/overview.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/overview.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,51 @@
+[/
+ (C) Copyright 2008-2009 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).
+]
+
+[/========================]
+[section:overview Overview]
+[/========================]
+
+[/==================]
+[heading Description]
+[/==================]
+
+To date, C++ multi threaded programs that need to be efficient use the same mutexes, semaphores, and events that Dijkstra described 40 years ago. This unfortunate state of affairs makes multi threaded programs difficult to design, debug, ensure correct, optimize, maintain, and analyze formally. Consequently, building tools that automate detection of race conditions and deadlocks is highly desirable.
+
+This library is a porting to C++ of the Beta rendez-vous library. My main concen has been to boostify all these ideas in a coherent way.
+
+[*Boost.Rendez-Vous] provides:
+
+* A rendezvous mechanism for handling direct communication between objects `concurrent_components` via `ports` using an accept-synchronize protocol based on the design of the concurrency library in the Beta language.
+
+
+[/====================================]
+[heading How to Use This Documentation]
+[/====================================]
+
+This documentation makes use of the following naming and formatting conventions.
+
+* Code is in `fixed width font` and is syntax-highlighted.
+* Replaceable text that you will need to supply is in [~italics].
+* If a name refers to a free function, it is specified like this:
+ `free_function()`; that is, it is in code font and its name is followed by `()` to indicate that it is a free function.
+* If a name refers to a class template, it is specified like this: `class_template<>`; that is, it is in code font and its name is followed by `<>` to indicate that it is a class template.
+* If a name refers to a function-like macro, it is specified like this: `MACRO()`;
+ that is, it is uppercase in code font and its name is followed by `()` to indicate that it is a function-like macro. Object-like macros appear without the trailing `()`.
+* Names that refer to /concepts/ in the generic programming sense are specified in CamelCase.
+
+[note In addition, notes such as this one specify non-essential information that provides additional background or rationale.]
+
+Finally, you can mentally add the following to any code fragments in this document:
+
+ // Include all of Rendez-Vous files
+ #include <boost/rendez_vous.hpp>
+
+ // Create a namespace aliases
+ namespace brv = boost::rendez_vous;
+
+[include introduction.qbk]
+[endsect]
Added: sandbox/rendez_vous/libs/rendez_vous/doc/rationale.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/rationale.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,12 @@
+[/
+ / Copyright (c) 2008 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)
+ /]
+
+[section:rationale Appendix B: Rationale]
+
+TBC
+
+[endsect]
Added: sandbox/rendez_vous/libs/rendez_vous/doc/reference.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/reference.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,16 @@
+[/
+ / Copyright (c) 2008 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)
+ /]
+
+[section Reference]
+
+
+[include reference/concurrent_component.qbk]
+
+
+[endsect]
+
+
Added: sandbox/rendez_vous/libs/rendez_vous/doc/reference/concurrent_component.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/reference/concurrent_component.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,104 @@
+[/
+ / Copyright (c) 2008-2009 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)
+ /]
+
+
+[/==========================================================================================]
+[section:concurrent_component_hpp Header `<boost/rendez_vous/concurrent_component.hpp>`]
+[/==========================================================================================]
+
+ namespace boost { namespace rendez_vous {
+ class port;
+ class object_port;
+ template <typename TYPE> class qualified_port;
+ class concurrent_component;
+ }}
+
+[section Class `port`]
+
+ class port {
+ public:
+ class synchronizer {
+ synchronizer(port& that);
+ ~synchronizer() {
+ };
+ port();
+ ~port();
+ void accept();
+ bool accept_until(const boost::posix_time::ptime &abs_time);
+ template<typename TimeDuration>
+ bool accept_for(TimeDuration const& rel_time);
+ };
+
+[endsect]
+
+[section Class `object_port`]
+
+ class object_port {
+ public:
+ class synchronizer {
+ synchronizer(object_port& that, const concurrent_component_base* snd);
+ ~synchronizer() {
+ };
+ object_port();
+ ~object_port();
+ void accept(const void* snd);
+ bool accept_until(const void* snd, const boost::posix_time::ptime &abs_time);
+ template<typename TimeDuration>
+ bool accept_for(const void* snd, TimeDuration const& rel_time);
+ };
+
+[endsect]
+
+[section Template Class `qualified_port`]
+
+ template <typename TYPE>
+ class qualified_port {
+ public:
+ class synchronizer {
+ synchronizer(qualified_port& that, const concurrent_component_base* snd);
+ ~synchronizer() {
+ };
+ object_port();
+ ~object_port();
+ void accept(const TYPE* snd);
+ bool accept_until(const TYPE* snd, const boost::posix_time::ptime &abs_time);
+ template<typename TimeDuration>
+ bool accept_for(const TYPE* snd, TimeDuration const& rel_time);
+ };
+
+[endsect]
+
+[section Class `concurrent_component`]
+
+ class concurrent_component
+ typedef unspecified port;
+ typedef unspecified object_port;
+ typedef unspecified qualified_port;
+
+ static void accept(port& p);
+ static void accept_until(const boost::posix_time::ptime &abs_time, port& p);
+ template<typename TimeDuration>
+ static bool accept_for(TimeDuration const& rel_time, port& p);
+
+ static void accept_all(port& p1, ..., port& pn);
+ static void accept_all_until(const boost::posix_time::ptime &abs_time, port& p1, ..., port& pn);
+ template<typename TimeDuration>
+ static void accept_all_for(TimeDuration const& rel_time, port& p1, ..., port& pn);
+
+ static void accept_any(port& p1, ..., port& pn);
+ static void accept_any_until(const boost::posix_time::ptime &abs_time, port& p1, ..., port& pn);
+ template<typename TimeDuration>
+ static void accept_any_for(TimeDuration const& rel_time, port& p1, ..., port& pn);
+
+ };
+
+[endsect]
+
+
+
+[endsect]
Added: sandbox/rendez_vous/libs/rendez_vous/doc/references.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/references.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,19 @@
+[/
+ / Copyright (c) 2008 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)
+ /]
+
+[section:ext_references References]
+[variablelist
+
+[
+ [[@http://www.daimi.au.dk/~beta/Books/index.html
+ [*Object-Oriented Programming in the BETA Programming Language ]]]
+ [Ole Lehrmann Madsen, Birger Moller-Pedersen, Kristen Nygaard]
+]
+
+]
+
+[endsect]
Added: sandbox/rendez_vous/libs/rendez_vous/doc/rendez_vous.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/rendez_vous.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,120 @@
+[/
+ / Copyright (c) 2008 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)
+ /]
+
+[library Boost.Rendez-Vous
+ [quickbook 1.3]
+ [authors [Botet Escriba, Vicente J.]]
+ [copyright 2008 Vicente J. Botet Escriba]
+ [id boost.rendez_vous]
+ [dirname rendez_vous]
+ [purpose Concurrent synchronization utilities]
+ [license
+ 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])
+ ]
+]
+[template concept_param[role concept] A type playing the role of [role] in the [concept] concept.]
+
+[template concept_var[type] Object of type [type].]
+
+[template var[name type]
+
+* [*[name]] Object of type [type].
+]
+
+[template concept_arg[name concept]
+
+The type [*[name]] must be a model of [*[concept]].
+]
+
+[template concept_valid_expressions[concept]
+[*Valid expressions]
+
+In addition to the expressions defined in [concept], the following expressions must be valid.
+]
+
+
+[def __lock__ `lock`]
+[def __unlock__ `unlock`]
+[def __try_lock__ `try_lock`]
+[def __lock_until__ `lock_until`]
+[def __lock_for__ `lock_for`]
+[def __try_lock_until__ `try_lock_until`]
+[def __try_lock_for__ `try_lock_for`]
+[def __lock_shared__ `lock_shared`]
+[def __try_lock_shared__ `try_lock_shared`]
+[def __unlock_shared__ `unlock_shared`]
+[def __lock_shared_until__ `lock_shared_until`]
+[def __lock_shared_for__ `lock_shared_for`]
+[def __try_lock_shared_until__ `try_lock_shared_until`]
+[def __try_lock_shared_for__ `try_lock_shared_for`]
+[def __lock_upgrade__ `lock_upgrade`]
+[def __lock_upgrade_until__ `lock_upgrade_until`]
+[def __lock_upgrade_for__ `lock_upgrade_for`]
+[def __try_lock_upgrade__ `try_lock_upgrade`]
+[def __try_lock_upgrade_until__ `try_lock_upgrade_until`]
+[def __try_lock_upgrade_for__ `try_lock_upgrade_for`]
+[def __unlock_upgrade__ `unlock_upgrade`]
+[def __unlock_and_lock_upgrade__ `unlock_and_lock_upgrade`]
+[def __unlock_and_lock_shared__ `unlock_and_lock_shared`]
+[def __unlock_upgrade_and_lock_shared__ `unlock_upgrade_and_lock_shared`]
+[def __unlock_upgrade_and_lock__ `unlock_upgrade_and_lock`]
+[def __unlock_upgrade_and_lock_until__ `unlock_upgrade_and_lock_until`]
+[def __unlock_upgrade_and_lock_for__ `unlock_upgrade_and_lock_for`]
+[def __try_unlock_upgrade_and_lock__ `try_unlock_upgrade_and_lock`]
+[def __try_unlock_upgrade_and_lock_until__ `try_unlock_upgrade_and_lock_until`]
+[def __try_unlock_upgrade_and_lock_for__ `try_unlock_upgrade_and_lock_for`]
+[def __unlock_shared_and_lock__ `unlock_shared_and_lock`]
+[def __try_unlock_shared_and_lock__ `try_unlock_shared_and_lock`]
+[def __try_unlock_shared_and_lock_upgrade__ `try_unlock_shared_and_lock_upgrade`]
+[def __Lockable__ `Lockable`]
+
+
+[/
+[section Preface]
+
+[:[".]]
+[:[*['-- ]]]
+
+[endsect]
+/]
+
+[warning Rendez-Vous is not a part of the Boost libraries.]
+
+[import ../../../boost/rendez_vous/concurrent_component.hpp]
+
+[import ../example/BankAccount.cpp]
+[import ../example/EL_BancAccount.cpp]
+[import ../example/Histogram.cpp]
+[import ../example/HotelReservation.cpp]
+[import ../example/IL_BancAccount.cpp]
+[import ../example/IL_Lockable_BancAccount.cpp]
+[import ../example/IL_Rec_Lockable_BancAccount.cpp]
+[import ../example/Master_Slave.cpp]
+[import ../example/SingleBuf.cpp]
+[import ../example/QualifiedSingleBuf.cpp]
+
+
+
+
+
+[include overview.qbk]
+
+[include users_guide.qbk]
+
+[include reference.qbk]
+
+[/xinclude autodoc.xml]
+
+
+[include case_studies.qbk]
+
+
+[include appendices.qbk]
+
+
Added: sandbox/rendez_vous/libs/rendez_vous/doc/tests.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/tests.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,22 @@
+[/
+ (C) Copyright 2008-2009 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).
+]
+
+[section Appendix E: Tests]
+
+
+[section Examples]
+[table
+ [[Name] [Kind] [Description] [Result] [Ticket]]
+ [[Master_Slave] [run] [ tests] [Pass] [#]]
+ [[HotelReservation] [run] [ tests] [Fail] [v0.2#2]]
+ [[QualifiedSingleBuf] [link] [ tests] [Pass] [#]]
+ [[Histogram] [run] [ tests] [Pass] [#]]
+]
+
+[endsect]
+
+[endsect]
Added: sandbox/rendez_vous/libs/rendez_vous/doc/tickets.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/tickets.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,45 @@
+[/
+ (C) Copyright 2008-2009 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).
+]
+
+[section Appendix F: Tickets]
+
+
+[table
+[[Kind] [Identifier] [Description] [Resolution] [State] [Tests] [Version]]
+[
+ [feature]
+ [v0.1#1]
+ [array_locker]
+ [See section]
+ [Open]
+ [See array_locker_tests]
+ [v0.2]
+]
+[
+ [bug]
+ [v0.2#1]
+ [sync_buffer_monitor_test fails]
+ [---]
+ [Open]
+ [sync_buffer_monitor_test]
+ [v0.2]
+]
+
+[
+ [bug]
+ [v0.2#2]
+ [HotelReservation fails]
+ [---]
+ [Open]
+ [HotelReservation example]
+ [v0.2]
+]
+]
+
+
+
+[endsect]
Added: sandbox/rendez_vous/libs/rendez_vous/doc/tutorial.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/tutorial.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,20 @@
+[/
+ / Copyright (c) 2008 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)
+ /]
+
+
+
+[section:tutorial Tutorial]
+
+[info The contents of this tutorial is an adaptation of the papers of Andrei Alexandrescu, Kevlin Henney and the concurrent part of the BETA Programming Language.]
+
+Concurrent components may interact in different ways: they may access the same shared objects by, for example, executing functions of these objects; or they may communicate directly by executing functions of each other.
+
+Concurrent execution of objects requires a mechanism for synchronizing the access to shared objects, just as direct communication between objects may require synchronization. The basic mechanism for synchronization in Boost.Threads and Boost.Interprocess are the well known mutex and condition_variables. Mutexes and condition variables are, however, only useful for very simple synchronization problems. The Synchro Library therefore introduce high-level abstractions for handling more complicated synchronization problems, including monitor for guaranteeing exclusive access to an object, controlling external locking and last a so-called rendezvous mechanism for handling direct communication between objects. All the concurrency abstractions being introduced are defined by means of mutexes an conditions.
+
+[include tutorial/rendezvous.qbk]
+
+[endsect]
Added: sandbox/rendez_vous/libs/rendez_vous/doc/tutorial/rendezvous.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/tutorial/rendezvous.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,145 @@
+[/
+ / Copyright (c) 2008 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)
+ /]
+
+[section Concurrent components]
+[note This tutorial is an adaptation of chapter Concurrency of the Object-Oriented Programming in the BETA Programming Language to the Boost library.]
+[section Direct communication between components]
+
+In the previous section we have described a mechanism for concurrent components to communicate through shared objects. In many cases it appears more natural for concurrent components to communicate directly instead of using shared objects. Consider the following example:
+
+[synchronized_communication_between_components_schema]
+
+Here the concurrent components `S` and `R` call operations on each other. The state of `S` may, however, not be meaningful when `R` executes `m`, and vice versa. In the following sections we will introduce abstractions for making it possible to synchronize such communication.
+
+[section Synchronized communication between components]
+
+In this section we will introduce the notion of synchronized execution of objects. A component `S` may request execution of a member function of a component `R`. The component `R` must accept that the request can be fulfilled. Synchronized communication is described in a generic class concurrent_component. A `concurrent_component` defines the notion of a `port` for controlling the communication. A `port` has a nested `synchronizer` class for defining operations controlled by the `port`; it also has an accept operation for signaling that an operation associated with the `port` can be executed. The `concurrent_component` has the following structure:
+
+[port]
+
+The following object illustrates two communicating `concurrent_component`s:
+
+[synchronized_communication_between_components]
+
+The concurrent_component `S` may execute a request, which is a normal remote procedure call:
+
+```
+ e2 = r_.m(e1);
+```
+
+Since `m` is a synchronized port operation, the execution of M has to be accepted
+by R before it is executed. For M to be accepted, R must execute an accept, which has the following form:
+
+```
+ port::accept(p);
+```
+
+The communication is carried out when `S` is executing `r_.m` and `R` is executing
+`port::accept(p)`. Both `S` and `R` are blocked until the communication takes place. A
+communication has the effect that `S` and `R` together execute the evaluation: `e2 = r_.m(e1);`
+
+This takes place as follows:
+
+# When S executes `e2 = r_.m(e1)`, `S` is now ready to execute the internals of the `R::m`.
+# When `R` executes `port::accept(p)`, `R` has signaled that the internals of a function protected with `port::synchronizer `_(p)`; may be executed. `R` will wait until such an execution has taken place.
+# When both `R` and `S` are ready, the internals of `R::m` can be executed.
+# When the internals of `R::m` has been executed, `R` will continue execution. In addition, a possible return of `R::m` is assigned to `e2`.
+
+The object `S` executing `r_.m()` is called the sender, and the object `R` having `m` as an operation is called the receiver.
+
+In the following example, two systems `Prod` and `Cons` communicate via a single element buffer represented by a `SingleBuf` concurrent_component. The `SingleBuf` concurrent_component alternates between accepting a `Push` and a `Pull`:
+
+[SingleBuf]
+
+[endsect]
+[section Ports controlling several operations]
+
+It is possible to associate more than one operation with a port.
+
+The `Master`-concurrent_component transmits a sequence of values to the two `Slave`-systems, and each Slave-concurrent_component computes the sum of the values being received. Each value is received and accumulated by a synchronous execution of `Add`. A Slave object can be used according to the following protocol:
+
+# The `Clear` operation must be used to initiate a new sequence of summations. A `Clear` thus terminates any ongoing summation.
+# The `Add` operation accumulates a new value.
+# The `Result` operation returns the current sum. In the example, positive numbers are transmitted to `Slave1` and negative numbers are transmitted to `Slave2`.
+
+[Master_Slave_Slave]
+
+[Master_Slave_Master]
+
+
+[endsect]
+
+[section Restricted acceptance]
+
+An accept operation on a port signals that any object is allowed to execute an operation associated with the port. Sometimes it is desirable to restrict the possible objects that are allowed to execute a port operation. The restriction may specify that one specific object is allowed to execute a port operation, or it may specify that instances of a specific class are allowed to execute a port operation. These two types of restrictions are described in the following two sections.
+
+[*Object restriction]
+
+It is possible to restrict the sender of an operation by declaring the port as an instance of the `object_port` class. The `accept` operation of an `object_port` has a parameter which is a reference to the object that is allowed to execute a port operation. As C++ do not allows to recover the sender of an operation we need pass it as parameter.
+
+The syntax for this is:
+
+ T S; //some component reference
+ object_port request_;
+ void Close(const concurrent_component_base* snd) {
+ object_port::synchronizer _(request_, snd);
+ // ...
+ }
+ //...
+ object_port::accept(request_, sender_); // sender_ has been stored previously
+
+
+The example describes an abstract pattern for handling reservations of some kind. The reservations are supposed to be stored in some register. The actual way this is done is supposed to be described in sub-classes of ReservationHandler. At most, one person at a time is allowed to make reservations. An agent making a reservation must perform the following steps:
+
+
+# The register must be locked by executing the Lock operation.
+# The agent may then perform one or more reservations using Reserve.
+# The agent terminates the reservation session by executing Close.
+
+The example includes a sketch of a handler for hotel reservations. The concurrent_component P describes a scenario of an agent making two hotel reservations.
+
+[ReservationHandler]
+
+[HotelResHandler]
+
+[HotelResHandler_main]
+
+[*Qualified restriction]
+
+The object_port described above makes it possible to ensure that only one specific concurrent_component may execute a port operation. It is often desirable to specify that a port operation may be executed by a restricted set of `concurrent_component`s. By using a port instantiated from `qualified_port`, it is possible to define port operations that may be executed by objects of a given class. The syntax for
+this is:
+
+
+Port operations associated with P may now be executed by an object which is an instance of T or inherits from T.
+
+The following example illustrates the use of a qualified port. The single buffer example is modified such that Push can only be executed by Producer objects and Pull can only be executed by Consumer objects.
+
+[QualifiedSingleBuf]
+
+[endsect]
+
+[endsect]
+
+[section Compound concurrent components]
+
+[section Indirect communication between internal concurrent components]
+
+Composition is a fundamental means for organizing objects. We have several examples of defining an object as compositions of other objects using part objects, references and block structure. We have also seen how the action part of an object may be composed of other objects. In this section we shall show how to construct compound systems that are concurrent_component objects consisting of several internal multiple action sequences.
+
+In Boost.Synchro the actions to be performed by a concurrent_component may be distributed among several internal systems. The internal systems may be more or less independent, and they may access common data (items in an enclosing concurrent_component), communicate with each other, communicate with external systems or control communication between external systems, and the enclosing concurrent_component.
+
+In the following, examples of such compound systems are described. For compound systems consisting of several internal concurrent systems, we are often interested in describing that execution of the outermost concurrent_component cannot terminate before execution of all inner systems have terminated. The outermost concurrent_component may have to do some initialization before executing the inner concurrent_component, and it may have to do some finalization (clean-up) when they have finished execution. The concurrent_component class has a concurrent_execution nested class that can be used for this purpose. concurrent_component can be used in the following way:
+
+ concurrent_execution<S1,S2, S3)> conc(s1,s2, s3);
+ conc();
+ conc.join();
+
+[Histogram]
+
+[endsect]
+[endsect]
+[endsect]
Added: sandbox/rendez_vous/libs/rendez_vous/doc/users_guide.qbk
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/doc/users_guide.qbk 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,30 @@
+[/
+[/
+ (C) Copyright 2008 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).
+]
+
+[/==============================]
+[section:users_guide Users'Guide]
+[/==============================]
+
+[include getting_started.qbk]
+[include tutorial.qbk]
+[include references.qbk]
+
+
+[/=======================]
+[section:glosary Glossary]
+[/=======================]
+
+
+[variablelist
+
+[[port] [.]]
+]
+
+[endsect]
+
+[endsect]
\ No newline at end of file
Added: sandbox/rendez_vous/libs/rendez_vous/example/Histogram.cpp
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/example/Histogram.cpp 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,149 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-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)
+//
+// See http://www.boost.org/libs/rendez_vous for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/rendez_vous/concurrent_component.hpp>
+#include <boost/synchro/monitor.hpp>
+#include <boost/synchro/thread/mutex.hpp>
+#include <boost/thread.hpp>
+#include <boost/ref.hpp>
+#if 0
+#include <boost/rendez_vous/conc_tuple.hpp>
+#else
+#include <boost/async/algorithm.hpp>
+#include <boost/async/typeof/threader.hpp>
+#endif
+
+namespace {
+ volatile int Run = 1;
+}
+
+using namespace boost::rendez_vous;
+using namespace boost::synchro;
+using namespace boost;
+
+
+//[Histogram
+class Histogram : boost::rendez_vous::concurrent_component {
+
+ class HistogramData : public exclusive_monitor<> {
+ unsigned R[100];
+ public:
+ HistogramData() {
+ for (int i = 0; i<100; i++) R[i] = 0;
+ }
+ void Add(unsigned i) {
+ synchronizer _(*this->mutex());
+ R[i]+=1;
+ }
+ void Sub(unsigned i) {
+ synchronizer _(*this->mutex());
+ R[i]=(R[i]>0)?R[i]-1:0;
+ }
+ unsigned Get(unsigned i) {
+ synchronizer _(*this->mutex());
+ return R[i];
+ }
+ };
+ class Display : boost::rendez_vous::concurrent_component {
+ HistogramData& histogramData_;
+ public:
+ typedef void result_type;
+ Display(HistogramData& histogramData) : histogramData_(histogramData) {}
+ void operator()()
+ {
+ for (int i=10;i>0;--i) {
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ for (unsigned i =0; i<100; ++i) {
+ std::cout << "==(" << i << ", "
+ << histogramData_.Get(i) << ")"
+ << std::endl;
+ }
+ }
+ }
+ };
+ class Update : boost::rendez_vous::concurrent_component {
+ Histogram::port& request_;
+ public:
+ typedef void result_type;
+ Update(Histogram::port& req) : request_(req) {}
+ void operator()()
+ {
+ for (int i=10;i>0;--i) {
+ accept(request_);
+ }
+ }
+ };
+ port request_;
+ HistogramData histogramData_;
+// friend class Update;
+ Display disp_;
+ Update updater_;
+public:
+ typedef void result_type;
+ Histogram()
+ : disp_(histogramData_)
+ , updater_(request_)
+ {}
+ void NewValue(int V) {
+ port::synchronizer _(request_);
+ if (V>0) histogramData_.Add(V);
+ else histogramData_.Sub(-V);
+ }
+ void operator()() {
+ #if 0
+ conc_tuple<Display,Update> conc_(disp_, updater_);
+ conc_();
+ conc_.join();
+ #else
+ boost::async::shared_threader ae;
+ BOOST_AUTO(conc_, boost::async::fork_all(ae, boost::bind(boost::ref(disp_)), boost::bind(boost::ref(updater_))));
+ boost::async::join_all(conc_);
+ #endif
+
+ }
+};
+//]
+class S : boost::rendez_vous::concurrent_component {
+ Histogram& histogram_;
+public:
+ typedef void result_type;
+ S(Histogram& histogram) : histogram_(histogram) {}
+ void operator()()
+ {
+ for (int i=10;i>0;--i) {
+ // TODO replace by random
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ histogram_.NewValue(i);
+
+ }
+ }
+};
+
+int main()
+{
+ Histogram histo;
+ S snd(histo);
+ #if 0
+ conc_tuple<Histogram, S> conc(histo, snd);
+ conc();
+ boost::this_thread::sleep(boost::posix_time::seconds(10));
+
+ conc.join();
+ #else
+ boost::async::shared_threader ae;
+ BOOST_AUTO(conc, boost::async::fork_all(ae, boost::bind(boost::ref(histo)), boost::bind(boost::ref(snd))));
+ boost::this_thread::sleep(boost::posix_time::seconds(10));
+ boost::async::join_all(conc);
+ #endif
+
+ return 0;
+}
+
+
Added: sandbox/rendez_vous/libs/rendez_vous/example/HotelReservation.cpp
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/example/HotelReservation.cpp 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,221 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-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)
+//
+// See http://www.boost.org/libs/rendez_vous for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/rendez_vous/concurrent_component.hpp>
+#include <boost/synchro/thread/mutex.hpp>
+#include <boost/thread.hpp>
+#include <boost/ref.hpp>
+#include <string>
+
+#if 0
+#include <boost/rendez_vous/conc_tuple.hpp>
+#endif
+
+#include <boost/async/algorithm.hpp>
+#include <boost/async/typeof/threader.hpp>
+
+#include <boost/test/unit_test.hpp>
+boost::mutex MTX;
+
+#define ABOOST_TEST_MESSAGE(MSG) { \
+/*boost::lock_guard<boost::mutex> g(MTX);*/ \
+std::cout << __LINE__ << MSG << std::endl; \
+}
+
+#define ABOOST_TEST_CHECKPOINT(MSG) { \
+ /*boost::lock_guard<boost::mutex> g(MTX); */\
+ std::cout << __LINE__ << MSG << std::endl; \
+}
+
+using namespace boost::rendez_vous;
+using namespace boost::synchro;
+using namespace boost;
+
+//namespace {
+// volatile int Run = 1;
+//}
+
+//[ReservationHandler
+class ReservationHandler : public boost::rendez_vous::concurrent_component
+{
+protected:
+ port lock_or_interrupt_;
+ object_port request_;
+ const concurrent_component_base* sender_;
+ bool closed_;
+ bool interrupted_;
+public:
+ typedef void result_type;
+ ReservationHandler() : sender_(0), closed_(true), interrupted_(false) {}
+ void Lock(const concurrent_component_base* snd) {
+ ABOOST_TEST_CHECKPOINT("Lock")
+ port::synchronizer _(lock_or_interrupt_);
+ ABOOST_TEST_CHECKPOINT("Locked")
+ sender_ = snd;
+ closed_ =false;
+ }
+ void Interrupt() {
+ ABOOST_TEST_CHECKPOINT("Interrupt")
+ port::synchronizer _(lock_or_interrupt_);
+ interrupted_ =true;
+ }
+// void Reserve(const concurrent_component_base& snd) {
+// object_port::synchronizer _(request_, snd);
+// Reserv();
+// }
+// virtual void Reserve()=0;
+
+ void Close(const concurrent_component_base* snd) {
+ ABOOST_TEST_CHECKPOINT("Close")
+ object_port::synchronizer _(request_, snd);
+ closed_ =true;
+ sender_ = 0;
+ DoClose();
+ }
+ virtual void DoClose() {};
+ void operator()() {
+ while (!interrupted_) {
+ accept(lock_or_interrupt_);
+ if (interrupted_) break;
+ while (!closed_) {
+ accept(request_, sender_);
+ }
+ }
+ }
+// ReservationHandler()
+// : closed_(false)
+// {}
+ virtual ~ReservationHandler() {};
+};
+//]
+
+//[HotelResHandler
+class HotelResHandler : public ReservationHandler
+{
+ unsigned roomNo;
+public:
+ unsigned Reserve(const concurrent_component_base* snd
+ , std::string guestName
+ , unsigned noOfPersons) {
+ ABOOST_TEST_CHECKPOINT("Reserve")
+ object_port::synchronizer _(request_, snd);
+ // ...
+ ++roomNo;
+ ABOOST_TEST_CHECKPOINT(roomNo<<":"<<guestName<<" #"<<noOfPersons)
+ return roomNo;
+ }
+ virtual void DoClose(){};
+ virtual ~HotelResHandler() {};
+};
+//]
+
+//[HotelResHandler_P
+class P : public boost::rendez_vous::concurrent_component {
+public:
+ typedef void result_type;
+ HotelResHandler& hrh_;
+ P(HotelResHandler& hrh):hrh_(hrh) {}
+ void operator()() {
+ ABOOST_TEST_MESSAGE("P Lock")
+ hrh_.Lock(this);
+ ABOOST_TEST_MESSAGE("P Reserve")
+ unsigned rno1 = hrh_.Reserve(this, std::string("Peter Olsen"),4);
+ ABOOST_TEST_CHECKPOINT(rno1)
+ ABOOST_TEST_MESSAGE("P Reserve")
+ unsigned rno2 = hrh_.Reserve(this, std::string("Anne Nielsen"),2);
+ ABOOST_TEST_CHECKPOINT(rno2)
+ hrh_.Close(this);
+ ABOOST_TEST_MESSAGE("P Close")
+ }
+};
+//]
+
+//[HotelResHandler_Q
+class Q : public boost::rendez_vous::concurrent_component {
+public:
+ typedef void result_type;
+ HotelResHandler& hrh_;
+ Q(HotelResHandler& hrh):hrh_(hrh) {}
+ void operator()() {
+ ABOOST_TEST_MESSAGE("Q Lock")
+ hrh_.Lock(this);
+ ABOOST_TEST_MESSAGE("Q Reserve")
+ unsigned rno1 = hrh_.Reserve(this, std::string("Carmen"),5);
+ ABOOST_TEST_CHECKPOINT(rno1)
+ ABOOST_TEST_MESSAGE("Q Reserve")
+ unsigned rno2 = hrh_.Reserve(this, std::string("Javier"),1);
+ ABOOST_TEST_CHECKPOINT(rno2)
+ hrh_.Close(this);
+ ABOOST_TEST_MESSAGE("Q Close")
+ }
+};
+//]
+
+class R : public boost::rendez_vous::concurrent_component {
+public:
+ typedef void result_type;
+ HotelResHandler& hrh_;
+ R(HotelResHandler& hrh):hrh_(hrh) {}
+ void operator()() {
+ try {
+ ABOOST_TEST_MESSAGE("R Reserve")
+ unsigned rno1 = hrh_.Reserve(this, std::string("Carmen"),5);
+ }catch (bad_sender& exp) {
+ ABOOST_TEST_MESSAGE("You need to Lock first")
+ }catch (...) {
+ std::cout << "... You need to Lock first" << std::endl;
+ }
+ }
+};
+//]
+
+//[HotelResHandler_main
+int main() {
+ HotelResHandler hrh;
+ P p(hrh);
+ Q q(hrh);
+ R r(hrh);
+#if 1
+ boost::async::shared_threader ae;
+ BOOST_AUTO(hrh_act, boost::async::fork(ae, boost::bind(boost::ref(hrh))));
+ BOOST_AUTO(conc, boost::async::fork_all(ae, boost::bind(boost::ref(p)), boost::bind(boost::ref(q)), boost::bind(boost::ref(r))));
+ boost::async::join_all(conc);
+ hrh.Interrupt();
+ boost::async::join(hrh_act);
+#else
+ conc_tuple<HotelResHandler, P, Q, R> conc(hrh, p, q, r);
+ conc();
+
+ boost::this_thread::sleep(boost::posix_time::seconds(4));
+
+ hrh.Interrupt();
+ conc.join();
+
+#if 0
+ boost::thread thread1(boost::ref(hrh));
+ boost::thread thread2(boost::ref(p));
+ boost::thread thread3(boost::ref(q));
+ boost::thread thread4(boost::ref(r));
+
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ hrh.Interrupt();
+
+ thread2.join();
+ thread3.join();
+ thread4.join();
+ thread1.join();
+
+#endif
+
+#endif
+ return 0;
+}
+//]
+
Added: sandbox/rendez_vous/libs/rendez_vous/example/Master_Slave.cpp
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/example/Master_Slave.cpp 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,117 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-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)
+//
+// See http://www.boost.org/libs/rendez_vous for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/rendez_vous/concurrent_component.hpp>
+#include <boost/synchro/thread/mutex.hpp>
+#include <boost/thread.hpp>
+#include <boost/ref.hpp>
+#include <boost/rendez_vous/conc_tuple.hpp>
+
+using namespace boost::rendez_vous;
+using namespace boost::synchro;
+using namespace boost;
+
+
+
+namespace {
+}
+
+//[Master_Slave_Slave
+class Slave : boost::rendez_vous::concurrent_component
+{
+ port receive_;
+ unsigned sum_;
+ bool End;
+public:
+ Slave() : End(false) {}
+ void Clear() {
+// std::cout << "Clear()" << std::endl;
+ port::synchronizer _(receive_);
+ sum_ = 0;
+ }
+ void Add(unsigned v) {
+// std::cout << "Add(" << v << ")" << std::endl;
+ port::synchronizer _(receive_);
+ sum_+=v;
+ }
+ unsigned Result() {
+ port::synchronizer _(receive_);
+// std::cout << sum_ << "=Result()" << std::endl;
+ return sum_;
+ }
+ void Interrupt() {
+// std::cout << "Interrupt()" << std::endl;
+ port::synchronizer _(receive_);
+ End=true;
+ }
+ void operator()() {
+ while (!End) {
+// std::cout << "accept()" << std::endl;
+ accept(receive_);
+ }
+ }
+};
+//]
+//[Master_Slave_Master
+struct Master : boost::rendez_vous::concurrent_component {
+ Slave& Slave1_;
+ Slave& Slave2_;
+
+ int V[100];
+ Master(Slave& slave1, Slave& slave2)
+ : Slave1_(slave1)
+ , Slave2_(slave2)
+ {}
+ void operator()()
+ {
+ for (int i=0; i<100; i++) {
+ V[i]=i;
+ }
+// std::cout << "before clear" << std::endl;
+ Slave1_.Clear();
+ Slave2_.Clear();
+// std::cout << "cleared" << std::endl;
+
+ for (int i=0; i<100; i++) {
+ if ((V[i]%2) > 0) Slave1_.Add(V[i]);
+ else Slave2_.Add(V[i]);
+ }
+ std::cout << Slave1_.Result() << std::endl;
+ std::cout << Slave2_.Result() << std::endl;
+ Slave1_.Interrupt();
+ Slave2_.Interrupt();
+ }
+};
+//]
+
+int main()
+{
+
+ std::cout << "BEGIN" << std::endl;
+ Slave slave1;
+ Slave slave2;
+ Master master(slave1, slave2);
+#if 1
+ conc_tuple<Slave, Slave, Master> conc(slave1, slave2, master);
+ conc();
+ conc.join();
+#else
+ boost::thread thread1(boost::ref(slave1));
+ boost::thread thread2(boost::ref(slave2));
+ boost::thread thread3(boost::ref(master));
+ std::cout << "wait" << std::endl;
+
+ thread1.join();
+ thread2.join();
+ thread3.join();
+#endif
+ return 0;
+}
+
Added: sandbox/rendez_vous/libs/rendez_vous/example/QualifiedSingleBuf.cpp
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/example/QualifiedSingleBuf.cpp 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,93 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-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)
+//
+// See http://www.boost.org/libs/rendez_vous for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/rendez_vous/concurrent_component.hpp>
+#include <boost/synchro/thread/mutex.hpp>
+#include <boost/thread.hpp>
+#include <boost/ref.hpp>
+#include <boost/rendez_vous/conc_tuple.hpp>
+
+namespace {
+ volatile int Run = 1;
+}
+
+using namespace boost::rendez_vous;
+using namespace boost::synchro;
+using namespace boost;
+
+struct Producer;
+struct Consumer;
+
+//[QualifiedSingleBuf
+class SingleBuf : boost::rendez_vous::concurrent_component {
+ qualified_port<Producer> PutPort_;
+ qualified_port<Consumer> GetPort_;
+// const concurrent_component_base* sender_;
+ char bufCh_;
+public:
+ void Put(const Producer* snd, char ch) {
+ qualified_port<Producer>::synchronizer _(PutPort_, snd);
+ bufCh_ = ch;
+ }
+ char Get(const Consumer* snd) {
+ qualified_port<Consumer>::synchronizer _(GetPort_, snd);
+ return bufCh_;
+ }
+ void operator()() {
+ while (Run) {
+ accept(PutPort_);
+ if (!Run) break;
+ accept(GetPort_);
+ }
+ }
+};
+//]
+struct Producer : boost::rendez_vous::concurrent_component {
+ SingleBuf& buf_;
+ Producer(SingleBuf& buf) : buf_(buf) {}
+ void operator()()
+ {
+ char ch=32;
+ while (Run) {
+ ch+=1;
+ if (ch > 65) ch = 32;
+ buf_.Put(this, ch);
+ }
+ }
+};
+struct Consumer : boost::rendez_vous::concurrent_component {
+ SingleBuf& buf_;
+ Consumer(SingleBuf& buf) : buf_(buf) {}
+ void operator()() {
+ while (Run) {
+ char ch = buf_.Get(this);
+ std::cout << ch << std::endl;
+ }
+ }
+};
+
+int main()
+{
+ std::cout << "press <enter> to end the program" << std::endl;
+
+ SingleBuf buf;
+ Producer prod(buf);
+ Consumer cons(buf);
+ conc_tuple<SingleBuf, Producer, Consumer> conc(buf, prod, cons);
+ conc();
+
+ std::cin.get();
+ Run = 0;
+ conc.join();
+
+ return 0;
+}
+
+
Added: sandbox/rendez_vous/libs/rendez_vous/example/SingleBuf.cpp
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/example/SingleBuf.cpp 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,107 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-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)
+//
+// See http://www.boost.org/libs/rendez_vous for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/rendez_vous/concurrent_component.hpp>
+#include <boost/synchro/thread/mutex.hpp>
+#include <boost/thread.hpp>
+#include <boost/ref.hpp>
+#include <boost/rendez_vous/conc_tuple.hpp>
+
+namespace {
+ volatile int Run = 1;
+}
+
+using namespace boost::rendez_vous;
+using namespace boost::synchro;
+using namespace boost;
+
+//[SingleBuf
+class SingleBuf : boost::rendez_vous::concurrent_component {
+ port PutPort_,GetPort_;
+ char bufCh_;
+ bool End;
+public:
+ SingleBuf() : End(false) {}
+ void Put(char ch) {
+ port::synchronizer _(PutPort_);
+// std::cout << "void Put("<<ch<<")" << std::endl;
+ bufCh_ = ch;
+ }
+ char Get() {
+ port::synchronizer _(GetPort_);
+// std::cout << bufCh_<<"=Get()" << std::endl;
+ return bufCh_;
+ }
+ void Interrupt() {
+ port::synchronizer _(PutPort_);
+// std::cout << "Interrupt()" << std::endl;
+ End=true;
+ }
+ void operator()() {
+ while (!End) {
+// std::cout << "port::accept(PutPort_)"<<std::endl;
+ accept(PutPort_);
+ if (End) break;
+// std::cout << "port::accept(GetPort_)"<<std::endl;
+ accept(GetPort_);
+ }
+ }
+};
+struct Producer : boost::rendez_vous::concurrent_component{
+ SingleBuf& buf_;
+ Producer(SingleBuf& buf) : buf_(buf) {}
+ void operator()()
+ {
+ buf_.Put('h');
+ buf_.Put('e');
+ buf_.Put('l');
+ buf_.Put('l');
+ buf_.Put('o');
+ buf_.Put(' ');
+ buf_.Put('w');
+ buf_.Put('o');
+ buf_.Put('r');
+ buf_.Put('l');
+ buf_.Put('d');
+ buf_.Put('!');
+ buf_.Put('\n');
+ }
+};
+struct Consumer : boost::rendez_vous::concurrent_component{
+ SingleBuf& buf_;
+ Consumer(SingleBuf& buf) : buf_(buf) {}
+ void operator()() {
+ for (;;) {
+// std::cout << "wait " << std::endl;
+ char ch = buf_.Get();
+ std::cout << ch;
+ if (ch=='\n') break;
+ }
+ }
+};
+//]
+
+int main()
+{
+// std::cout << "press <enter> to end the program" << std::endl;
+
+ SingleBuf buf;
+ Producer prod(buf);
+ Consumer cons(buf);
+ conc_tuple<SingleBuf, Producer, Consumer> conc(buf, prod, cons);
+ conc();
+
+ boost::this_thread::sleep(boost::posix_time::seconds(3));
+ buf.Interrupt();
+
+ conc.join();
+ return 0;
+}
+
Added: sandbox/rendez_vous/libs/rendez_vous/test/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/rendez_vous/libs/rendez_vous/test/Jamfile.v2 2009-06-06 10:35:28 EDT (Sat, 06 Jun 2009)
@@ -0,0 +1,59 @@
+#
+# Boost.Synchro
+# Build script for tests.
+#
+# Copyright (c) 2008-2009 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)
+
+using testing ;
+
+if ! $(BOOST_ROOT)
+{
+ BOOST_ROOT = [ modules.peek : BOOST_ROOT ] ;
+}
+
+# bjam -V2 threading=multi target-os=cygwin threadapi=pthread variant=debug
+
+project :
+ : requirements
+ <include>$(BOOST_ROOT)
+ <include>/sandbox/synchro
+ <include>/sandbox/async
+ <include>/sandbox/chrono
+ <include>/sandbox/conversion
+ <include>../../..
+
+ <threading>multi
+# <target-os>cygwin
+ #<threadapi>pthread
+# <variant>debug
+
+ #<library>/boost/test//boost_unit_test_framework/<link>static
+ #<library>/boost/thread//boost_thread/<link>static
+
+ <library>/boost_1_39_0/libs/test/build//boost_unit_test_framework/<link>static
+ <library>/boost_1_39_0/libs/thread/build//boost_thread/<link>static
+ <library>/sandbox/chrono/libs/chrono/build//boost_chrono/<link>static
+ <library>/boost_1_39_0/libs/system/build//boost_system/<link>static
+
+;
+
+
+test-suite "port" :
+# [ run port_test.cpp ]
+ ;
+
+
+test-suite "compile_fail_test" :
+# [ compile-fail ../example/IL_BancAccount.cpp : <define>BOOST_SYNCHRO_DO_NOT_COMPILE : IL_BancAccount_comp_fail ]
+ ;
+
+test-suite "examples" :
+ [ run ../example/SingleBuf.cpp ]
+ [ run ../example/Master_Slave.cpp ]
+ [ run ../example/HotelReservation.cpp ]
+ [ link ../example/QualifiedSingleBuf.cpp ]
+ [ run ../example/Histogram.cpp ]
+ ;
+
\ No newline at end of file
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