1 // Copyright (C) 2013 Vicente J. Botet Escriba
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 // <boost/thread/sync_queue.hpp>
12 #include <boost/config.hpp>
13 #if ! defined BOOST_NO_CXX11_DECLTYPE
14 #define BOOST_RESULT_OF_USE_DECLTYPE
17 #define BOOST_THREAD_VERSION 4
19 #include <boost/thread/sync_queue.hpp>
20 #include <boost/thread/future.hpp>
21 #include <boost/thread/barrier.hpp>
23 #include <boost/detail/lightweight_test.hpp>
25 template <typename ValueType
>
28 boost::sync_queue
<ValueType
> *q_
;
31 call_push(boost::sync_queue
<ValueType
> *q
, boost::barrier
*go
) :
35 typedef void result_type
;
38 go_
->count_down_and_wait();
43 template <typename ValueType
>
46 boost::sync_queue
<ValueType
> *q_
;
49 call_pull(boost::sync_queue
<ValueType
> *q
, boost::barrier
*go
) :
53 typedef ValueType result_type
;
54 ValueType
operator()()
56 go_
->count_down_and_wait();
61 template <typename ValueType
>
64 boost::sync_queue
<ValueType
> *q_
;
67 call_wait_pull(boost::sync_queue
<ValueType
> *q
, boost::barrier
*go
) :
71 typedef boost::queue_op_status result_type
;
72 boost::queue_op_status
operator()(ValueType
& v
)
75 return q_
->wait_pull(v
);
79 void test_concurrent_push_and_pull_on_empty_queue()
81 boost::sync_queue
<int> q
;
85 boost::future
<void> push_done
;
86 boost::future
<int> pull_done
;
90 push_done
=boost::async(boost::launch::async
,
91 call_push
<int>(&q
,&go
));
92 pull_done
=boost::async(boost::launch::async
,
93 call_pull
<int>(&q
,&go
));
96 BOOST_TEST_EQ(pull_done
.get(), 42);
97 BOOST_TEST(q
.empty());
105 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
106 void test_concurrent_push_and_wait_pull_on_empty_queue()
108 boost::sync_queue
<int> q
;
109 const unsigned int n
= 3;
110 boost::barrier
go(n
);
112 boost::future
<boost::queue_op_status
> pull_done
[n
];
117 for (unsigned int i
=0; i
< n
; ++i
)
118 pull_done
[i
]=boost::async(boost::launch::async
,
119 call_wait_pull
<int>(&q
,&go
),
120 boost::ref(results
[i
]));
122 for (unsigned int i
=0; i
< n
; ++i
)
125 for (unsigned int i
= 0; i
< n
; ++i
) {
126 BOOST_TEST(pull_done
[i
].get() == boost::queue_op_status::success
);
127 BOOST_TEST_EQ(results
[i
], 42);
129 BOOST_TEST(q
.empty());
137 void test_concurrent_wait_pull_and_close_on_empty_queue()
139 boost::sync_queue
<int> q
;
140 const unsigned int n
= 3;
141 boost::barrier
go(n
);
143 boost::future
<boost::queue_op_status
> pull_done
[n
];
148 for (unsigned int i
=0; i
< n
; ++i
)
149 pull_done
[i
]=boost::async(boost::launch::async
,
150 call_wait_pull
<int>(&q
,&go
),
151 boost::ref(results
[i
]));
155 for (unsigned int i
= 0; i
< n
; ++i
) {
156 BOOST_TEST(pull_done
[i
].get() == boost::queue_op_status::closed
);
158 BOOST_TEST(q
.empty());
167 void test_concurrent_push_on_empty_queue()
169 boost::sync_queue
<int> q
;
170 const unsigned int n
= 3;
171 boost::barrier
go(n
);
172 boost::future
<void> push_done
[n
];
176 for (unsigned int i
=0; i
< n
; ++i
)
177 push_done
[i
]=boost::async(boost::launch::async
,
178 call_push
<int>(&q
,&go
));
187 for (unsigned int i
= 0; i
< n
; ++i
)
197 BOOST_TEST(!q
.empty());
198 for (unsigned int i
=0; i
< n
; ++i
)
199 BOOST_TEST_EQ(q
.pull(), 42);
200 BOOST_TEST(q
.empty());
209 void test_concurrent_pull_on_queue()
211 boost::sync_queue
<int> q
;
212 const unsigned int n
= 3;
213 boost::barrier
go(n
);
215 boost::future
<int> pull_done
[n
];
219 for (unsigned int i
=0; i
< n
; ++i
)
222 for (unsigned int i
=0; i
< n
; ++i
)
223 pull_done
[i
]=boost::async(boost::launch::async
,
224 #if ! defined BOOST_NO_CXX11_LAMBDAS
231 call_pull
<int>(&q
,&go
)
235 for (unsigned int i
= 0; i
< n
; ++i
)
236 BOOST_TEST_EQ(pull_done
[i
].get(), 42);
237 BOOST_TEST(q
.empty());
247 test_concurrent_push_and_pull_on_empty_queue();
248 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
249 test_concurrent_push_and_wait_pull_on_empty_queue();
250 test_concurrent_wait_pull_and_close_on_empty_queue();
252 test_concurrent_push_on_empty_queue();
253 test_concurrent_pull_on_queue();
254 return boost::report_errors();