• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

STEllAR-GROUP / hpx / #882

31 Aug 2023 07:44PM UTC coverage: 41.798% (-44.7%) from 86.546%
#882

push

19442 of 46514 relevant lines covered (41.8%)

126375.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

19.05
/libs/core/coroutines/src/detail/coroutine_impl.cpp
1
//  Copyright (c) 2006, Giovanni P. Deretta
2
//  Copyright (c) 2007-2024 Hartmut Kaiser
3
//
4
//  This code may be used under either of the following two licences:
5
//
6
//  Permission is hereby granted, free of charge, to any person obtaining a copy
7
//  of this software and associated documentation files (the "Software"), to deal
8
//  in the Software without restriction, including without limitation the rights
9
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
//  copies of the Software, and to permit persons to whom the Software is
11
//  furnished to do so, subject to the following conditions:
12
//
13
//  The above copyright notice and this permission notice shall be included in
14
//  all copies or substantial portions of the Software.
15
//
16
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
//  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
//  THE SOFTWARE. OF SUCH DAMAGE.
23
//
24
//  Or:
25
//
26
//  SPDX-License-Identifier: BSL-1.0
27
//  Distributed under the Boost Software License, Version 1.0.
28
//  (See accompanying file LICENSE_1_0.txt or copy at
29
//  http://www.boost.org/LICENSE_1_0.txt)
30

31
#include <hpx/config.hpp>
32

33
#include <hpx/assert.hpp>
34
#include <hpx/coroutines/coroutine.hpp>
35
#include <hpx/coroutines/detail/coroutine_impl.hpp>
36
#include <hpx/coroutines/detail/coroutine_stackful_self.hpp>
37
#include <hpx/coroutines/detail/coroutine_stackful_self_direct.hpp>
38

39
#include <cstddef>
40
#include <exception>
41
#include <utility>
42

43
namespace hpx::threads::coroutines::detail {
44

45
    ///////////////////////////////////////////////////////////////////////////
46
#if defined(HPX_DEBUG)
47
    coroutine_impl::~coroutine_impl()
48
    {
49
        HPX_ASSERT(!m_fun);    // functor should have been reset by now
50
    }
51
#endif
52

53
    void coroutine_impl::operator()() noexcept
43,912✔
54
    {
55
        using context_state = super_type::context_state;
56
        using context_exit_status = super_type::context_exit_status;
57

58
        auto status = context_exit_status::not_exited;
59

60
        // yield value once the thread function has finished executing
61
        result_type result_last;
62

63
        // loop as long this coroutine has been rebound
64
        do
65
        {
66
#if defined(HPX_HAVE_ADDRESS_SANITIZER)
67
            finish_switch_fiber(nullptr, m_caller);
68
#endif
69
            std::exception_ptr tinfo;
70
            {
71
                coroutine_self* old_self = coroutine_self::get_self();
72
                coroutine_stackful_self self(this, old_self);
73

74
                coroutine_self::set_self(&self);
75
                auto on_exit = hpx::experimental::scope_exit(
76
                    [&] { coroutine_self::set_self(old_self); });
77

43,912✔
78
                try
79
                {
80
                    result_last = m_fun(*this->args());
81
                    HPX_ASSERT(
82
                        result_last.first == thread_schedule_state::terminated);
×
83
                    status = context_exit_status::exited_return;
84
                }
85
                catch (...)
×
86
                {
×
87
                    status = context_exit_status::exited_abnormally;
88
                    tinfo = std::current_exception();
89
                }
90

43,912✔
91
                // Reset early as the destructors may still yield.
92
                this->reset_tss();
93
                this->reset(false);
94

95
                // return value to other side of the fence
96
                this->bind_result(result_last);
43,912✔
97
            }
×
98

99
            this->do_return(status, HPX_MOVE(tinfo));
100
        } while (this->m_state == context_state::running);
101

×
102
        // should not get here, never
103
        HPX_ASSERT(this->m_state == context_state::running);
104
    }
105

×
106
    // execute the coroutine function directly in the context of the calling
107
    // thread
108
    coroutine_impl::result_type coroutine_impl::invoke_directly(
109
        coroutine_impl::arg_type arg)
110
    {
111
        using context_state = super_type::context_state;
112
        using context_exit_status = super_type::context_exit_status;
113

114
        auto status = context_exit_status::not_exited;
115

116
        result_type const result_last(
×
117
            thread_schedule_state::unknown, invalid_thread_id);
118

119
        this->m_state = context_state::running;
120

121
        std::exception_ptr tinfo;
122
        {
123
            coroutine_self* old_self = coroutine_self::get_self();
124
            coroutine_stackful_self_direct self(this, old_self);
125

×
126
            coroutine_self::set_self(&self);
127
            auto on_exit = hpx::experimental::scope_exit(
128
                [&] { coroutine_self::set_self(old_self); });
129

130
            try
×
131
            {
132
                this->m_result = this->m_fun(arg);
133
                HPX_ASSERT(
×
134
                    this->m_result.first == thread_schedule_state::terminated);
×
135
                status = context_exit_status::exited_return;
136
            }
137
            catch (...)
×
138
            {
139
                status = context_exit_status::exited_abnormally;
140
                this->m_type_info = std::current_exception();
141
            }
142

143
            this->reset_tss();
×
144
            this->reset(true);
×
145

146
            this->bind_result(result_last);
×
147
        }
148

×
149
        HPX_ASSERT(this->m_state == context_state::running);
150
        this->m_state = context_state::exited;
×
151
        this->m_exit_status = status;
152

153
        if (status == context_exit_status::exited_abnormally)
154
        {
155
            std::rethrow_exception(this->m_type_info);
156
        }
157
        return this->m_result;
158
    }
159
}    // namespace hpx::threads::coroutines::detail
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc