| 1 | #include <boost/exception.hpp>
|
|---|
| 2 | #include <boost/thread.hpp>
|
|---|
| 3 | #include <string>
|
|---|
| 4 |
|
|---|
| 5 | typedef boost::error_info<struct tag_throw_string, std::string> err_info;
|
|---|
| 6 |
|
|---|
| 7 | class err
|
|---|
| 8 | : public boost::exception
|
|---|
| 9 | , public std::exception
|
|---|
| 10 | {
|
|---|
| 11 | };
|
|---|
| 12 |
|
|---|
| 13 | class future
|
|---|
| 14 | {
|
|---|
| 15 | public:
|
|---|
| 16 | future () : ready_ (false) {}
|
|---|
| 17 |
|
|---|
| 18 | void set_exception (boost::exception_ptr const& e)
|
|---|
| 19 | {
|
|---|
| 20 | boost::unique_lock<boost::mutex> lck (mux_);
|
|---|
| 21 | exc_ = e;
|
|---|
| 22 | ready_ = true;
|
|---|
| 23 | cond_.notify_all();
|
|---|
| 24 | }
|
|---|
| 25 |
|
|---|
| 26 | void get_exception () const
|
|---|
| 27 | {
|
|---|
| 28 | boost::unique_lock<boost::mutex> lck (mux_);
|
|---|
| 29 | while (! ready_)
|
|---|
| 30 | cond_.wait (lck);
|
|---|
| 31 | rethrow_exception (exc_);
|
|---|
| 32 | }
|
|---|
| 33 |
|
|---|
| 34 | private:
|
|---|
| 35 | bool ready_;
|
|---|
| 36 | boost::exception_ptr exc_;
|
|---|
| 37 | mutable boost::mutex mux_;
|
|---|
| 38 | mutable boost::condition_variable cond_;
|
|---|
| 39 | };
|
|---|
| 40 |
|
|---|
| 41 | void producer (future& f)
|
|---|
| 42 | {
|
|---|
| 43 | f.set_exception (boost::copy_exception (err () << err_info ("stub")));
|
|---|
| 44 | }
|
|---|
| 45 |
|
|---|
| 46 | void consumer ()
|
|---|
| 47 | {
|
|---|
| 48 | future f;
|
|---|
| 49 | boost::thread thr (boost::bind (&producer, boost::ref (f)));
|
|---|
| 50 |
|
|---|
| 51 | try { f.get_exception (); }
|
|---|
| 52 | catch (err const& e) {}
|
|---|
| 53 |
|
|---|
| 54 | thr.join ();
|
|---|
| 55 | }
|
|---|
| 56 |
|
|---|
| 57 |
|
|---|
| 58 | void consume ()
|
|---|
| 59 | {
|
|---|
| 60 | for (int i=0;i<100;++i)
|
|---|
| 61 | consumer ();
|
|---|
| 62 | }
|
|---|
| 63 |
|
|---|
| 64 | int main ()
|
|---|
| 65 | {
|
|---|
| 66 | boost::thread_group grp;
|
|---|
| 67 | for (int i=0; i<50; ++i)
|
|---|
| 68 | grp.create_thread (&consume);
|
|---|
| 69 |
|
|---|
| 70 | grp.join_all ();
|
|---|
| 71 | }
|
|---|
| 72 |
|
|---|