diff options
Diffstat (limited to 'src/boost/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp')
-rw-r--r-- | src/boost/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp new file mode 100644 index 000000000..ac7b80769 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp @@ -0,0 +1,297 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// 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/once.hpp> + +// struct once_flag; + +// template<class Callable, class ...Args> +// void call_once(once_flag& flag, Callable&& func, Args&&... args); + +//#define BOOST_THREAD_VERSION 4 +#define BOOST_THREAD_USES_MOVE +#define BOOST_THREAD_PROVIDES_ONCE_CXX11 + +#include <boost/thread/once.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> + +#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 +#define BOOST_INIT_ONCE_INIT +#else +#define BOOST_INIT_ONCE_INIT =BOOST_ONCE_INIT +#endif + +typedef boost::chrono::milliseconds ms; + +boost::once_flag flg0 BOOST_INIT_ONCE_INIT; + +int init0_called = 0; + +void init0() +{ + boost::this_thread::sleep_for(ms(250)); + ++init0_called; +} + +void f0() +{ + boost::call_once(flg0, init0); +} + +boost::once_flag flg3 BOOST_INIT_ONCE_INIT; + +int init3_called = 0; +int init3_completed = 0; + +void init3() +{ + ++init3_called; + boost::this_thread::sleep_for(ms(250)); + if (init3_called == 1) + throw 1; + ++init3_completed; +} + +void f3() +{ + try + { + boost::call_once(flg3, init3); + } + catch (...) + { + } +} + +struct init1 +{ + static int called; + typedef void result_type; + + void operator()(int i) {called += i;} + void operator()(int i) const {called += i;} +}; + +int init1::called = 0; + +boost::once_flag flg1 BOOST_INIT_ONCE_INIT; + +void f1() +{ + boost::call_once(flg1, init1(), 1); +} + +boost::once_flag flg1_member BOOST_INIT_ONCE_INIT; + +struct init1_member +{ + static int called; + typedef void result_type; + void call(int i) { + called += i; + } +}; +int init1_member::called = 0; + +void f1_member_l() +{ + init1_member o; + int i=1; + boost::call_once(flg1_member, &init1_member::call, o, i); +} +void f1_member_r() +{ + init1_member o; + boost::call_once(flg1_member, &init1_member::call, o, 1); +} +struct init2 +{ + static int called; + typedef void result_type; + + void operator()(int i, int j) {called += i + j;} + void operator()(int i, int j) const {called += i + j;} +}; + +int init2::called = 0; + +boost::once_flag flg2 BOOST_INIT_ONCE_INIT; + +void f2() +{ + boost::call_once(flg2, init2(), 2, 3); + boost::call_once(flg2, init2(), 4, 5); +} + +boost::once_flag flg41 BOOST_INIT_ONCE_INIT; +boost::once_flag flg42 BOOST_INIT_ONCE_INIT; + +int init41_called = 0; +int init42_called = 0; + +void init42(); + +void init41() +{ + boost::this_thread::sleep_for(ms(250)); + ++init41_called; +} + +void init42() +{ + boost::this_thread::sleep_for(ms(250)); + ++init42_called; +} + +void f41() +{ + boost::call_once(flg41, init41); + boost::call_once(flg42, init42); +} + +void f42() +{ + boost::call_once(flg42, init42); + boost::call_once(flg41, init41); +} + +class MoveOnly +{ +public: + typedef void result_type; + + BOOST_THREAD_MOVABLE_ONLY(MoveOnly) + MoveOnly() + { + } + MoveOnly(BOOST_THREAD_RV_REF(MoveOnly)) + {} + + void operator()(BOOST_THREAD_RV_REF(MoveOnly)) + { + } + void operator()(int) + { + } + void operator()() + { + } +}; + + +struct id_string +{ + static boost::once_flag flag; + static void do_init(id_string & ) + {} + void operator()() + { + boost::call_once(flag, &id_string::do_init, boost::ref(*this)); + } +// void operator()(int,int) +// { +// // This should fail but works with gcc-4.6.3 +// //std::bind(&id_string::do_init, *this)(); +// std::bind(&id_string::do_init, std::ref(*this))(); +// } +// void operator()(int) const +// { +// //std::bind(&id_string::do_init, *this)(); +// } +}; + + +boost::once_flag id_string::flag BOOST_INIT_ONCE_INIT; + +int main() +{ + + // + { + id_string id; + id(); + //id(1,1); + } + // check basic functionality + { + boost::thread t0(f0); + boost::thread t1(f0); + t0.join(); + t1.join(); + BOOST_TEST(init0_called == 1); + } + // check basic exception safety + { + boost::thread t0(f3); + boost::thread t1(f3); + t0.join(); + t1.join(); + BOOST_TEST(init3_called == 2); + BOOST_TEST(init3_completed == 1); + } + // check deadlock avoidance + { + boost::thread t0(f41); + boost::thread t1(f42); + t0.join(); + t1.join(); + BOOST_TEST(init41_called == 1); + BOOST_TEST(init42_called == 1); + } + // check functors with 1 arg + { + boost::thread t0(f1); + boost::thread t1(f1); + t0.join(); + t1.join(); + BOOST_TEST(init1::called == 1); + } + // check functors with 2 args + { + boost::thread t0(f2); + boost::thread t1(f2); + t0.join(); + t1.join(); + BOOST_TEST(init2::called == 5); + } + + // check member function with 1 arg + { + boost::thread t0(f1_member_l); + boost::thread t1(f1_member_r); + t0.join(); + t1.join(); + BOOST_TEST(init1_member::called == 1); + } +#if defined BOOST_THREAD_PLATFORM_PTHREAD || (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ > 40600) + { + boost::once_flag f BOOST_INIT_ONCE_INIT; + boost::call_once(f, MoveOnly()); + } +#endif +#if defined BOOST_THREAD_PROVIDES_INVOKE + { + boost::once_flag f BOOST_INIT_ONCE_INIT; + boost::call_once(f, MoveOnly(), 1); + } + { + boost::once_flag f BOOST_INIT_ONCE_INIT; + boost::call_once(f, MoveOnly(), MoveOnly()); + } +#endif // BOOST_THREAD_PLATFORM_PTHREAD + return boost::report_errors(); +} + + |