Skip to content

Commit 5d495f9

Browse files
committed
Add RAII cleanup to ChainAwaiter
Prevents handle leak if the awaiting coroutine is destroyed while suspended. Signed-off-by: Nicolas 'Pixel' Noble <nicolas@nobis-crew.org>
1 parent 098d34f commit 5d495f9

2 files changed

Lines changed: 24 additions & 0 deletions

File tree

src/mips/psyqo/coroutine.hh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,16 @@ struct Coroutine {
243243
struct ChainAwaiter {
244244
std::coroutine_handle<Promise> handle;
245245

246+
explicit ChainAwaiter(std::coroutine_handle<Promise> h) : handle(h) {}
247+
~ChainAwaiter() {
248+
if (handle) handle.destroy();
249+
}
250+
251+
ChainAwaiter(ChainAwaiter &&other) : handle(other.handle) { other.handle = nullptr; }
252+
ChainAwaiter &operator=(ChainAwaiter &&) = delete;
253+
ChainAwaiter(const ChainAwaiter &) = delete;
254+
ChainAwaiter &operator=(const ChainAwaiter &) = delete;
255+
246256
constexpr bool await_ready() { return handle.done(); }
247257

248258
void await_suspend(std::coroutine_handle<> h) {
@@ -253,10 +263,12 @@ struct Coroutine {
253263
constexpr T await_resume() {
254264
if constexpr (std::is_void<T>::value) {
255265
handle.destroy();
266+
handle = nullptr;
256267
return;
257268
} else {
258269
auto val = eastl::move(handle.promise().m_value);
259270
handle.destroy();
271+
handle = nullptr;
260272
return val;
261273
}
262274
}

src/support/coroutine.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,16 @@ struct Coroutine {
180180
struct ChainAwaiter {
181181
std::coroutine_handle<Promise> handle;
182182

183+
explicit ChainAwaiter(std::coroutine_handle<Promise> h) : handle(h) {}
184+
~ChainAwaiter() {
185+
if (handle) handle.destroy();
186+
}
187+
188+
ChainAwaiter(ChainAwaiter &&other) : handle(other.handle) { other.handle = nullptr; }
189+
ChainAwaiter &operator=(ChainAwaiter &&) = delete;
190+
ChainAwaiter(const ChainAwaiter &) = delete;
191+
ChainAwaiter &operator=(const ChainAwaiter &) = delete;
192+
183193
constexpr bool await_ready() { return handle.done(); }
184194

185195
void await_suspend(std::coroutine_handle<> h) {
@@ -190,10 +200,12 @@ struct Coroutine {
190200
constexpr T await_resume() {
191201
if constexpr (std::is_void<T>::value) {
192202
handle.destroy();
203+
handle = nullptr;
193204
return;
194205
} else {
195206
auto val = std::move(handle.promise().m_value);
196207
handle.destroy();
208+
handle = nullptr;
197209
return val;
198210
}
199211
}

0 commit comments

Comments
 (0)