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..625b924 100644 --- a/src/Platform.c +++ b/src/Platform.c @@ -198,18 +198,43 @@ 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 } +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) 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 } @@ -262,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__) 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);