#include #include #include typedef boost::error_info err_info; class err : public boost::exception , public std::exception { }; // transferres exception_ptr from producer to consumer thread class future { public: future () : ready_ (false) {} // called in producer thread, gets exception_ptr void set_exception (boost::exception_ptr const& e) { boost::unique_lock lck (mux_); exc_ = e; ready_ = true; cond_.notify_all(); } // called in consumer thread, returns exception_ptr boost::exception_ptr get_exception () const { boost::unique_lock lck (mux_); while (! ready_) cond_.wait (lck); return exc_; // was: rethrow_exception (exc_); } private: bool ready_; boost::exception_ptr exc_; mutable boost::mutex mux_; mutable boost::condition_variable cond_; }; void producer (future& f, boost::barrier& b) { b.wait (); // 1. create temp boost::exception object // 2. take exception_ptr to it f.set_exception (boost::copy_exception (err () << err_info ("stub"))); // 3. destroying temp boost::exception object } void consumer () { // barrier used to increase probablity to get a fault boost::barrier b (2); future f; boost::thread thr (boost::bind (&producer, boost::ref (f), boost::ref (b))); b.wait (); if (boost::exception_ptr e=f.get_exception() ) { try { rethrow_exception (e); } catch (err const& e) {} } thr.join (); } void consume () { for (int i=0;i<100;++i) consumer (); } int main () { boost::thread_group grp; for (int i=0; i<50; ++i) grp.create_thread (&consume); grp.join_all (); }