Skip to content

Commit 451b6df

Browse files
committed
Harden PCSX::Coroutine move safety and awaiter API
Fix exception safety in move operations by transferring handle ownership before the potentially-throwing value move. Restrict awaiter() to lvalues in both PCSX and psyqo coroutines to prevent dangling pointer from temporaries. Signed-off-by: Nicolas 'Pixel' Noble <nicolas@nobis-crew.org>
1 parent 287fc74 commit 451b6df

2 files changed

Lines changed: 8 additions & 15 deletions

File tree

src/mips/psyqo/coroutine.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ struct Coroutine {
128128
* @details This method is used to create an instance of the `Awaiter` object.
129129
* It's used to suspend the coroutine after scheduling an asynchronous operation.
130130
*/
131-
Awaiter awaiter() { return Awaiter(this); }
131+
Awaiter awaiter() & { return Awaiter(this); }
132132

133133
/**
134134
* @brief Resumes the coroutine.

src/support/coroutine.h

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,29 +39,22 @@ struct Coroutine {
3939

4040
Coroutine() = default;
4141

42-
Coroutine(Coroutine &&other) {
43-
if (m_handle) m_handle.destroy();
44-
m_handle = other.m_handle;
45-
m_value = std::move(other.m_value);
46-
m_suspended = other.m_suspended;
47-
m_earlyResume = other.m_earlyResume;
48-
49-
other.m_handle = nullptr;
50-
other.m_value = SafeT{};
42+
Coroutine(Coroutine &&other)
43+
: m_handle(std::exchange(other.m_handle, nullptr)),
44+
m_value(std::move(other.m_value)),
45+
m_suspended(other.m_suspended),
46+
m_earlyResume(other.m_earlyResume) {
5147
other.m_suspended = true;
5248
other.m_earlyResume = false;
5349
}
5450

5551
Coroutine &operator=(Coroutine &&other) {
5652
if (this != &other) {
5753
if (m_handle) m_handle.destroy();
58-
m_handle = other.m_handle;
54+
m_handle = std::exchange(other.m_handle, nullptr);
5955
m_value = std::move(other.m_value);
6056
m_suspended = other.m_suspended;
6157
m_earlyResume = other.m_earlyResume;
62-
63-
other.m_handle = nullptr;
64-
other.m_value = SafeT{};
6558
other.m_suspended = true;
6659
other.m_earlyResume = false;
6760
}
@@ -94,7 +87,7 @@ struct Coroutine {
9487
friend struct Coroutine;
9588
};
9689

97-
Awaiter awaiter() { return Awaiter(this); }
90+
Awaiter awaiter() & { return Awaiter(this); }
9891

9992
void resume() {
10093
if (!m_handle) return;

0 commit comments

Comments
 (0)