bug_000008.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*=============================================================================
  2. Copyright (c) 2003 Martin Wille
  3. http://spirit.sourceforge.net/
  4. Use, modification and distribution is subject to the Boost Software
  5. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. 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. // the problem should be solved with version 1.3 of phoenix/closures.hpp>
  13. #if defined(BOOST_SPIRIT_DEBUG) && defined(__GNUC__) && defined(__WIN32__)
  14. // It seems that MinGW has some problems with threads and iostream ?
  15. // This code crashes MinGW when BOOST_SPIRIT_DEBUG is defined. The reason
  16. // is beyond me. Disable BOOST_SPIRIT_DEBUG for now.
  17. #undef BOOST_SPIRIT_DEBUG
  18. #endif
  19. #include <iostream>
  20. #include <boost/config.hpp>
  21. #include <boost/detail/lightweight_test.hpp>
  22. #if defined(DONT_HAVE_BOOST) || !defined(BOOST_HAS_THREADS) || defined(BOOST_DISABLE_THREADS)
  23. // we end here if we can't do multithreading
  24. static void skipped()
  25. {
  26. std::cout << "skipped\n";
  27. }
  28. int
  29. main()
  30. {
  31. skipped();
  32. return boost::report_errors();
  33. }
  34. #else
  35. // the real MT stuff
  36. #undef BOOST_SPIRIT_THREADSAFE
  37. #define BOOST_SPIRIT_THREADSAFE
  38. #undef PHOENIX_THREADSAFE
  39. #define PHOENIX_THREADSAFE
  40. #include <boost/spirit/include/classic_core.hpp>
  41. #include <boost/spirit/include/classic_closure.hpp>
  42. #include <boost/thread.hpp>
  43. static const int number_of_calls_to_parse_per_thread=20000;
  44. struct test_closure
  45. : BOOST_SPIRIT_CLASSIC_NS::closure<test_closure, char const*>
  46. {
  47. member1 b;
  48. };
  49. struct test_grammar
  50. : BOOST_SPIRIT_CLASSIC_NS::grammar<test_grammar, test_closure::context_t>
  51. {
  52. test_grammar() {}
  53. template <typename ScannerT>
  54. struct definition
  55. {
  56. definition(test_grammar const &self)
  57. {
  58. using namespace phoenix;
  59. rule = BOOST_SPIRIT_CLASSIC_NS::epsilon_p[self.b = arg1];
  60. }
  61. BOOST_SPIRIT_CLASSIC_NS::rule<ScannerT> const &start() const { return rule; }
  62. BOOST_SPIRIT_CLASSIC_NS::rule<ScannerT> rule;
  63. };
  64. };
  65. test_grammar const g;
  66. void
  67. in_thread(void)
  68. {
  69. char const text[]="foo";
  70. for(int i=0; i<number_of_calls_to_parse_per_thread; ++i)
  71. {
  72. BOOST_SPIRIT_CLASSIC_NS::parse(&text[0], text+sizeof(text), g);
  73. }
  74. }
  75. void
  76. bug_000008()
  77. {
  78. boost::thread t1(in_thread);
  79. boost::thread t2(in_thread);
  80. boost::thread t3(in_thread);
  81. boost::thread t4(in_thread);
  82. t1.join();
  83. t2.join();
  84. t3.join();
  85. t4.join();
  86. }
  87. int
  88. main()
  89. {
  90. bug_000008();
  91. return boost::report_errors();
  92. }
  93. #endif