Ticket #3848: exc1.cc

File exc1.cc, 1.7 KB (added by Nikki Chumakov <nikkikom@…>, 13 years ago)
Line 
1#include <boost/exception.hpp>
2#include <boost/thread.hpp>
3#include <string>
4
5typedef boost::error_info<struct tag_throw_string, std::string> err_info;
6
7class err
8 : public boost::exception
9 , public std::exception
10{
11};
12
13// transferres exception_ptr from producer to consumer thread
14class future
15{
16 public:
17 future () : ready_ (false) {}
18
19 // called in producer thread, gets exception_ptr
20 void set_exception (boost::exception_ptr const& e)
21 {
22 boost::unique_lock<boost::mutex> lck (mux_);
23 exc_ = e;
24 ready_ = true;
25 cond_.notify_all();
26 }
27
28 // called in consumer thread, returns exception_ptr
29 boost::exception_ptr get_exception () const
30 {
31 boost::unique_lock<boost::mutex> lck (mux_);
32 while (! ready_)
33 cond_.wait (lck);
34 return exc_; // was: rethrow_exception (exc_);
35 }
36
37 private:
38 bool ready_;
39 boost::exception_ptr exc_;
40 mutable boost::mutex mux_;
41 mutable boost::condition_variable cond_;
42};
43
44void producer (future& f, boost::barrier& b)
45{
46 b.wait ();
47
48 // 1. create temp boost::exception object
49 // 2. take exception_ptr to it
50 f.set_exception (boost::copy_exception (err () << err_info ("stub")));
51 // 3. destroying temp boost::exception object
52}
53
54void consumer ()
55{
56 // barrier used to increase probablity to get a fault
57 boost::barrier b (2);
58
59 future f;
60 boost::thread thr (boost::bind (&producer, boost::ref (f), boost::ref (b)));
61
62 b.wait ();
63
64 if (boost::exception_ptr e=f.get_exception() )
65 {
66 try { rethrow_exception (e); }
67 catch (err const& e) {}
68 }
69
70 thr.join ();
71}
72
73
74void consume ()
75{
76 for (int i=0;i<100;++i)
77 consumer ();
78}
79
80int main ()
81{
82 boost::thread_group grp;
83 for (int i=0; i<50; ++i)
84 grp.create_thread (&consume);
85
86 grp.join_all ();
87}