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/info.hpp>
14#include <boost/exception/get_error_info.hpp>
15#include <boost/exception/diagnostic_information.hpp>
16#include <boost/function.hpp>
17#include <boost/bind.hpp>
18#include <boost/thread.hpp>
19#include <boost/detail/atomic_count.hpp>
20#include <boost/detail/lightweight_test.hpp>
21#include <iostream>
22
23class thread_handle;
24boost::shared_ptr<thread_handle> create_thread( boost::function<void()> const & f );
25void join( thread_handle & t );
26
27class
28thread_handle
29 {
30 thread_handle( thread_handle const & );
31 thread_handle & operator=( thread_handle const & );
32
33 boost::exception_ptr err_;
34 boost::thread t_;
35
36 static
37 void
38 thread_wrapper( boost::function<void()> const & f, boost::exception_ptr & ep )
39 {
40 BOOST_ASSERT(!ep);
41 try
42 {
43 f();
44 }
45 catch(...)
46 {
47 ep = boost::current_exception();
48 }
49 }
50
51 explicit
52 thread_handle( boost::function<void()> const & f ):
53 t_(boost::bind(f: thread_wrapper,a1: f,a2: boost::ref(t&: err_)))
54 {
55 }
56
57 friend boost::shared_ptr<thread_handle> create_thread( boost::function<void()> const & f );
58 friend void join( thread_handle & t );
59 };
60
61boost::shared_ptr<thread_handle>
62create_thread( boost::function<void()> const & f )
63 {
64 boost::shared_ptr<thread_handle> t( new thread_handle(f) );
65 return t;
66 }
67
68void
69join( thread_handle & t )
70 {
71 t.t_.join();
72 assert(t.err_);
73 rethrow_exception(p: t.err_);
74 }
75
76boost::detail::atomic_count exc_count(0);
77
78struct
79exc:
80 virtual boost::exception,
81 virtual std::exception
82 {
83 exc()
84 {
85 ++exc_count;
86 }
87
88 exc( exc const & e ):
89 boost::exception(e),
90 std::exception(e)
91 {
92 ++exc_count;
93 }
94
95 virtual
96 ~exc() BOOST_NOEXCEPT_OR_NOTHROW
97 {
98 --exc_count;
99 }
100
101 private:
102
103 exc & operator=( exc const & );
104 };
105
106typedef boost::error_info<struct answer_,int> answer;
107
108void
109thread_func()
110 {
111 BOOST_THROW_EXCEPTION(exc() << answer(42));
112 }
113
114void
115check( boost::shared_ptr<thread_handle> const & t )
116 {
117 try
118 {
119 join(t&: *t);
120 BOOST_TEST(false);
121 }
122 catch(
123 exc & e )
124 {
125 int const * a = boost::get_error_info<answer>(some_exception&: e);
126 BOOST_TEST(a && *a==42);
127 }
128 }
129
130void
131test_deep_copy()
132 {
133 int const * p1=0;
134 boost::exception_ptr p;
135 try
136 {
137 BOOST_THROW_EXCEPTION(exc() << answer(42));
138 BOOST_ERROR("BOOST_THROW_EXCEPTION didn't throw");
139 }
140 catch(
141 exc & e )
142 {
143 p1=boost::get_error_info<answer>(some_exception&: e);
144 p=boost::current_exception();
145 }
146 BOOST_TEST(p1!=0);
147 BOOST_TEST(p);
148 try
149 {
150 boost::rethrow_exception(p);
151 BOOST_ERROR("rethrow_exception didn't throw");
152 }
153 catch(
154 exc & e )
155 {
156 int const * p2=boost::get_error_info<answer>(some_exception&: e);
157 BOOST_TEST(p2!=0 && *p2==42);
158 BOOST_TEST(p2!=p1);
159 }
160 }
161
162int
163main()
164 {
165 test_deep_copy();
166 BOOST_TEST(++exc_count==1);
167 try
168 {
169 std::vector< boost::shared_ptr<thread_handle> > threads;
170 std::generate_n(first: std::inserter(x&: threads,i: threads.end()),n: 1,gen: boost::bind(f: create_thread,a1: thread_func));
171 std::for_each(first: threads.begin(),last: threads.end(),f: check);
172 return boost::report_errors();
173 }
174 catch(
175 ... )
176 {
177 std::cerr <<
178 "Caught unexpected exception.\n"
179 "Output from current_exception_diagnostic_information:\n" <<
180 boost::current_exception_diagnostic_information() << std::endl;
181 return 42;
182 }
183 BOOST_TEST(!--exc_count);
184 }
185

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