GCC Code Coverage Report


Directory: src/gate/
File: src/gate/cxx_coroutines.cpp
Date: 2026-03-20 22:56:14
Exec Total Coverage
Lines: 94 94 100.0%
Functions: 18 18 100.0%
Branches: 35 84 41.7%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright (c) 2018-2026, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/coroutines.hpp"
30 #include "gate/exceptions.hpp"
31
32 namespace gate
33 {
34
35 3 bool_t Coroutine::supported()
36 {
37 3 return gate_coroutine_supported();
38 }
39
40 struct GATE_API_LOCAL CoroutineDispatcher : public IRunnable, private NonCopyable
41 {
42 gate_coroutine_function_t func;
43 void* param;
44 IRunnable* runnable;
45 Ptr<IRunnable> runnableManager;
46
47 5 CoroutineDispatcher(gate_coroutine_function_t f, void* p)
48 5 : func(f), param(p), runnable(NULL)
49 {
50 5 }
51 3 explicit CoroutineDispatcher(IRunnable* r)
52 3 : func(NULL), param(NULL), runnable(r), runnableManager(r)
53 {
54 3 }
55 3 explicit CoroutineDispatcher(IRunnable& r)
56 3 : func(NULL), param(NULL), runnable(&r)
57 {
58 3 }
59
60 11 virtual void run() override
61 {
62
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6 times.
11 if (this->func)
63 {
64 5 result_t result = this->func(this->param);
65
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 GATEXX_CHECK_EXCEPTION(result);
66 }
67
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 else if (this->runnable)
68 {
69 6 this->runnable->run();
70 }
71 11 }
72
73 11 static gate_result_t GATE_CALL dispatcher(void* param)
74 {
75 11 Ptr<CoroutineDispatcher> disp(static_cast<CoroutineDispatcher*>(param));
76
77 11 IRunnable& code = *disp;
78
79 11 exception_info_t const xcpt = catchException(code);
80 11 return xcpt.result_code;
81 }
82
83 };
84
85 2 void Coroutine::run(gate_coroutine_function_t func, void* param)
86 {
87
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 Ptr<CoroutineDispatcher> ptr(new CoroutineDispatcher(func, param));
88
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 result_t ret = gate_coroutine_run(&CoroutineDispatcher::dispatcher, ptr.get());
89
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (GATE_SUCCEEDED(ret))
90 {
91 2 ptr.release();
92 }
93
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2 GATEXX_CHECK_ERROR(ret);
94 2 }
95 1 void Coroutine::run(IRunnable& code)
96 {
97
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 Ptr<CoroutineDispatcher> ptr(new CoroutineDispatcher(code));
98
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 result_t ret = gate_coroutine_run(&CoroutineDispatcher::dispatcher, ptr.get());
99
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (GATE_SUCCEEDED(ret))
100 {
101 1 ptr.release();
102 }
103
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 GATEXX_CHECK_ERROR(ret);
104 1 }
105 1 void Coroutine::run(Ptr<IRunnable>& codeptr)
106 {
107
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 Ptr<CoroutineDispatcher> ptr(new CoroutineDispatcher(codeptr.get()));
108 1 codeptr.release();
109
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 result_t ret = gate_coroutine_run(&CoroutineDispatcher::dispatcher, ptr.get());
110
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (GATE_SUCCEEDED(ret))
111 {
112 1 ptr.release();
113 }
114
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 GATEXX_CHECK_ERROR(ret);
115 1 }
116
117 2 bool_t Coroutine::enabled()
118 {
119 2 return gate_coroutine_enabled();
120 }
121 1 Coroutine::id_t Coroutine::getCurrent()
122 {
123 1 id_t id = 0;
124
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 result_t result = gate_coroutine_get_current(&id);
125
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 GATEXX_CHECK_ERROR(result);
126 1 return id;
127 }
128 413930 void Coroutine::yield()
129 {
130 413930 result_t result = gate_coroutine_yield();
131
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 413930 times.
413930 GATEXX_CHECK_ERROR(result);
132 413930 }
133 3 Coroutine::id_t Coroutine::create(gate_coroutine_function_t func, void* param)
134 {
135 3 id_t ret = 0;
136
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 Ptr<CoroutineDispatcher> ptr(new CoroutineDispatcher(func, param));
137
1/2
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 result_t result = gate_coroutine_create(&CoroutineDispatcher::dispatcher, ptr.get(), &ret);
138
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (GATE_SUCCEEDED(result))
139 {
140 3 ptr.release();
141 }
142
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
3 GATEXX_CHECK_ERROR(result);
143 6 return ret;
144 }
145 2 Coroutine::id_t Coroutine::create(IRunnable& code)
146 {
147 2 id_t ret = 0;
148
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 Ptr<CoroutineDispatcher> ptr(new CoroutineDispatcher(code));
149
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 result_t result = gate_coroutine_create(&CoroutineDispatcher::dispatcher, ptr.get(), &ret);
150
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (GATE_SUCCEEDED(result))
151 {
152 2 ptr.release();
153 }
154
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2 GATEXX_CHECK_ERROR(result);
155 4 return ret;
156 }
157 2 Coroutine::id_t Coroutine::create(Ptr<IRunnable>& codeptr)
158 {
159 2 id_t ret = 0;
160
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 Ptr<CoroutineDispatcher> ptr(new CoroutineDispatcher(codeptr.get()));
161 2 codeptr.release();
162
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 result_t result = gate_coroutine_create(&CoroutineDispatcher::dispatcher, ptr.get(), &ret);
163
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (GATE_SUCCEEDED(result))
164 {
165 2 ptr.release();
166 }
167
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2 GATEXX_CHECK_ERROR(result);
168 4 return ret;
169 }
170
171 5 void Coroutine::switchTo(id_t context_id)
172 {
173 5 result_t result = gate_coroutine_switch_to(context_id);
174
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 GATEXX_CHECK_ERROR(result);
175 5 }
176
177 5 result_t Coroutine::await(id_t id)
178 {
179 5 result_t co_result = GATE_RESULT_FAILED;
180
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 result_t result = gate_coroutine_await(id, &co_result);
181
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
5 GATEXX_CHECK_ERROR(result);
182 5 return co_result;
183 }
184
185 1 void Coroutine::sleep(uint32_t timeoutMs)
186 {
187 1 result_t result = gate_coroutine_sleep(timeoutMs);
188
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATEXX_CHECK_ERROR(result);
189 1 }
190
191
192 } // end of namespace gate
193