Skip to content

Commit 8b1c63b

Browse files
squidbusdiegolix29
authored andcommitted
semaphore: Use handles to properly handle semaphore double-delete. (shadps4-emu#1728)
1 parent a14a881 commit 8b1c63b

File tree

1 file changed

+17
-13
lines changed

1 file changed

+17
-13
lines changed

src/core/libraries/kernel/threads/semaphore.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "core/libraries/kernel/sync/semaphore.h"
1010

1111
#include "common/logging/log.h"
12+
#include "common/slot_vector.h"
1213
#include "core/libraries/kernel/kernel.h"
1314
#include "core/libraries/kernel/orbis_error.h"
1415
#include "core/libraries/kernel/posix_error.h"
@@ -188,55 +189,58 @@ class OrbisSem {
188189
bool is_fifo;
189190
};
190191

191-
using OrbisKernelSema = OrbisSem*;
192+
using OrbisKernelSema = Common::SlotId;
193+
194+
static Common::SlotVector<std::unique_ptr<OrbisSem>> orbis_sems;
192195

193196
s32 PS4_SYSV_ABI sceKernelCreateSema(OrbisKernelSema* sem, const char* pName, u32 attr,
194197
s32 initCount, s32 maxCount, const void* pOptParam) {
195198
if (!pName || attr > 2 || initCount < 0 || maxCount <= 0 || initCount > maxCount) {
196199
LOG_ERROR(Lib_Kernel, "Semaphore creation parameters are invalid!");
197200
return ORBIS_KERNEL_ERROR_EINVAL;
198201
}
199-
*sem = new OrbisSem(initCount, maxCount, pName, attr == 1);
202+
*sem = orbis_sems.insert(
203+
std::move(std::make_unique<OrbisSem>(initCount, maxCount, pName, attr == 1)));
200204
return ORBIS_OK;
201205
}
202206

203207
s32 PS4_SYSV_ABI sceKernelWaitSema(OrbisKernelSema sem, s32 needCount, u32* pTimeout) {
204-
if (!sem) {
208+
if (!orbis_sems.is_allocated(sem)) {
205209
return ORBIS_KERNEL_ERROR_ESRCH;
206210
}
207-
return sem->Wait(true, needCount, pTimeout);
211+
return orbis_sems[sem]->Wait(true, needCount, pTimeout);
208212
}
209213

210214
s32 PS4_SYSV_ABI sceKernelSignalSema(OrbisKernelSema sem, s32 signalCount) {
211-
if (!sem) {
215+
if (!orbis_sems.is_allocated(sem)) {
212216
return ORBIS_KERNEL_ERROR_ESRCH;
213217
}
214-
if (!sem->Signal(signalCount)) {
218+
if (!orbis_sems[sem]->Signal(signalCount)) {
215219
return ORBIS_KERNEL_ERROR_EINVAL;
216220
}
217221
return ORBIS_OK;
218222
}
219223

220224
s32 PS4_SYSV_ABI sceKernelPollSema(OrbisKernelSema sem, s32 needCount) {
221-
if (!sem) {
225+
if (!orbis_sems.is_allocated(sem)) {
222226
return ORBIS_KERNEL_ERROR_ESRCH;
223227
}
224-
return sem->Wait(false, needCount, nullptr);
228+
return orbis_sems[sem]->Wait(false, needCount, nullptr);
225229
}
226230

227231
int PS4_SYSV_ABI sceKernelCancelSema(OrbisKernelSema sem, s32 setCount, s32* pNumWaitThreads) {
228-
if (!sem) {
232+
if (!orbis_sems.is_allocated(sem)) {
229233
return ORBIS_KERNEL_ERROR_ESRCH;
230234
}
231-
return sem->Cancel(setCount, pNumWaitThreads);
235+
return orbis_sems[sem]->Cancel(setCount, pNumWaitThreads);
232236
}
233237

234238
int PS4_SYSV_ABI sceKernelDeleteSema(OrbisKernelSema sem) {
235-
if (!sem) {
239+
if (!orbis_sems.is_allocated(sem)) {
236240
return ORBIS_KERNEL_ERROR_ESRCH;
237241
}
238-
sem->Delete();
239-
delete sem;
242+
orbis_sems[sem]->Delete();
243+
orbis_sems.erase(sem);
240244
return ORBIS_OK;
241245
}
242246

0 commit comments

Comments
 (0)