1 /*============================================================================= 2 Copyright (c) 2003 Martin Wille 3 Copyright (c) 2001-2007 Joel de Guzman 4 Copyright (c) 2015 John Fletcher 5 6 Distributed under the Boost Software License, Version 1.0. (See accompanying 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 =============================================================================*/ 9 10 // see http://article.gmane.org/gmane.comp.parsers.spirit.general/4575 11 // or https://sf.net/mailarchive/forum.php?thread_id=2692308&forum_id=1595 12 // for a description of the bug being tested for by this program 13 // 14 // This code is borrowed from Spirit's bug_000008.cpp test for multithreads. 15 // Now modified to point to the Phoenix headers 16 // instead of the ones in Spirit. 17 #include <iostream> 18 #include <boost/config.hpp> 19 #include <boost/assert.hpp> 20 #include <boost/detail/lightweight_test.hpp> 21 // Testing problems in thread/future 22 //#include <boost/move/move.hpp> 23 //#include <boost/move/detail/type_traits.hpp> 24 //using boost::move_detail::is_copy_constructible; 25 #include <boost/phoenix/scope/dynamic.hpp> 26 27 #if defined(DONT_HAVE_BOOST) \ 28 || !defined(BOOST_HAS_THREADS) \ 29 || defined(BOOST_DISABLE_THREADS) \ 30 || (defined(__GNUC__) && defined(__WIN32__)) // MinGW 31 #define SKIP_TEST 32 #endif 33 34 35 #if defined(SKIP_TEST) 36 // we end here if we can't do multithreading skipped()37static void skipped() 38 { 39 std::cout << "skipped\n"; 40 } 41 42 int main()43main() 44 { 45 skipped(); 46 return boost::report_errors(); 47 } 48 49 #else 50 // the real MT stuff 51 52 #include <boost/phoenix/operator.hpp> 53 #include <boost/phoenix/scope.hpp> 54 #include <boost/thread.hpp> 55 56 static const int number_of_calls_per_thread=20000; 57 58 struct test_dynamic : boost::phoenix::dynamic<int> 59 { 60 // test_dynamic() : b(*this) {} test_dynamictest_dynamic61 test_dynamic() : b(init<0>(this)) {} 62 member1 b; 63 }; 64 65 void in_thread(void)66in_thread(void) 67 { 68 test_dynamic s; // should now be a local 69 70 for (int i = 0; i < number_of_calls_per_thread; ++i) 71 { 72 boost::phoenix::dynamic_frame<test_dynamic::self_type> frame(s); 73 (s.b = 123)(); 74 { 75 boost::phoenix::dynamic_frame<test_dynamic::self_type> frame(s); 76 (s.b = 456)(); 77 BOOST_ASSERT((s.b == 456)()); 78 } 79 BOOST_ASSERT((s.b == 123)()); 80 } 81 } 82 83 void bug_000008()84bug_000008() 85 { 86 boost::thread t1(in_thread); 87 boost::thread t2(in_thread); 88 boost::thread t3(in_thread); 89 boost::thread t4(in_thread); 90 91 t1.join(); 92 t2.join(); 93 t3.join(); 94 t4.join(); 95 } 96 97 int main()98main() 99 { 100 bug_000008(); 101 return boost::report_errors(); 102 } 103 104 #endif 105 106