mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-01-28 17:28:26 +00:00
semaphore: Use handles to properly handle semaphore double-delete. (#1728)
This commit is contained in:
parent
bf41ab6c40
commit
41fd1c84cf
|
@ -9,6 +9,7 @@
|
||||||
#include "core/libraries/kernel/sync/semaphore.h"
|
#include "core/libraries/kernel/sync/semaphore.h"
|
||||||
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/slot_vector.h"
|
||||||
#include "core/libraries/kernel/kernel.h"
|
#include "core/libraries/kernel/kernel.h"
|
||||||
#include "core/libraries/kernel/orbis_error.h"
|
#include "core/libraries/kernel/orbis_error.h"
|
||||||
#include "core/libraries/kernel/posix_error.h"
|
#include "core/libraries/kernel/posix_error.h"
|
||||||
|
@ -188,7 +189,9 @@ public:
|
||||||
bool is_fifo;
|
bool is_fifo;
|
||||||
};
|
};
|
||||||
|
|
||||||
using OrbisKernelSema = OrbisSem*;
|
using OrbisKernelSema = Common::SlotId;
|
||||||
|
|
||||||
|
static Common::SlotVector<std::unique_ptr<OrbisSem>> orbis_sems;
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceKernelCreateSema(OrbisKernelSema* sem, const char* pName, u32 attr,
|
s32 PS4_SYSV_ABI sceKernelCreateSema(OrbisKernelSema* sem, const char* pName, u32 attr,
|
||||||
s32 initCount, s32 maxCount, const void* pOptParam) {
|
s32 initCount, s32 maxCount, const void* pOptParam) {
|
||||||
|
@ -196,47 +199,48 @@ s32 PS4_SYSV_ABI sceKernelCreateSema(OrbisKernelSema* sem, const char* pName, u3
|
||||||
LOG_ERROR(Lib_Kernel, "Semaphore creation parameters are invalid!");
|
LOG_ERROR(Lib_Kernel, "Semaphore creation parameters are invalid!");
|
||||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
*sem = new OrbisSem(initCount, maxCount, pName, attr == 1);
|
*sem = orbis_sems.insert(
|
||||||
|
std::move(std::make_unique<OrbisSem>(initCount, maxCount, pName, attr == 1)));
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceKernelWaitSema(OrbisKernelSema sem, s32 needCount, u32* pTimeout) {
|
s32 PS4_SYSV_ABI sceKernelWaitSema(OrbisKernelSema sem, s32 needCount, u32* pTimeout) {
|
||||||
if (!sem) {
|
if (!orbis_sems.is_allocated(sem)) {
|
||||||
return ORBIS_KERNEL_ERROR_ESRCH;
|
return ORBIS_KERNEL_ERROR_ESRCH;
|
||||||
}
|
}
|
||||||
return sem->Wait(true, needCount, pTimeout);
|
return orbis_sems[sem]->Wait(true, needCount, pTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceKernelSignalSema(OrbisKernelSema sem, s32 signalCount) {
|
s32 PS4_SYSV_ABI sceKernelSignalSema(OrbisKernelSema sem, s32 signalCount) {
|
||||||
if (!sem) {
|
if (!orbis_sems.is_allocated(sem)) {
|
||||||
return ORBIS_KERNEL_ERROR_ESRCH;
|
return ORBIS_KERNEL_ERROR_ESRCH;
|
||||||
}
|
}
|
||||||
if (!sem->Signal(signalCount)) {
|
if (!orbis_sems[sem]->Signal(signalCount)) {
|
||||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceKernelPollSema(OrbisKernelSema sem, s32 needCount) {
|
s32 PS4_SYSV_ABI sceKernelPollSema(OrbisKernelSema sem, s32 needCount) {
|
||||||
if (!sem) {
|
if (!orbis_sems.is_allocated(sem)) {
|
||||||
return ORBIS_KERNEL_ERROR_ESRCH;
|
return ORBIS_KERNEL_ERROR_ESRCH;
|
||||||
}
|
}
|
||||||
return sem->Wait(false, needCount, nullptr);
|
return orbis_sems[sem]->Wait(false, needCount, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelCancelSema(OrbisKernelSema sem, s32 setCount, s32* pNumWaitThreads) {
|
int PS4_SYSV_ABI sceKernelCancelSema(OrbisKernelSema sem, s32 setCount, s32* pNumWaitThreads) {
|
||||||
if (!sem) {
|
if (!orbis_sems.is_allocated(sem)) {
|
||||||
return ORBIS_KERNEL_ERROR_ESRCH;
|
return ORBIS_KERNEL_ERROR_ESRCH;
|
||||||
}
|
}
|
||||||
return sem->Cancel(setCount, pNumWaitThreads);
|
return orbis_sems[sem]->Cancel(setCount, pNumWaitThreads);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelDeleteSema(OrbisKernelSema sem) {
|
int PS4_SYSV_ABI sceKernelDeleteSema(OrbisKernelSema sem) {
|
||||||
if (!sem) {
|
if (!orbis_sems.is_allocated(sem)) {
|
||||||
return ORBIS_KERNEL_ERROR_ESRCH;
|
return ORBIS_KERNEL_ERROR_ESRCH;
|
||||||
}
|
}
|
||||||
sem->Delete();
|
orbis_sems[sem]->Delete();
|
||||||
delete sem;
|
orbis_sems.erase(sem);
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue