mirror of
https://github.com/boostorg/thread.git
synced 2026-02-08 23:22:13 +00:00
Merge from trunk
[SVN r39987]
This commit is contained in:
@@ -49,6 +49,103 @@ void test_call_once()
|
||||
BOOST_CHECK_EQUAL(var_to_init,1);
|
||||
}
|
||||
|
||||
int var_to_init_with_functor=0;
|
||||
|
||||
struct increment_value
|
||||
{
|
||||
int* value;
|
||||
explicit increment_value(int* value_):
|
||||
value(value_)
|
||||
{}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m);
|
||||
++(*value);
|
||||
}
|
||||
};
|
||||
|
||||
void call_once_with_functor()
|
||||
{
|
||||
unsigned const loop_count=100;
|
||||
int my_once_value=0;
|
||||
static boost::once_flag functor_flag=BOOST_ONCE_INIT;
|
||||
for(unsigned i=0;i<loop_count;++i)
|
||||
{
|
||||
boost::call_once(functor_flag, increment_value(&var_to_init_with_functor));
|
||||
my_once_value=var_to_init_with_functor;
|
||||
if(my_once_value!=1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
boost::mutex::scoped_lock lock(m);
|
||||
BOOST_CHECK_EQUAL(my_once_value, 1);
|
||||
}
|
||||
|
||||
void test_call_once_arbitrary_functor()
|
||||
{
|
||||
unsigned const num_threads=100;
|
||||
boost::thread_group group;
|
||||
|
||||
for(unsigned i=0;i<num_threads;++i)
|
||||
{
|
||||
group.create_thread(&call_once_with_functor);
|
||||
}
|
||||
group.join_all();
|
||||
BOOST_CHECK_EQUAL(var_to_init_with_functor,1);
|
||||
}
|
||||
|
||||
|
||||
struct throw_before_third_pass
|
||||
{
|
||||
struct my_exception
|
||||
{};
|
||||
|
||||
static unsigned pass_counter;
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m);
|
||||
++pass_counter;
|
||||
if(pass_counter<3)
|
||||
{
|
||||
throw my_exception();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
unsigned throw_before_third_pass::pass_counter=0;
|
||||
unsigned exception_counter=0;
|
||||
|
||||
void call_once_with_exception()
|
||||
{
|
||||
static boost::once_flag functor_flag=BOOST_ONCE_INIT;
|
||||
try
|
||||
{
|
||||
boost::call_once(functor_flag, throw_before_third_pass());
|
||||
}
|
||||
catch(throw_before_third_pass::my_exception)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m);
|
||||
++exception_counter;
|
||||
}
|
||||
}
|
||||
|
||||
void test_call_once_retried_on_exception()
|
||||
{
|
||||
unsigned const num_threads=100;
|
||||
boost::thread_group group;
|
||||
|
||||
for(unsigned i=0;i<num_threads;++i)
|
||||
{
|
||||
group.create_thread(&call_once_with_exception);
|
||||
}
|
||||
group.join_all();
|
||||
BOOST_CHECK_EQUAL(throw_before_third_pass::pass_counter,3);
|
||||
BOOST_CHECK_EQUAL(exception_counter,2);
|
||||
}
|
||||
|
||||
|
||||
boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
@@ -56,6 +153,8 @@ boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
|
||||
BOOST_TEST_SUITE("Boost.Threads: call_once test suite");
|
||||
|
||||
test->add(BOOST_TEST_CASE(test_call_once));
|
||||
test->add(BOOST_TEST_CASE(test_call_once_arbitrary_functor));
|
||||
test->add(BOOST_TEST_CASE(test_call_once_retried_on_exception));
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user