| //Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. |
| |
| //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) |
| |
| #include <boost/exception_ptr.hpp> |
| #include <boost/exception/get_error_info.hpp> |
| #include <boost/thread.hpp> |
| #include <boost/detail/lightweight_test.hpp> |
| |
| typedef boost::error_info<struct tag_answer,int> answer; |
| |
| struct |
| err: |
| virtual boost::exception, |
| virtual std::exception |
| { |
| }; |
| |
| class |
| future |
| { |
| public: |
| |
| future (): |
| ready_ (false) |
| { |
| } |
| |
| void |
| set_exception( boost::exception_ptr const & e ) |
| { |
| boost::unique_lock<boost::mutex> lck (mux_); |
| exc_ = e; |
| ready_ = true; |
| cond_.notify_all(); |
| } |
| |
| void |
| get_exception() const |
| { |
| boost::unique_lock<boost::mutex> lck (mux_); |
| while (! ready_) |
| cond_.wait (lck); |
| rethrow_exception (exc_); |
| } |
| |
| private: |
| |
| bool ready_; |
| boost::exception_ptr exc_; |
| mutable boost::mutex mux_; |
| mutable boost::condition_variable cond_; |
| }; |
| |
| void |
| producer( future & f ) |
| { |
| f.set_exception (boost::copy_exception (err () << answer(42))); |
| } |
| |
| void |
| consumer() |
| { |
| future f; |
| boost::thread thr (boost::bind (&producer, boost::ref (f))); |
| try |
| { |
| f.get_exception (); |
| } |
| catch( |
| err & e ) |
| { |
| int const * ans=boost::get_error_info<answer>(e); |
| BOOST_TEST(ans && *ans==42); |
| } |
| thr.join(); |
| } |
| |
| void |
| consume() |
| { |
| for( int i=0; i!=100; ++i ) |
| consumer(); |
| } |
| |
| void |
| thread_test() |
| { |
| boost::thread_group grp; |
| for( int i=0; i!=50; ++i ) |
| grp.create_thread(&consume); |
| grp.join_all (); |
| } |
| |
| void |
| simple_test() |
| { |
| boost::exception_ptr p = boost::copy_exception(err()); |
| try |
| { |
| rethrow_exception(p); |
| BOOST_TEST(false); |
| } |
| catch( |
| err & ) |
| { |
| } |
| catch( |
| ... ) |
| { |
| BOOST_TEST(false); |
| } |
| } |
| |
| int |
| main() |
| { |
| simple_test(); |
| thread_test(); |
| return boost::report_errors(); |
| } |