copy_exception_test.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. //Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
  2. //Distributed under the Boost Software License, Version 1.0. (See accompanying
  3. //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. #include <boost/exception_ptr.hpp>
  5. #include <boost/exception/get_error_info.hpp>
  6. #include <boost/thread.hpp>
  7. #include <boost/detail/atomic_count.hpp>
  8. #include <boost/detail/lightweight_test.hpp>
  9. typedef boost::error_info<struct tag_answer,int> answer;
  10. boost::detail::atomic_count exc_count(0);
  11. struct
  12. err:
  13. virtual boost::exception,
  14. virtual std::exception
  15. {
  16. err()
  17. {
  18. ++exc_count;
  19. }
  20. err( err const & )
  21. {
  22. ++exc_count;
  23. }
  24. virtual
  25. ~err() BOOST_NOEXCEPT_OR_NOTHROW
  26. {
  27. --exc_count;
  28. }
  29. private:
  30. err & operator=( err const & );
  31. };
  32. class
  33. future
  34. {
  35. public:
  36. future ():
  37. ready_ (false)
  38. {
  39. }
  40. void
  41. set_exception( boost::exception_ptr const & e )
  42. {
  43. boost::unique_lock<boost::mutex> lck (mux_);
  44. exc_ = e;
  45. ready_ = true;
  46. cond_.notify_all();
  47. }
  48. void
  49. get_exception() const
  50. {
  51. boost::unique_lock<boost::mutex> lck (mux_);
  52. while (! ready_)
  53. cond_.wait (lck);
  54. rethrow_exception (exc_);
  55. }
  56. private:
  57. bool ready_;
  58. boost::exception_ptr exc_;
  59. mutable boost::mutex mux_;
  60. mutable boost::condition_variable cond_;
  61. };
  62. void
  63. producer( future & f )
  64. {
  65. f.set_exception (boost::copy_exception (err () << answer(42)));
  66. }
  67. void
  68. consumer()
  69. {
  70. future f;
  71. boost::thread thr (boost::bind (&producer, boost::ref (f)));
  72. try
  73. {
  74. f.get_exception ();
  75. }
  76. catch(
  77. err & e )
  78. {
  79. int const * ans=boost::get_error_info<answer>(e);
  80. BOOST_TEST(ans && *ans==42);
  81. }
  82. thr.join();
  83. }
  84. void
  85. consume()
  86. {
  87. for( int i=0; i!=100; ++i )
  88. consumer();
  89. }
  90. void
  91. thread_test()
  92. {
  93. boost::thread_group grp;
  94. for( int i=0; i!=50; ++i )
  95. grp.create_thread(&consume);
  96. grp.join_all ();
  97. }
  98. void
  99. simple_test()
  100. {
  101. boost::exception_ptr p = boost::copy_exception(err());
  102. try
  103. {
  104. rethrow_exception(p);
  105. BOOST_TEST(false);
  106. }
  107. catch(
  108. err & )
  109. {
  110. }
  111. catch(
  112. ... )
  113. {
  114. BOOST_TEST(false);
  115. }
  116. }
  117. int
  118. main()
  119. {
  120. BOOST_TEST(++exc_count==1);
  121. simple_test();
  122. thread_test();
  123. BOOST_TEST(!--exc_count);
  124. return boost::report_errors();
  125. }