fixed the bug when exit() other coroutine in a coroutine
@@ -0,0 +1,49 @@ | ||
1 | +// exit_other_test.cpp: test case for exit() from other thread | |
2 | + | |
3 | +// Copyright Takeshi Mouri 2008. | |
4 | +// Distributed under the Boost Software License, Version 1.0. | |
5 | +// (See accompanying file LICENSE_1_0.txt or copy at | |
6 | +// http://www.boost.org/LICENSE_1_0.txt) | |
7 | + | |
8 | +// See http://hamigaki.sourceforge.jp/libs/coroutine for library home page. | |
9 | + | |
10 | +// This test is based on the code contributed by W.Dee. | |
11 | + | |
12 | +#include <hamigaki/coroutine/coroutine.hpp> | |
13 | +#include <boost/test/unit_test.hpp> | |
14 | + | |
15 | +namespace coro = hamigaki::coroutines; | |
16 | +namespace ut = boost::unit_test; | |
17 | + | |
18 | +typedef coro::coroutine<void()> coroutine_type1; | |
19 | +typedef coro::coroutine<int(coroutine_type1*)> coroutine_type2; | |
20 | + | |
21 | +void body1(coroutine_type1::self& self) | |
22 | +{ | |
23 | + while (true) | |
24 | + self.yield(); | |
25 | +} | |
26 | + | |
27 | +int body2(coroutine_type2::self& self, coroutine_type1* coroutine1) | |
28 | +{ | |
29 | + coroutine1->exit(); | |
30 | + while (true) | |
31 | + self.yield(0); | |
32 | + HAMIGAKI_COROUTINE_UNREACHABLE_RETURN(0) | |
33 | +} | |
34 | + | |
35 | +void exit_other_test() | |
36 | +{ | |
37 | + coroutine_type1 coroutine1(body1); | |
38 | + coroutine1(); | |
39 | + | |
40 | + coroutine_type2 coroutine2(body2); | |
41 | + coroutine2(&coroutine1); | |
42 | +} | |
43 | + | |
44 | +ut::test_suite* init_unit_test_suite(int, char* []) | |
45 | +{ | |
46 | + ut::test_suite* test = BOOST_TEST_SUITE("exit other test"); | |
47 | + test->add(BOOST_TEST_CASE(&exit_other_test)); | |
48 | + return test; | |
49 | +} |
@@ -1,6 +1,6 @@ | ||
1 | 1 | // fiber_context.hpp: Win32 fiber based context implementation |
2 | 2 | |
3 | -// Copyright Takeshi Mouri 2006, 2007. | |
3 | +// Copyright Takeshi Mouri 2006-2008. | |
4 | 4 | // Distributed under the Boost Software License, Version 1.0. |
5 | 5 | // (See accompanying file LICENSE_1_0.txt or copy at |
6 | 6 | // http://www.boost.org/LICENSE_1_0.txt) |
@@ -61,14 +61,21 @@ | ||
61 | 61 | { |
62 | 62 | if (is_fiber()) |
63 | 63 | { |
64 | + bool need_reset = false; | |
64 | 65 | if (from.context_ == 0) |
66 | + { | |
65 | 67 | from.context_ = get_current_fiber(); |
68 | + need_reset = true; | |
69 | + } | |
66 | 70 | from.switch_to(to); |
71 | + if (need_reset) | |
72 | + from.context_ = 0; | |
67 | 73 | } |
68 | 74 | else |
69 | 75 | { |
70 | 76 | from.context_ = ::ConvertThreadToFiber(0); |
71 | 77 | from.switch_to(to); |
78 | + from.context_ = 0; | |
72 | 79 | } |
73 | 80 | } |
74 | 81 |