summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp
diff options
context:
space:
mode:
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.cpp297
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();
+}
+
+