1 // Copyright (C) 2001-2003
3 // Copyright (C) 2007 Anthony Williams
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11 #include <boost/test/unit_test.hpp>
13 #include <boost/fiber/all.hpp>
15 boost::fibers::mutex check_mutex
;
16 boost::fibers::mutex fss_mutex
;
17 int fss_instances
= 0;
22 std::unique_lock
<boost::fibers::mutex
> lock(fss_mutex
);
28 std::unique_lock
<boost::fibers::mutex
> lock(fss_mutex
);
34 boost::fibers::fiber_specific_ptr
<fss_value_t
> fss_value
;
37 fss_value
.reset(new fss_value_t());
38 for (int i
=0; i
<1000; ++i
) {
39 int& n
= fss_value
->value
;
41 std::unique_lock
<boost::fibers::mutex
> lock(check_mutex
);
42 BOOST_CHECK_EQUAL(n
, i
);
52 boost::fibers::fiber
f1( boost::fibers::launch::post
, fss_fiber
);
53 boost::fibers::fiber
f2( boost::fibers::launch::post
, fss_fiber
);
54 boost::fibers::fiber
f3( boost::fibers::launch::post
, fss_fiber
);
55 boost::fibers::fiber
f4( boost::fibers::launch::post
, fss_fiber
);
56 boost::fibers::fiber
f5( boost::fibers::launch::post
, fss_fiber
);
64 << "fss_instances = " << fss_instances
65 << "; fss_total = " << fss_total
69 BOOST_CHECK_EQUAL(fss_instances
, 0);
70 BOOST_CHECK_EQUAL(fss_total
, 5);
74 boost::fibers::fiber( boost::fibers::launch::post
, fss
).join();
77 bool fss_cleanup_called
=false;
82 void fss_custom_cleanup(Dummy
* d
) {
84 fss_cleanup_called
=true;
87 boost::fibers::fiber_specific_ptr
<Dummy
> fss_with_cleanup(fss_custom_cleanup
);
89 void fss_fiber_with_custom_cleanup() {
90 fss_with_cleanup
.reset(new Dummy
);
93 void fss_with_custom_cleanup() {
94 boost::fibers::fiber
f( boost::fibers::launch::post
, fss_fiber_with_custom_cleanup
);
102 BOOST_CHECK(fss_cleanup_called
);
105 void test_fss_with_custom_cleanup() {
106 boost::fibers::fiber( boost::fibers::launch::post
, fss_with_custom_cleanup
).join();
109 Dummy
* fss_object
=new Dummy
;
111 void fss_fiber_with_custom_cleanup_and_release() {
112 fss_with_cleanup
.reset(fss_object
);
113 fss_with_cleanup
.release();
116 void do_test_fss_does_no_cleanup_after_release() {
117 fss_cleanup_called
=false;
118 boost::fibers::fiber
f( boost::fibers::launch::post
, fss_fiber_with_custom_cleanup_and_release
);
126 BOOST_CHECK(!fss_cleanup_called
);
127 if(!fss_cleanup_called
) {
132 struct dummy_class_tracks_deletions
{
133 static unsigned deletions
;
135 ~dummy_class_tracks_deletions() {
140 unsigned dummy_class_tracks_deletions::deletions
=0;
142 boost::fibers::fiber_specific_ptr
<dummy_class_tracks_deletions
> fss_with_null_cleanup(NULL
);
144 void fss_fiber_with_null_cleanup(dummy_class_tracks_deletions
* delete_tracker
) {
145 fss_with_null_cleanup
.reset(delete_tracker
);
148 void do_test_fss_does_no_cleanup_with_null_cleanup_function() {
149 dummy_class_tracks_deletions
* delete_tracker
=new dummy_class_tracks_deletions
;
150 boost::fibers::fiber
f( boost::fibers::launch::post
, [&delete_tracker
](){
151 fss_fiber_with_null_cleanup( delete_tracker
); });
159 BOOST_CHECK(!dummy_class_tracks_deletions::deletions
);
160 if(!dummy_class_tracks_deletions::deletions
) {
161 delete delete_tracker
;
165 void test_fss_does_no_cleanup_after_release() {
166 boost::fibers::fiber( boost::fibers::launch::post
, do_test_fss_does_no_cleanup_after_release
).join();
169 void test_fss_does_no_cleanup_with_null_cleanup_function() {
170 boost::fibers::fiber( boost::fibers::launch::post
, do_test_fss_does_no_cleanup_with_null_cleanup_function
).join();
174 void fiber_with_local_fss_ptr() {
176 boost::fibers::fiber_specific_ptr
<Dummy
> local_fss(fss_custom_cleanup
);
178 local_fss
.reset(new Dummy
);
180 BOOST_CHECK(fss_cleanup_called
);
181 fss_cleanup_called
=false;
184 void fss_does_not_call_cleanup_after_ptr_destroyed() {
185 boost::fibers::fiber( boost::fibers::launch::post
, fiber_with_local_fss_ptr
).join();
186 BOOST_CHECK(!fss_cleanup_called
);
189 void test_fss_does_not_call_cleanup_after_ptr_destroyed() {
190 boost::fibers::fiber( boost::fibers::launch::post
, fss_does_not_call_cleanup_after_ptr_destroyed
).join();
194 void fss_cleanup_not_called_for_null_pointer() {
195 boost::fibers::fiber_specific_ptr
<Dummy
> local_fss(fss_custom_cleanup
);
196 local_fss
.reset(new Dummy
);
197 fss_cleanup_called
=false;
199 BOOST_CHECK(fss_cleanup_called
);
200 fss_cleanup_called
=false;
201 local_fss
.reset(new Dummy
);
202 BOOST_CHECK(!fss_cleanup_called
);
205 void test_fss_cleanup_not_called_for_null_pointer() {
206 boost::fibers::fiber( boost::fibers::launch::post
, fss_cleanup_not_called_for_null_pointer
).join();
210 void fss_at_the_same_adress() {
211 for(int i
=0; i
<2; i
++) {
212 boost::fibers::fiber_specific_ptr
<Dummy
> local_fss(fss_custom_cleanup
);
213 local_fss
.reset(new Dummy
);
214 fss_cleanup_called
=false;
215 BOOST_CHECK(fss_cleanup_called
);
216 fss_cleanup_called
=false;
217 BOOST_CHECK(!fss_cleanup_called
);
221 void test_fss_at_the_same_adress() {
222 boost::fibers::fiber( boost::fibers::launch::post
, fss_at_the_same_adress
).join();
225 boost::unit_test::test_suite
* init_unit_test_suite(int, char*[]) {
226 boost::unit_test::test_suite
* test
=
227 BOOST_TEST_SUITE("Boost.Fiber: fss test suite");
229 test
->add(BOOST_TEST_CASE(test_fss
));
230 test
->add(BOOST_TEST_CASE(test_fss_with_custom_cleanup
));
231 test
->add(BOOST_TEST_CASE(test_fss_does_no_cleanup_after_release
));
232 test
->add(BOOST_TEST_CASE(test_fss_does_no_cleanup_with_null_cleanup_function
));
233 test
->add(BOOST_TEST_CASE(test_fss_does_not_call_cleanup_after_ptr_destroyed
));
234 test
->add(BOOST_TEST_CASE(test_fss_cleanup_not_called_for_null_pointer
));