bug_000008.cpp 2.6 KB

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