Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r84888 - in trunk: boost/thread libs/thread/test libs/thread/test/sync/mutual_exclusion/sync_bounded_queue libs/thread/test/sync/mutual_exclusion/sync_queue
From: vicente.botet_at_[hidden]
Date: 2013-06-23 16:47:03


Author: viboes
Date: 2013-06-23 16:47:03 EDT (Sun, 23 Jun 2013)
New Revision: 84888
URL: http://svn.boost.org/trac/boost/changeset/84888

Log:
Thread: fix some issues with sync_bounded_queue and added tests.

Added:
   trunk/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/
   trunk/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp (contents, props changed)
   trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/
   trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp (contents, props changed)
   trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp (contents, props changed)
Text files modified:
   trunk/boost/thread/sync_bounded_queue.hpp | 96 +++++++++-------
   trunk/boost/thread/sync_queue.hpp | 79 ++++++-------
   trunk/libs/thread/test/Jamfile.v2 | 11 +
   trunk/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp | 226 ++++++++++++++++++++++++++++++++++++++++
   trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp | 213 +++++++++++++++++++++++++++++++++++++
   trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp | 203 +++++++++++++++++++++++++++++++++++
   6 files changed, 742 insertions(+), 86 deletions(-)

Modified: trunk/boost/thread/sync_bounded_queue.hpp
==============================================================================
--- trunk/boost/thread/sync_bounded_queue.hpp Sun Jun 23 16:45:26 2013 (r84887)
+++ trunk/boost/thread/sync_bounded_queue.hpp 2013-06-23 16:47:03 EDT (Sun, 23 Jun 2013) (r84888)
@@ -48,31 +48,31 @@
     ~sync_bounded_queue();
 
     // Observers
- bool empty() const;
- bool full() const;
- size_type capacity() const;
- size_type size() const;
- bool closed() const;
+ inline bool empty() const;
+ inline bool full() const;
+ inline size_type capacity() const;
+ inline size_type size() const;
+ inline bool closed() const;
 
     // Modifiers
- void close();
+ inline void close();
 
- void push(const value_type& x);
- void push(BOOST_THREAD_RV_REF(value_type) x);
- bool try_push(const value_type& x);
- bool try_push(BOOST_THREAD_RV_REF(value_type) x);
- bool try_push(no_block_tag, const value_type& x);
- bool try_push(no_block_tag, BOOST_THREAD_RV_REF(value_type) x);
+ inline void push(const value_type& x);
+ inline void push(BOOST_THREAD_RV_REF(value_type) x);
+ inline bool try_push(const value_type& x);
+ inline bool try_push(BOOST_THREAD_RV_REF(value_type) x);
+ inline bool try_push(no_block_tag, const value_type& x);
+ inline bool try_push(no_block_tag, BOOST_THREAD_RV_REF(value_type) x);
 
     // Observers/Modifiers
- void pull(value_type&);
- void pull(ValueType& elem, bool & closed);
+ inline void pull(value_type&);
+ inline void pull(ValueType& elem, bool & closed);
     // enable_if is_nothrow_copy_movable<value_type>
- value_type pull();
- shared_ptr<ValueType> ptr_pull();
- bool try_pull(value_type&);
- bool try_pull(no_block_tag,value_type&);
- shared_ptr<ValueType> try_pull();
+ inline value_type pull();
+ inline shared_ptr<ValueType> ptr_pull();
+ inline bool try_pull(value_type&);
+ inline bool try_pull(no_block_tag,value_type&);
+ inline shared_ptr<ValueType> try_pull();
 
   private:
     mutable mutex mtx_;
@@ -86,42 +86,51 @@
     size_type capacity_;
     bool closed_;
 
- size_type inc(size_type idx) const BOOST_NOEXCEPT
+ inline size_type inc(size_type idx) const BOOST_NOEXCEPT
     {
       return (idx + 1) % capacity_;
     }
 
- bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
+ inline bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
     {
       return in_ == out_;
     }
- bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
     {
       return in_ == out_;
     }
- size_type capacity(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ inline bool full(unique_lock<mutex>& ) const BOOST_NOEXCEPT
     {
- return capacity;
+ return (inc(in_) == out_);
     }
- size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ inline bool full(lock_guard<mutex>& ) const BOOST_NOEXCEPT
     {
- return ((out_+capacity_-in_) % capacity_)-1;
+ return (inc(in_) == out_);
+ }
+ inline size_type capacity(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ {
+ return capacity_-1;
+ }
+ inline size_type size(lock_guard<mutex>& lk) const BOOST_NOEXCEPT
+ {
+ if (full(lk)) return capacity(lk);
+ return ((out_+capacity(lk)-in_) % capacity(lk));
     }
 
- void throw_if_closed(unique_lock<mutex>&);
+ inline void throw_if_closed(unique_lock<mutex>&);
 
- bool try_pull(value_type& x, unique_lock<mutex>& lk);
- bool try_push(const value_type& x, unique_lock<mutex>& lk);
- bool try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
- shared_ptr<value_type> try_pull(unique_lock<mutex>& lk);
+ inline bool try_pull(value_type& x, unique_lock<mutex>& lk);
+ inline bool try_push(const value_type& x, unique_lock<mutex>& lk);
+ inline bool try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
+ inline shared_ptr<value_type> try_pull(unique_lock<mutex>& lk);
 
- void wait_until_not_empty(unique_lock<mutex>& lk);
- void wait_until_not_empty(unique_lock<mutex>& lk, bool&);
- size_type wait_until_not_full(unique_lock<mutex>& lk);
- size_type wait_until_not_full(unique_lock<mutex>& lk, bool&);
+ inline void wait_until_not_empty(unique_lock<mutex>& lk);
+ inline void wait_until_not_empty(unique_lock<mutex>& lk, bool&);
+ inline size_type wait_until_not_full(unique_lock<mutex>& lk);
+ inline size_type wait_until_not_full(unique_lock<mutex>& lk, bool&);
 
 
- void notify_not_empty_if_needed(unique_lock<mutex>& lk)
+ inline void notify_not_empty_if_needed(unique_lock<mutex>& lk)
     {
       if (waiting_empty_ > 0)
       {
@@ -130,7 +139,7 @@
         not_empty_.notify_one();
       }
     }
- void notify_not_full_if_needed(unique_lock<mutex>& lk)
+ inline void notify_not_full_if_needed(unique_lock<mutex>& lk)
     {
       if (waiting_full_ > 0)
       {
@@ -140,13 +149,13 @@
       }
     }
 
- void pull(value_type& elem, unique_lock<mutex>& lk)
+ inline void pull(value_type& elem, unique_lock<mutex>& lk)
     {
       elem = boost::move(data_[out_]);
       out_ = inc(out_);
       notify_not_full_if_needed(lk);
     }
- boost::shared_ptr<value_type> ptr_pull(unique_lock<mutex>& lk)
+ inline boost::shared_ptr<value_type> ptr_pull(unique_lock<mutex>& lk)
     {
       shared_ptr<value_type> res = make_shared<value_type>(boost::move(data_[out_]));
       out_ = inc(out_);
@@ -154,26 +163,23 @@
       return res;
     }
 
-
- void set_in(size_type in, unique_lock<mutex>& lk)
+ inline void set_in(size_type in, unique_lock<mutex>& lk)
     {
       in_ = in;
       notify_not_empty_if_needed(lk);
     }
 
- void push_at(const value_type& elem, size_type in_p_1, unique_lock<mutex>& lk)
+ inline void push_at(const value_type& elem, size_type in_p_1, unique_lock<mutex>& lk)
     {
       data_[in_] = elem;
       set_in(in_p_1, lk);
     }
 
- void push_at(BOOST_THREAD_RV_REF(value_type) elem, size_type in_p_1, unique_lock<mutex>& lk)
+ inline void push_at(BOOST_THREAD_RV_REF(value_type) elem, size_type in_p_1, unique_lock<mutex>& lk)
     {
       data_[in_] = boost::move(elem);
       set_in(in_p_1, lk);
     }
-
-
   };
 
   template <typename ValueType>

Modified: trunk/boost/thread/sync_queue.hpp
==============================================================================
--- trunk/boost/thread/sync_queue.hpp Sun Jun 23 16:45:26 2013 (r84887)
+++ trunk/boost/thread/sync_queue.hpp 2013-06-23 16:47:03 EDT (Sun, 23 Jun 2013) (r84888)
@@ -37,37 +37,36 @@
 
     // Constructors/Assignment/Destructors
     BOOST_THREAD_NO_COPYABLE(sync_queue)
- sync_queue();
- template <typename Range>
- explicit sync_queue(Range range);
- ~sync_queue();
+ inline sync_queue();
+ //template <typename Range>
+ //inline explicit sync_queue(Range range);
+ inline ~sync_queue();
 
     // Observers
- bool empty() const;
- bool full() const;
- size_type size() const;
- bool closed() const;
+ inline bool empty() const;
+ inline bool full() const;
+ inline size_type size() const;
+ inline bool closed() const;
 
     // Modifiers
- void close();
+ inline void close();
 
- void push(const value_type& x);
- void push(BOOST_THREAD_RV_REF(value_type) x);
- bool try_push(const value_type& x);
- bool try_push(BOOST_THREAD_RV_REF(value_type) x);
- bool try_push(no_block_tag, const value_type& x);
- bool try_push(no_block_tag, BOOST_THREAD_RV_REF(value_type) x);
+ inline void push(const value_type& x);
+ inline void push(BOOST_THREAD_RV_REF(value_type) x);
+ inline bool try_push(const value_type& x);
+ inline bool try_push(BOOST_THREAD_RV_REF(value_type) x);
+ inline bool try_push(no_block_tag, const value_type& x);
+ inline bool try_push(no_block_tag, BOOST_THREAD_RV_REF(value_type) x);
 
     // Observers/Modifiers
- void pull(value_type&);
- void pull(ValueType& elem, bool & closed);
+ inline void pull(value_type&);
+ inline void pull(ValueType& elem, bool & closed);
     // enable_if is_nothrow_copy_movable<value_type>
- value_type pull();
- shared_ptr<ValueType> ptr_pull();
- bool try_pull(value_type&);
- bool try_pull(no_block_tag,value_type&);
- shared_ptr<ValueType> try_pull();
-
+ inline value_type pull();
+ inline shared_ptr<ValueType> ptr_pull();
+ inline bool try_pull(value_type&);
+ inline bool try_pull(no_block_tag,value_type&);
+ inline shared_ptr<ValueType> try_pull();
 
   private:
     mutable mutex mtx_;
@@ -76,32 +75,31 @@
     boost::container::deque<ValueType> data_;
     bool closed_;
 
- bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
+ inline bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
     {
       return data_.empty();
     }
- bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
     {
       return data_.empty();
     }
 
- size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
+ inline size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
     {
       return data_.size();
     }
 
- void throw_if_closed(unique_lock<mutex>&);
-
- bool try_pull(value_type& x, unique_lock<mutex>& lk);
- bool try_push(const value_type& x, unique_lock<mutex>& lk);
- bool try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
- shared_ptr<value_type> try_pull(unique_lock<mutex>& lk);
+ inline void throw_if_closed(unique_lock<mutex>&);
 
- void wait_until_not_empty(unique_lock<mutex>& lk);
- void wait_until_not_empty(unique_lock<mutex>& lk, bool&);
+ inline bool try_pull(value_type& x, unique_lock<mutex>& lk);
+ inline bool try_push(const value_type& x, unique_lock<mutex>& lk);
+ inline bool try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
+ inline shared_ptr<value_type> try_pull(unique_lock<mutex>& lk);
 
+ inline void wait_until_not_empty(unique_lock<mutex>& lk);
+ inline void wait_until_not_empty(unique_lock<mutex>& lk, bool&);
 
- void notify_not_empty_if_needed(unique_lock<mutex>& lk)
+ inline void notify_not_empty_if_needed(unique_lock<mutex>& lk)
     {
       if (waiting_empty_ > 0)
       {
@@ -111,31 +109,29 @@
       }
     }
 
- void pull(value_type& elem, unique_lock<mutex>& )
+ inline void pull(value_type& elem, unique_lock<mutex>& )
     {
       elem = boost::move(data_.front());
       data_.pop_front();
     }
- boost::shared_ptr<value_type> ptr_pull(unique_lock<mutex>& )
+ inline boost::shared_ptr<value_type> ptr_pull(unique_lock<mutex>& )
     {
       shared_ptr<value_type> res = make_shared<value_type>(boost::move(data_.front()));
       data_.pop_front();
       return res;
     }
 
- void push(const value_type& elem, unique_lock<mutex>& lk)
+ inline void push(const value_type& elem, unique_lock<mutex>& lk)
     {
       data_.push_back(elem);
       notify_not_empty_if_needed(lk);
     }
 
- void push(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk)
+ inline void push(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk)
     {
       data_.push(boost::move(elem));
       notify_not_empty_if_needed(lk);
     }
-
-
   };
 
   template <typename ValueType>
@@ -309,6 +305,7 @@
       ++waiting_empty_;
       not_empty_.wait(lk);
     }
+ closed=false;
   }
 
   template <typename ValueType>

Modified: trunk/libs/thread/test/Jamfile.v2
==============================================================================
--- trunk/libs/thread/test/Jamfile.v2 Sun Jun 23 16:45:26 2013 (r84887)
+++ trunk/libs/thread/test/Jamfile.v2 2013-06-23 16:47:03 EDT (Sun, 23 Jun 2013) (r84888)
@@ -630,6 +630,15 @@
           [ thread-run2-noit ./sync/mutual_exclusion/null_mutex/try_lock_until_pass.cpp : null_mutex__try_lock_until_p ]
     ;
 
+ test-suite ts_sync_queue
+ :
+ [ thread-run2-noit ./sync/mutual_exclusion/sync_queue/single_thread_pass.cpp : sync_queue__single_thread_p ]
+ ;
+
+ test-suite ts_sync_bounded_queue
+ :
+ [ thread-run2-noit ./sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp : sync_bounded_queue__single_thread_p ]
+ ;
 
     #explicit ts_this_thread ;
     test-suite ts_this_thread
@@ -779,6 +788,8 @@
           #[ thread-run test_8586.cpp ]
           #[ thread-run test_8596.cpp ]
           #[ thread-run test_8600.cpp ]
+ #[ thread-run2-noit ./sync/mutual_exclusion/sync_bounded_queue/multi_thread_pass.cpp : sync_bounded_queue__multi_thread_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp : sync_queue__multi_thread_p ]
           
     ;
 

Added: trunk/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp 2013-06-23 16:47:03 EDT (Sun, 23 Jun 2013) (r84888)
@@ -0,0 +1,226 @@
+// Copyright (C) 2013 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)
+
+// <boost/thread/sync_bounded_queue.hpp>
+
+// class sync_bounded_queue<T>
+
+// sync_bounded_queue();
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/sync_bounded_queue.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ // default queue invariants
+ boost::sync_bounded_queue<int> q(2);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST_EQ(q.capacity(), 2);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_pull fails
+ boost::sync_bounded_queue<int> q(2);
+ int i;
+ BOOST_TEST(! q.try_pull(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_pull fails
+ boost::sync_bounded_queue<int> q(2);
+ BOOST_TEST(! q.try_pull());
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue succeeds
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue succeeds
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ q.push(2);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST( q.full());
+ BOOST_TEST_EQ(q.size(), 2);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push value succeeds
+ boost::sync_bounded_queue<int> q(2);
+ int i;
+ q.push(i);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::sync_bounded_queue<int> q(2);
+ BOOST_TEST(q.try_push(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push value succeeds
+ boost::sync_bounded_queue<int> q(2);
+ int i;
+ BOOST_TEST(q.try_push(i));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::sync_bounded_queue<int> q(2);
+ BOOST_TEST(q.try_push(boost::no_block, 1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ int i;
+ q.pull(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ int i = q.pull();
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ int i;
+ BOOST_TEST(q.try_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ int i;
+ BOOST_TEST(q.try_pull(boost::no_block, i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ boost::shared_ptr<int> i = q.try_pull();
+ BOOST_TEST_EQ(*i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // full queue try_push rvalue fails
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ q.push(2);
+ BOOST_TEST(! q.try_push(3));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST( q.full());
+ BOOST_TEST_EQ(q.size(), 2);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // full queue try_push succeeds
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ q.push(2);
+ BOOST_TEST(q.try_pull());
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+
+ {
+ // closed invariants
+ boost::sync_bounded_queue<int> q(2);
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed queue push fails
+ boost::sync_bounded_queue<int> q(2);
+ q.close();
+ try {
+ q.push(1);
+ BOOST_TEST(false);
+ } catch (...) {
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(q.closed());
+ }
+ }
+ {
+ // 1-element closed queue pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ q.close();
+ int i;
+ q.pull(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(q.closed());
+ }
+
+ return boost::report_errors();
+}
+

Added: trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp 2013-06-23 16:47:03 EDT (Sun, 23 Jun 2013) (r84888)
@@ -0,0 +1,213 @@
+// Copyright (C) 2013 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)
+
+// <boost/thread/sync_queue.hpp>
+
+// class sync_queue<T>
+
+// push || pull;
+
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/sync_queue.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/future.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+struct call_push
+{
+ boost::sync_queue<int> &q_;
+ boost::shared_future<void> ready_;
+ boost::promise<void> &op_ready_;
+
+ call_push(boost::sync_queue<int> &q, boost::shared_future<void> ready, boost::promise<void> &op_ready) :
+ q_(q), ready_(ready), op_ready_(op_ready)
+ {
+ }
+ typedef void result_type;
+ void operator()()
+ {
+ op_ready_.set_value();
+ ready_.wait();
+ q_.push(42);
+ }
+
+};
+
+struct call_pull
+{
+ boost::sync_queue<int> &q_;
+ boost::shared_future<void> ready_;
+ boost::promise<void> &op_ready_;
+
+ call_pull(boost::sync_queue<int> &q, boost::shared_future<void> ready, boost::promise<void> &op_ready) :
+ q_(q), ready_(ready), op_ready_(op_ready)
+ {
+ }
+ typedef int result_type;
+ int operator()()
+ {
+ op_ready_.set_value();
+ ready_.wait();
+ return q_.pull();
+ }
+
+};
+
+void test_concurrent_push_and_pull_on_empty_queue()
+{
+ boost::sync_queue<int> q;
+
+ boost::promise<void> go, push_ready, pull_ready;
+ boost::shared_future<void> ready(go.get_future());
+
+ boost::future<void> push_done;
+ boost::future<int> pull_done;
+
+ try
+ {
+ push_done=boost::async(boost::launch::async,
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ [&q,ready,&push_ready]()
+ {
+ push_ready.set_value();
+ ready.wait();
+ q.push(42);
+ }
+#else
+ call_push(q,ready,push_ready)
+#endif
+ );
+ pull_done=boost::async(boost::launch::async,
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ [&q,ready,&pull_ready]()
+ {
+ pull_ready.set_value();
+ ready.wait();
+ return q.pull();
+ }
+#else
+ call_pull(q,ready,pull_ready)
+#endif
+ );
+ push_ready.get_future().wait();
+ pull_ready.get_future().wait();
+ go.set_value();
+
+ push_done.get();
+ BOOST_TEST_EQ(pull_done.get(), 42);
+ BOOST_TEST(q.empty());
+ }
+ catch (...)
+ {
+ go.set_value();
+ BOOST_TEST(false);
+ }
+}
+
+void test_concurrent_push_on_empty_queue()
+{
+ boost::sync_queue<int> q;
+ const unsigned int n = 3;
+ boost::promise<void> go;
+ boost::shared_future<void> ready(go.get_future());
+
+ boost::promise<void> push_ready[n];
+ boost::future<void> push_done[n];
+
+ try
+ {
+ for (unsigned int i =0; i< n; ++i)
+ push_done[i]=boost::async(boost::launch::async,
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ [&q,ready,&push_ready,i]()
+ {
+ push_ready[i].set_value();
+ ready.wait();
+ q.push(42);
+ }
+#else
+ call_push(q,ready,push_ready[i])
+#endif
+ );
+
+ for (unsigned int i = 0; i < n; ++i)
+ push_ready[i].get_future().wait();
+ go.set_value();
+
+ for (unsigned int i = 0; i < n; ++i)
+ push_done[i].get();
+ BOOST_TEST(!q.empty());
+ for (unsigned int i =0; i< n; ++i)
+ BOOST_TEST_EQ(q.pull(), 42);
+ BOOST_TEST(q.empty());
+
+ }
+ catch (...)
+ {
+ go.set_value();
+ BOOST_TEST(false);
+ }
+}
+
+void test_concurrent_pull_on_queue()
+{
+ boost::sync_queue<int> q;
+ const unsigned int n = 3;
+ boost::promise<void> go;
+ boost::shared_future<void> ready(go.get_future());
+
+ boost::promise<void> pull_ready[n];
+ boost::future<int> pull_done[n];
+
+ try
+ {
+ for (unsigned int i =0; i< n; ++i)
+ q.push(42);
+
+ for (unsigned int i =0; i< n; ++i)
+ pull_done[i]=boost::async(boost::launch::async,
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ [&q,ready,&pull_ready,i]()
+ {
+ pull_ready[i].set_value();
+ ready.wait();
+ return q.pull();
+ }
+#else
+ call_pull(q,ready,pull_ready[i])
+#endif
+ );
+
+ for (unsigned int i = 0; i < n; ++i)
+ pull_ready[i].get_future().wait();
+ go.set_value();
+
+ for (unsigned int i = 0; i < n; ++i)
+ BOOST_TEST_EQ(pull_done[i].get(), 42);
+ BOOST_TEST(q.empty());
+ }
+ catch (...)
+ {
+ go.set_value();
+ BOOST_TEST(false);
+ }
+}
+
+int main()
+{
+ test_concurrent_push_and_pull_on_empty_queue();
+ test_concurrent_push_on_empty_queue();
+ test_concurrent_pull_on_queue();
+
+ return boost::report_errors();
+}
+

Added: trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp 2013-06-23 16:47:03 EDT (Sun, 23 Jun 2013) (r84888)
@@ -0,0 +1,203 @@
+// Copyright (C) 2013 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)
+
+// <boost/thread/sync_queue.hpp>
+
+// class sync_queue<T>
+
+// sync_queue();
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/sync_queue.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ // default queue invariants
+ boost::sync_queue<int> q;
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_pull fails
+ boost::sync_queue<int> q;
+ int i;
+ BOOST_TEST(! q.try_pull(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_pull fails
+ boost::sync_queue<int> q;
+ BOOST_TEST(! q.try_pull());
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue succeeds
+ boost::sync_queue<int> q;
+ q.push(1);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue succeeds
+ boost::sync_queue<int> q;
+ q.push(1);
+ q.push(2);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 2);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push value succeeds
+ boost::sync_queue<int> q;
+ int i;
+ q.push(i);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::sync_queue<int> q;
+ BOOST_TEST(q.try_push(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push value succeeds
+ boost::sync_queue<int> q;
+ int i;
+ BOOST_TEST(q.try_push(i));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::sync_queue<int> q;
+ BOOST_TEST(q.try_push(boost::no_block, 1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_queue<int> q;
+ q.push(1);
+ int i;
+ q.pull(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_queue<int> q;
+ q.push(1);
+ int i = q.pull();
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_queue<int> q;
+ q.push(1);
+ int i;
+ BOOST_TEST(q.try_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_queue<int> q;
+ q.push(1);
+ int i;
+ BOOST_TEST(q.try_pull(boost::no_block, i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_queue<int> q;
+ q.push(1);
+ boost::shared_ptr<int> i = q.try_pull();
+ BOOST_TEST_EQ(*i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(! q.closed());
+ }
+
+ {
+ // closed invariants
+ boost::sync_queue<int> q;
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed queue push fails
+ boost::sync_queue<int> q;
+ q.close();
+ try {
+ q.push(1);
+ BOOST_TEST(false);
+ } catch (...) {
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(q.closed());
+ }
+ }
+ {
+ // 1-element closed queue pull succeed
+ boost::sync_queue<int> q;
+ q.push(1);
+ q.close();
+ int i;
+ q.pull(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0);
+ BOOST_TEST(q.closed());
+ }
+
+ return boost::report_errors();
+}
+


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