]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/fiber/test/test_unbuffered_channel_post.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / fiber / test / test_unbuffered_channel_post.cpp
CommitLineData
b32b8144
FG
1
2// Copyright Oliver Kowalke 2013.
3// Distributed under the Boost Software License, Version 1.0.
4// (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6
7#include <chrono>
8#include <sstream>
9#include <string>
10#include <vector>
11
12#include <boost/assert.hpp>
13#include <boost/test/unit_test.hpp>
14
15#include <boost/fiber/all.hpp>
16
17struct moveable {
18 bool state;
19 int value;
20
21 moveable() :
22 state( false),
23 value( -1) {
24 }
25
26 moveable( int v) :
27 state( true),
28 value( v) {
29 }
30
31 moveable( moveable && other) :
32 state( other.state),
33 value( other.value) {
34 other.state = false;
35 other.value = -1;
36 }
37
38 moveable & operator=( moveable && other) {
39 if ( this == & other) return * this;
40 state = other.state;
41 other.state = false;
42 value = other.value;
43 other.value = -1;
44 return * this;
45 }
46};
47
48void test_push() {
49 boost::fibers::unbuffered_channel< int > c;
50 boost::fibers::fiber f( boost::fibers::launch::post, [&c](){
51 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 1) );
52 });
53 int value = 0;
54 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( value) );
55 BOOST_CHECK_EQUAL( 1, value);
56 f.join();
57}
58
59void test_push_closed() {
60 boost::fibers::unbuffered_channel< int > c;
61 c.close();
62 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.push( 1) );
63}
64
65
66void test_push_wait_for() {
67 boost::fibers::unbuffered_channel< int > c;
68 boost::fibers::fiber f( boost::fibers::launch::post, [&c](){
69 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push_wait_for( 1, std::chrono::seconds( 1) ) );
70 });
71 int value = 0;
72 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( value) );
73 BOOST_CHECK_EQUAL( 1, value);
74 f.join();
75}
76
77void test_push_wait_for_closed() {
78 boost::fibers::unbuffered_channel< int > c;
79 c.close();
80 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.push_wait_for( 1, std::chrono::seconds( 1) ) );
81}
82
83void test_push_wait_for_timeout() {
84 boost::fibers::unbuffered_channel< int > c;
85 boost::fibers::fiber f( boost::fibers::launch::post, [&c](){
86 int value = 0;
87 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( value) );
88 BOOST_CHECK_EQUAL( 1, value);
89 });
90 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push_wait_for( 1, std::chrono::seconds( 1) ) );
91 BOOST_CHECK( boost::fibers::channel_op_status::timeout == c.push_wait_for( 1, std::chrono::seconds( 1) ) );
92 f.join();
93}
94
95void test_push_wait_until() {
96 boost::fibers::unbuffered_channel< int > c;
97 boost::fibers::fiber f( boost::fibers::launch::post, [&c](){
98 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push_wait_until( 1,
99 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
100 });
101 int value = 0;
102 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( value) );
103 BOOST_CHECK_EQUAL( 1, value);
104 f.join();
105}
106
107void test_push_wait_until_closed() {
108 boost::fibers::unbuffered_channel< int > c;
109 c.close();
110 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.push_wait_until( 1,
111 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
112}
113
114void test_push_wait_until_timeout() {
115 boost::fibers::unbuffered_channel< int > c;
116 boost::fibers::fiber f( boost::fibers::launch::post, [&c](){
117 int value = 0;
118 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( value) );
119 BOOST_CHECK_EQUAL( 1, value);
120 });
121 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push_wait_until( 1,
122 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
123 BOOST_CHECK( boost::fibers::channel_op_status::timeout == c.push_wait_until( 1,
124 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
125 f.join();
126}
127
128void test_pop() {
129 boost::fibers::unbuffered_channel< int > c;
130 int v1 = 2, v2 = 0;
131 boost::fibers::fiber f( boost::fibers::launch::post, [&v1,&c](){
132 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
133 });
134 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( v2) );
135 BOOST_CHECK_EQUAL( v1, v2);
136 f.join();
137}
138
139void test_pop_closed() {
140 boost::fibers::unbuffered_channel< int > c;
141 int v1 = 2, v2 = 0;
142 boost::fibers::fiber f( boost::fibers::launch::post, [&v1,&c](){
143 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
144 c.close();
145 });
146 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( v2) );
147 BOOST_CHECK_EQUAL( v1, v2);
148 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.pop( v2) );
149 f.join();
150}
151
152void test_pop_success() {
153 boost::fibers::unbuffered_channel< int > c;
154 int v1 = 2, v2 = 0;
155 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v2](){
156 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( v2) );
157 });
158 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
159 f.join();
160 BOOST_CHECK_EQUAL( v1, v2);
161}
162
163void test_value_pop() {
164 boost::fibers::unbuffered_channel< int > c;
165 int v1 = 2, v2 = 0;
166 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v1](){
167 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
168 });
169 v2 = c.value_pop();
170 f.join();
171 BOOST_CHECK_EQUAL( v1, v2);
172}
173
174void test_value_pop_closed() {
175 boost::fibers::unbuffered_channel< int > c;
176 int v1 = 2;
177 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v1](){
178 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
179 c.close();
180 });
181 int v2 = c.value_pop();
182 BOOST_CHECK_EQUAL( v1, v2);
183 f.join();
184 bool thrown = false;
185 try {
186 c.value_pop();
187 } catch ( boost::fibers::fiber_error const&) {
188 thrown = true;
189 }
190 BOOST_CHECK( thrown);
191}
192
193void test_value_pop_success() {
194 boost::fibers::unbuffered_channel< int > c;
195 int v1 = 2, v2 = 0;
196 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v2](){
197 v2 = c.value_pop();
198 });
199 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
200 f.join();
201 BOOST_CHECK_EQUAL( v1, v2);
202}
203
204void test_pop_wait_for() {
205 boost::fibers::unbuffered_channel< int > c;
206 int v1 = 2, v2 = 0;
207 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v1](){
208 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
209 });
210 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_for( v2, std::chrono::seconds( 1) ) );
211 f.join();
212 BOOST_CHECK_EQUAL( v1, v2);
213}
214
215void test_pop_wait_for_closed() {
216 boost::fibers::unbuffered_channel< int > c;
217 int v1 = 2, v2 = 0;
218 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v1](){
219 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
220 c.close();
221 });
222 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_for( v2, std::chrono::seconds( 1) ) );
223 BOOST_CHECK_EQUAL( v1, v2);
224 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.pop_wait_for( v2, std::chrono::seconds( 1) ) );
225 f.join();
226}
227
228void test_pop_wait_for_success() {
229 boost::fibers::unbuffered_channel< int > c;
230 int v1 = 2, v2 = 0;
231 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v2](){
232 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_for( v2, std::chrono::seconds( 1) ) );
233 });
234 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
235 f.join();
236 BOOST_CHECK_EQUAL( v1, v2);
237}
238
239void test_pop_wait_for_timeout() {
240 boost::fibers::unbuffered_channel< int > c;
241 int v = 0;
242 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v](){
243 BOOST_CHECK( boost::fibers::channel_op_status::timeout == c.pop_wait_for( v, std::chrono::seconds( 1) ) );
244 });
245 f.join();
246}
247
248void test_pop_wait_until() {
249 boost::fibers::unbuffered_channel< int > c;
250 int v1 = 2, v2 = 0;
251 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v1](){
252 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
253 });
254 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_until( v2,
255 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
256 BOOST_CHECK_EQUAL( v1, v2);
257 f.join();
258}
259
260void test_pop_wait_until_closed() {
261 boost::fibers::unbuffered_channel< int > c;
262 int v1 = 2, v2 = 0;
263 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v1](){
264 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
265 c.close();
266 });
267 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_until( v2,
268 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
269 BOOST_CHECK_EQUAL( v1, v2);
270 BOOST_CHECK( boost::fibers::channel_op_status::closed == c.pop_wait_until( v2,
271 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
272 f.join();
273}
274
275void test_pop_wait_until_success() {
276 boost::fibers::unbuffered_channel< int > c;
277 int v1 = 2, v2 = 0;
278 boost::fibers::fiber f( boost::fibers::launch::post, [&c,&v2](){
279 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop_wait_until( v2,
280 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
281 });
282 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( v1) );
283 f.join();
284 BOOST_CHECK_EQUAL( v1, v2);
285}
286
287void test_pop_wait_until_timeout() {
288 boost::fibers::unbuffered_channel< int > c;
289 int v = 0;
290 BOOST_CHECK(
291 boost::fibers::channel_op_status::timeout == c.pop_wait_until( v,
292 std::chrono::system_clock::now() + std::chrono::seconds( 1) ) );
293}
294
295void test_wm_1() {
296 boost::fibers::unbuffered_channel< int > c;
297 std::vector< boost::fibers::fiber::id > ids;
298 boost::fibers::fiber f1( boost::fibers::launch::post, [&c,&ids](){
299 ids.push_back( boost::this_fiber::get_id() );
300 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 1) );
301
302 ids.push_back( boost::this_fiber::get_id() );
303 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 2) );
304
305 ids.push_back( boost::this_fiber::get_id() );
306 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 3) );
307
308 ids.push_back( boost::this_fiber::get_id() );
309 // would be blocked because channel is full
310 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 4) );
311
312 ids.push_back( boost::this_fiber::get_id() );
313 // would be blocked because channel is full
314 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( 5) );
315
316 ids.push_back( boost::this_fiber::get_id() );
317 });
318 boost::fibers::fiber f2( boost::fibers::launch::post, [&c,&ids](){
319 ids.push_back( boost::this_fiber::get_id() );
320 BOOST_CHECK_EQUAL( 1, c.value_pop() );
321
322 // let other fiber run
323 boost::this_fiber::yield();
324
325 ids.push_back( boost::this_fiber::get_id() );
326 BOOST_CHECK_EQUAL( 2, c.value_pop() );
327
328 ids.push_back( boost::this_fiber::get_id() );
329 BOOST_CHECK_EQUAL( 3, c.value_pop() );
330
331 ids.push_back( boost::this_fiber::get_id() );
332 BOOST_CHECK_EQUAL( 4, c.value_pop() );
333
334 ids.push_back( boost::this_fiber::get_id() );
335 // would block because channel is empty
336 BOOST_CHECK_EQUAL( 5, c.value_pop() );
337
338 ids.push_back( boost::this_fiber::get_id() );
339 });
340 boost::fibers::fiber::id id1 = f1.get_id();
341 boost::fibers::fiber::id id2 = f2.get_id();
342 f1.join();
343 f2.join();
344 BOOST_CHECK_EQUAL( 12u, ids.size() );
345 BOOST_CHECK_EQUAL( id1, ids[0]);
346 BOOST_CHECK_EQUAL( id2, ids[1]);
347 BOOST_CHECK_EQUAL( id1, ids[2]);
348 BOOST_CHECK_EQUAL( id2, ids[3]);
349 BOOST_CHECK_EQUAL( id2, ids[4]);
350 BOOST_CHECK_EQUAL( id1, ids[5]);
351 BOOST_CHECK_EQUAL( id2, ids[6]);
352 BOOST_CHECK_EQUAL( id1, ids[7]);
353 BOOST_CHECK_EQUAL( id2, ids[8]);
354 BOOST_CHECK_EQUAL( id1, ids[9]);
355 BOOST_CHECK_EQUAL( id2, ids[10]);
356 BOOST_CHECK_EQUAL( id1, ids[11]);
357}
358
359void test_moveable() {
360 boost::fibers::unbuffered_channel< moveable > c;
361 boost::fibers::fiber f( boost::fibers::launch::post, [&c]{
362 moveable m1( 3);
363 BOOST_CHECK( m1.state);
364 BOOST_CHECK_EQUAL( 3, m1.value);
365 BOOST_CHECK( boost::fibers::channel_op_status::success == c.push( std::move( m1) ) );
366 });
367 moveable m2;
368 BOOST_CHECK( ! m2.state);
369 BOOST_CHECK_EQUAL( -1, m2.value);
370 BOOST_CHECK( boost::fibers::channel_op_status::success == c.pop( m2) );
371 BOOST_CHECK( m2.state);
372 BOOST_CHECK_EQUAL( 3, m2.value);
373 f.join();
374}
375
376void test_rangefor() {
377 boost::fibers::unbuffered_channel< int > chan;
378 std::vector< int > vec;
379 boost::fibers::fiber f1( boost::fibers::launch::post, [&chan]{
380 chan.push( 1);
381 chan.push( 1);
382 chan.push( 2);
383 chan.push( 3);
384 chan.push( 5);
385 chan.push( 8);
386 chan.push( 12);
387 chan.close();
388 });
389 boost::fibers::fiber f2( boost::fibers::launch::post, [&vec,&chan]{
390 for ( int value : chan) {
391 vec.push_back( value);
392 }
393 });
394 f1.join();
395 f2.join();
396 BOOST_CHECK_EQUAL( 1, vec[0]);
397 BOOST_CHECK_EQUAL( 1, vec[1]);
398 BOOST_CHECK_EQUAL( 2, vec[2]);
399 BOOST_CHECK_EQUAL( 3, vec[3]);
400 BOOST_CHECK_EQUAL( 5, vec[4]);
401 BOOST_CHECK_EQUAL( 8, vec[5]);
402 BOOST_CHECK_EQUAL( 12, vec[6]);
403}
404
92f5a8d4
TL
405void test_issue_181() {
406 boost::fibers::unbuffered_channel< int > chan;
407 boost::fibers::fiber f1( boost::fibers::launch::post, [&chan]() {
408 auto state = chan.push( 1);
409 BOOST_CHECK( boost::fibers::channel_op_status::closed == state);
410 });
411 boost::fibers::fiber f2( boost::fibers::launch::post, [&chan]() {
412 boost::this_fiber::sleep_for( std::chrono::milliseconds( 100) );
413 chan.close();
414 });
415 f2.join();
416 f1.join();
417}
418
b32b8144
FG
419boost::unit_test::test_suite * init_unit_test_suite( int, char* []) {
420 boost::unit_test::test_suite * test =
421 BOOST_TEST_SUITE("Boost.Fiber: unbuffered_channel test suite");
422
423 test->add( BOOST_TEST_CASE( & test_push) );
424 test->add( BOOST_TEST_CASE( & test_push_closed) );
425 test->add( BOOST_TEST_CASE( & test_push_wait_for) );
426 test->add( BOOST_TEST_CASE( & test_push_wait_for_closed) );
427 test->add( BOOST_TEST_CASE( & test_push_wait_for_timeout) );
428 test->add( BOOST_TEST_CASE( & test_push_wait_until) );
429 test->add( BOOST_TEST_CASE( & test_push_wait_until_closed) );
430 test->add( BOOST_TEST_CASE( & test_push_wait_until_timeout) );
431 test->add( BOOST_TEST_CASE( & test_pop) );
432 test->add( BOOST_TEST_CASE( & test_pop_closed) );
433 test->add( BOOST_TEST_CASE( & test_pop_success) );
434 test->add( BOOST_TEST_CASE( & test_value_pop) );
435 test->add( BOOST_TEST_CASE( & test_value_pop_closed) );
436 test->add( BOOST_TEST_CASE( & test_value_pop_success) );
437 test->add( BOOST_TEST_CASE( & test_pop_wait_for) );
438 test->add( BOOST_TEST_CASE( & test_pop_wait_for_closed) );
439 test->add( BOOST_TEST_CASE( & test_pop_wait_for_success) );
440 test->add( BOOST_TEST_CASE( & test_pop_wait_for_timeout) );
441 test->add( BOOST_TEST_CASE( & test_pop_wait_until) );
442 test->add( BOOST_TEST_CASE( & test_pop_wait_until_closed) );
443 test->add( BOOST_TEST_CASE( & test_pop_wait_until_success) );
444 test->add( BOOST_TEST_CASE( & test_pop_wait_until_timeout) );
445 test->add( BOOST_TEST_CASE( & test_wm_1) );
446 test->add( BOOST_TEST_CASE( & test_moveable) );
447 test->add( BOOST_TEST_CASE( & test_rangefor) );
92f5a8d4 448 test->add( BOOST_TEST_CASE( & test_issue_181) );
b32b8144
FG
449
450 return test;
451}