// Copyright Oliver Kowalke 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) #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace pt = boost::posix_time; namespace tsk = boost::tasks; boost::uint32_t wait_fn( boost::uint32_t n, tsk::spin::auto_reset_event & ev) { ev.wait(); return n; } // check wait in new thread void test_case_1() { boost::uint32_t n = 3; tsk::spin::auto_reset_event ev; tsk::handle< boost::uint32_t > h1( tsk::async( tsk::make_task( wait_fn, n, boost::ref( ev) ), tsk::new_thread() ) ); tsk::handle< boost::uint32_t > h2( tsk::async( tsk::make_task( wait_fn, n, boost::ref( ev) ), tsk::new_thread() ) ); boost::this_thread::sleep( pt::millisec( 250) ); BOOST_CHECK( ! h1.is_ready() ); BOOST_CHECK( ! h2.is_ready() ); ev.set(); boost::this_thread::sleep( pt::millisec( 250) ); BOOST_CHECK( h1.is_ready() || h2.is_ready() ); if ( h1.is_ready() ) { BOOST_CHECK_EQUAL( h1.get(), n); BOOST_CHECK( ! h2.is_ready() ); ev.set(); boost::this_thread::sleep( pt::millisec( 250) ); BOOST_CHECK( h2.is_ready() ); BOOST_CHECK_EQUAL( h2.get(), n); } else { BOOST_CHECK( h2.is_ready() ); BOOST_CHECK_EQUAL( h2.get(), n); BOOST_CHECK( ! h1.is_ready() ); ev.set(); boost::this_thread::sleep( pt::millisec( 250) ); BOOST_CHECK( h1.is_ready() ); BOOST_CHECK_EQUAL( h1.get(), n); } } // check wait in pool void test_case_2() { tsk::static_pool< tsk::unbounded_fifo > pool( tsk::poolsize( 3) ); boost::uint32_t n = 3; tsk::spin::auto_reset_event ev; tsk::handle< boost::uint32_t > h1( tsk::async( tsk::make_task( wait_fn, n, boost::ref( ev) ), pool) ); tsk::handle< boost::uint32_t > h2( tsk::async( tsk::make_task( wait_fn, n, boost::ref( ev) ), pool) ); boost::this_thread::sleep( pt::millisec( 250) ); BOOST_CHECK( ! h1.is_ready() ); BOOST_CHECK( ! h2.is_ready() ); ev.set(); boost::this_thread::sleep( pt::millisec( 250) ); BOOST_CHECK( h1.is_ready() || h2.is_ready() ); if ( h1.is_ready() ) { BOOST_CHECK_EQUAL( h1.get(), n); BOOST_CHECK( ! h2.is_ready() ); ev.set(); boost::this_thread::sleep( pt::millisec( 250) ); BOOST_CHECK( h2.is_ready() ); BOOST_CHECK_EQUAL( h2.get(), n); } else { BOOST_CHECK( h2.is_ready() ); BOOST_CHECK_EQUAL( h2.get(), n); BOOST_CHECK( ! h1.is_ready() ); ev.set(); boost::this_thread::sleep( pt::millisec( 250) ); BOOST_CHECK( h1.is_ready() ); BOOST_CHECK_EQUAL( h1.get(), n); } } void test_case_3() { boost::uint32_t n = 3; tsk::spin::auto_reset_event ev( true); tsk::handle< boost::uint32_t > h1( tsk::async( tsk::make_task( wait_fn, n, boost::ref( ev) ), tsk::new_thread() ) ); tsk::handle< boost::uint32_t > h2( tsk::async( tsk::make_task( wait_fn, n, boost::ref( ev) ), tsk::new_thread() ) ); boost::this_thread::sleep( pt::millisec( 250) ); BOOST_CHECK( h1.is_ready() || h2.is_ready() ); if ( h1.is_ready() ) { BOOST_CHECK_EQUAL( h1.get(), n); BOOST_CHECK( ! h2.is_ready() ); ev.set(); boost::this_thread::sleep( pt::millisec( 250) ); BOOST_CHECK( h2.is_ready() ); BOOST_CHECK_EQUAL( h2.get(), n); } else { BOOST_CHECK( h2.is_ready() ); BOOST_CHECK_EQUAL( h2.get(), n); BOOST_CHECK( ! h1.is_ready() ); ev.set(); boost::this_thread::sleep( pt::millisec( 250) ); BOOST_CHECK( h1.is_ready() ); BOOST_CHECK_EQUAL( h1.get(), n); } } void test_case_4() { tsk::spin::auto_reset_event ev; BOOST_CHECK_EQUAL( false, ev.try_wait() ); ev.set(); BOOST_CHECK_EQUAL( true, ev.try_wait() ); BOOST_CHECK_EQUAL( false, ev.try_wait() ); } boost::unit_test::test_suite * init_unit_test_suite( int, char* []) { boost::unit_test::test_suite * test = BOOST_TEST_SUITE("Boost.Task: spin-auto-reset-event test suite"); test->add( BOOST_TEST_CASE( & test_case_1) ); test->add( BOOST_TEST_CASE( & test_case_2) ); test->add( BOOST_TEST_CASE( & test_case_3) ); return test; }