From d9014600536e91345a109bf1338e2be53d23c2e6 Mon Sep 17 00:00:00 2001 From: GaryOderNichts <12049776+GaryOderNichts@users.noreply.github.com> Date: Tue, 13 Feb 2024 17:10:07 +0100 Subject: [PATCH 1/3] Implement detached threads The `AsyncTerm` thread is never joined but its handle is immediately closed. This works fine on Windows, but causes issues on other platforms where threads need to be explicitly detached if never joined (pthread, wiiu). This adds a new `PltDetachThread` function, which can be used instead of `PltCloseThread` to explictly detach a thread, requiring it to no longer be closed. --- src/Connection.c | 4 ++-- src/Platform.c | 20 ++++++++++++++++++++ src/PlatformThreads.h | 1 + 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/Connection.c b/src/Connection.c index 2b82eda..dddff92 100644 --- a/src/Connection.c +++ b/src/Connection.c @@ -175,8 +175,8 @@ static void ClInternalConnectionTerminated(int errorCode) LC_ASSERT(err == 0); } - // Close the thread handle since we can never wait on it - PltCloseThread(&terminationCallbackThread); + // Detach the thread since we never wait on it + PltDetachThread(&terminationCallbackThread); } static bool parseRtspPortNumberFromUrl(const char* rtspSessionUrl, uint16_t* port) diff --git a/src/Platform.c b/src/Platform.c index f41ffde..ddd05a9 100644 --- a/src/Platform.c +++ b/src/Platform.c @@ -204,6 +204,26 @@ void PltJoinThread(PLT_THREAD* thread) { #endif } +void PltDetachThread(PLT_THREAD* thread) +{ + // Assume detached threads are no longer active + activeThreads--; + +#if defined(LC_WINDOWS) + // According MSDN: + // "Closing a thread handle does not terminate the associated thread or remove the thread object." + CloseHandle(thread->handle); +#elif defined(__vita__) + sceKernelDeleteThread(thread->handle); +#elif defined(__WIIU__) + OSDetachThread(&thread->thread); +#elif defined(__3DS__) + threadDetach(thread->thread); +#else + pthread_detach(thread->thread); +#endif +} + void PltCloseThread(PLT_THREAD* thread) { activeThreads--; #if defined(LC_WINDOWS) diff --git a/src/PlatformThreads.h b/src/PlatformThreads.h index 67cdb5e..75d1980 100644 --- a/src/PlatformThreads.h +++ b/src/PlatformThreads.h @@ -66,6 +66,7 @@ void PltCloseThread(PLT_THREAD* thread); void PltInterruptThread(PLT_THREAD* thread); bool PltIsThreadInterrupted(PLT_THREAD* thread); void PltJoinThread(PLT_THREAD* thread); +void PltDetachThread(PLT_THREAD* thread); int PltCreateEvent(PLT_EVENT* event); void PltCloseEvent(PLT_EVENT* event); From dbdd08ece9263bc1646ebd0a2f3d56b49586c040 Mon Sep 17 00:00:00 2001 From: GaryOderNichts <12049776+GaryOderNichts@users.noreply.github.com> Date: Tue, 13 Feb 2024 17:10:38 +0100 Subject: [PATCH 2/3] 3ds: Free threads on close --- src/Platform.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Platform.c b/src/Platform.c index ddd05a9..6975186 100644 --- a/src/Platform.c +++ b/src/Platform.c @@ -198,7 +198,6 @@ void PltJoinThread(PLT_THREAD* thread) { OSJoinThread(&thread->thread, NULL); #elif defined(__3DS__) threadJoin(thread->thread, U64_MAX); - threadFree(thread->thread); #else pthread_join(thread->thread, NULL); #endif @@ -230,6 +229,12 @@ void PltCloseThread(PLT_THREAD* thread) { CloseHandle(thread->handle); #elif defined(__vita__) sceKernelDeleteThread(thread->handle); +#elif defined(__WIIU__) + // Thread is automatically closed after join +#elif defined(__3DS__) + threadFree(thread->thread); +#else + // Thread is automatically closed after join #endif } From e6ba62d9bdfa02dc912fb61ceab935ce303e7410 Mon Sep 17 00:00:00 2001 From: GaryOderNichts <12049776+GaryOderNichts@users.noreply.github.com> Date: Tue, 13 Feb 2024 17:11:09 +0100 Subject: [PATCH 3/3] wiiu: Revise thread creation --- src/Platform.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Platform.c b/src/Platform.c index 6975186..625b924 100644 --- a/src/Platform.c +++ b/src/Platform.c @@ -287,19 +287,29 @@ int PltCreateThread(const char* name, ThreadEntry entry, void* context, PLT_THRE sceKernelStartThread(thread->handle, sizeof(struct thread_context), ctx); } #elif defined(__WIIU__) - int stack_size = 4 * 1024 * 1024; - void* stack_addr = (uint8_t *)memalign(8, stack_size) + stack_size; + memset(&thread->thread, 0, sizeof(thread->thread)); + // Allocate stack + const int stack_size = 4 * 1024 * 1024; + uint8_t* stack = (uint8_t*)memalign(16, stack_size); + if (stack == NULL) { + free(ctx); + return -1; + } + + // Create thread if (!OSCreateThread(&thread->thread, ThreadProc, 0, (char*)ctx, - stack_addr, stack_size, + stack + stack_size, stack_size, 0x10, OS_THREAD_ATTRIB_AFFINITY_ANY)) { free(ctx); + free(stack); return -1; } + OSSetThreadName(&thread->thread, name); OSSetThreadDeallocator(&thread->thread, thread_deallocator); OSResumeThread(&thread->thread); #elif defined(__3DS__)