Merge pull request #4063 from MarcZX100/codex/carry-pthread-join-self-4052
fix(libkernel): return EDEADLK for self-join and EINVAL for null threads
This commit is contained in:
commit
fb23e85f66
|
|
@ -624,7 +624,7 @@ int APS5_VABI scePthreadCreate(Pthread* thread, const PthreadAttr* attr, Pthread
|
|||
}
|
||||
|
||||
int APS5_VABI scePthreadJoin(Pthread thread, void** retval) {
|
||||
if (!thread) throw std::runtime_error("scePthreadJoin: null thread");
|
||||
if (!thread) return SCE_KERNEL_ERROR_EINVAL;
|
||||
if (thread->_detached) return SCE_KERNEL_ERROR_EINVAL;
|
||||
if (thread == CurrentGuestState().current) return SCE_KERNEL_ERROR_EDEADLK;
|
||||
ThreadCancel::Check();
|
||||
|
|
@ -647,7 +647,7 @@ int APS5_VABI scePthreadJoin(Pthread thread, void** retval) {
|
|||
}
|
||||
|
||||
int APS5_VABI scePthreadDetach(Pthread thread) {
|
||||
if (!thread) throw std::runtime_error("scePthreadDetach: null thread");
|
||||
if (!thread) return SCE_KERNEL_ERROR_EINVAL;
|
||||
if (thread->_detached) return SCE_KERNEL_ERROR_EINVAL;
|
||||
thread->_detached = true;
|
||||
#ifdef _WIN32
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ extern "C" {
|
|||
int APS5_VABI scePthreadCreate(Pthread* thread, const PthreadAttr* attr, PthreadEntry entry, void* arg, const char* name);
|
||||
int APS5_VABI scePthreadJoin(Pthread thread, void** retval);
|
||||
int APS5_VABI scePthreadDetach(Pthread thread);
|
||||
int APS5_VABI pthread_join_nid_postfix(Pthread thread, void** value);
|
||||
int APS5_VABI pthread_detach_nid_postfix(Pthread thread);
|
||||
void APS5_VABI scePthreadExit(void* retval);
|
||||
Pthread APS5_VABI scePthreadSelf();
|
||||
int APS5_VABI scePthreadGetthreadid(void);
|
||||
|
|
@ -46,6 +48,9 @@ static bool StackContains(Pthread thread, const void* address) {
|
|||
static constexpr int SCE_OK = 0;
|
||||
static constexpr int SCE_KERNEL_ERROR_EINVAL = 0x80020016;
|
||||
static constexpr int SCE_KERNEL_ERROR_EPERM = 0x80020001;
|
||||
static constexpr int SCE_KERNEL_ERROR_EDEADLK = 0x8002000b;
|
||||
static constexpr int GUEST_EDEADLK = 11;
|
||||
static constexpr int GUEST_EINVAL = 22;
|
||||
static constexpr int MUTEX_TYPE_RECURSIVE = 2;
|
||||
static constexpr int PTHREAD_CANCEL_ENABLE = 0;
|
||||
static constexpr int PTHREAD_CANCEL_ASYNCHRONOUS = 2;
|
||||
|
|
@ -69,6 +74,8 @@ struct WorkerContext {
|
|||
PthreadMutex* mutex = nullptr;
|
||||
int unlockResult = 0;
|
||||
bool testcancelReturned = false;
|
||||
int sceJoinSelf = 0;
|
||||
int posixJoinSelf = 0;
|
||||
};
|
||||
|
||||
static void* APS5_VABI Worker(void* arg) {
|
||||
|
|
@ -80,6 +87,8 @@ static void* APS5_VABI Worker(void* arg) {
|
|||
int local = 0;
|
||||
context.workerStackReported = StackContains(context.selfFromWorker, &local);
|
||||
context.unlockResult = scePthreadMutexUnlock(context.mutex);
|
||||
context.sceJoinSelf = scePthreadJoin(context.selfFromWorker, nullptr);
|
||||
context.posixJoinSelf = pthread_join_nid_postfix(context.selfFromWorker, nullptr);
|
||||
int oldState = -1;
|
||||
int oldType = -1;
|
||||
context.testcancelReturned = scePthreadSetcancelstate(PTHREAD_CANCEL_ENABLE, &oldState) == SCE_OK &&
|
||||
|
|
@ -103,6 +112,10 @@ int main() {
|
|||
Require(StackContains(mainSelf, &local));
|
||||
Require(scePthreadJoin(mainSelf, nullptr) == SCE_KERNEL_ERROR_EINVAL);
|
||||
Require(scePthreadDetach(mainSelf) == SCE_KERNEL_ERROR_EINVAL);
|
||||
Require(scePthreadJoin(nullptr, nullptr) == SCE_KERNEL_ERROR_EINVAL);
|
||||
Require(scePthreadDetach(nullptr) == SCE_KERNEL_ERROR_EINVAL);
|
||||
Require(pthread_join_nid_postfix(nullptr, nullptr) == GUEST_EINVAL);
|
||||
Require(pthread_detach_nid_postfix(nullptr) == GUEST_EINVAL);
|
||||
|
||||
PthreadMutexattr attr = nullptr;
|
||||
Require(scePthreadMutexattrInit(&attr) == SCE_OK);
|
||||
|
|
@ -129,6 +142,8 @@ int main() {
|
|||
Require(context.workerThreadId == static_cast<int>(context.workerTid));
|
||||
Require(context.workerPosixThreadId == context.workerThreadId && context.workerPosixThreadId != static_cast<int>(mainTid));
|
||||
Require(context.unlockResult == SCE_KERNEL_ERROR_EPERM);
|
||||
Require(context.sceJoinSelf == SCE_KERNEL_ERROR_EDEADLK);
|
||||
Require(context.posixJoinSelf == GUEST_EDEADLK);
|
||||
Require(context.workerStackReported);
|
||||
Require(context.testcancelReturned);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue