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

source code of boost/libs/exception/test/copy_exception_test.cpp