mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2026-06-17 22:31:21 +00:00
Fix a race condition where PltCloseThread was called before the thread was inserted into the list
This commit is contained in:
@@ -41,6 +41,9 @@ void* ThreadProc(void* context) {
|
|||||||
thread_head = ctx->thread;
|
thread_head = ctx->thread;
|
||||||
PltUnlockMutex(&thread_list_lock);
|
PltUnlockMutex(&thread_list_lock);
|
||||||
|
|
||||||
|
// Signal the event since the thread is now inserted
|
||||||
|
PltSetEvent(&ctx->thread->insertedEvent);
|
||||||
|
|
||||||
ctx->entry(ctx->context);
|
ctx->entry(ctx->context);
|
||||||
|
|
||||||
free(ctx);
|
free(ctx);
|
||||||
@@ -165,6 +168,8 @@ void PltCloseThread(PLT_THREAD* thread) {
|
|||||||
|
|
||||||
PltUnlockMutex(&thread_list_lock);
|
PltUnlockMutex(&thread_list_lock);
|
||||||
|
|
||||||
|
PltCloseEvent(&thread->insertedEvent);
|
||||||
|
|
||||||
#if defined(LC_WINDOWS)
|
#if defined(LC_WINDOWS)
|
||||||
CloseHandle(thread->termRequested);
|
CloseHandle(thread->termRequested);
|
||||||
CloseHandle(thread->handle);
|
CloseHandle(thread->handle);
|
||||||
@@ -195,36 +200,49 @@ int PltCreateThread(ThreadEntry entry, void* context, PLT_THREAD* thread) {
|
|||||||
ctx->context = context;
|
ctx->context = context;
|
||||||
ctx->thread = thread;
|
ctx->thread = thread;
|
||||||
|
|
||||||
|
err = PltCreateEvent(&thread->insertedEvent);
|
||||||
|
if (err != 0) {
|
||||||
|
free(ctx);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
thread->cancelled = 0;
|
thread->cancelled = 0;
|
||||||
|
|
||||||
#if defined(LC_WINDOWS)
|
#if defined(LC_WINDOWS)
|
||||||
{
|
{
|
||||||
thread->termRequested = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
|
thread->termRequested = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
|
||||||
if (thread->termRequested == NULL) {
|
if (thread->termRequested == NULL) {
|
||||||
|
PltCloseEvent(&thread->insertedEvent);
|
||||||
free(ctx);
|
free(ctx);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread->handle = CreateThread(NULL, 0, ThreadProc, ctx, 0, &thread->tid);
|
thread->handle = CreateThread(NULL, 0, ThreadProc, ctx, 0, &thread->tid);
|
||||||
if (thread->handle == NULL) {
|
if (thread->handle == NULL) {
|
||||||
|
PltCloseEvent(&thread->insertedEvent);
|
||||||
CloseHandle(thread->termRequested);
|
CloseHandle(thread->termRequested);
|
||||||
free(ctx);
|
free(ctx);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
err = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
err = pthread_create(&thread->thread, NULL, ThreadProc, ctx);
|
err = pthread_create(&thread->thread, NULL, ThreadProc, ctx);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
|
PltCloseEvent(&thread->insertedEvent);
|
||||||
free(ctx);
|
free(ctx);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return err;
|
// We shouldn't get this far with an error
|
||||||
|
LC_ASSERT(err == 0);
|
||||||
|
|
||||||
|
// Wait for the thread to be started and inserted into the active threads list
|
||||||
|
PltWaitForEvent(&thread->insertedEvent);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PltCreateEvent(PLT_EVENT* event) {
|
int PltCreateEvent(PLT_EVENT* event) {
|
||||||
|
|||||||
@@ -6,29 +6,31 @@
|
|||||||
typedef void(*ThreadEntry)(void* context);
|
typedef void(*ThreadEntry)(void* context);
|
||||||
|
|
||||||
#if defined(LC_WINDOWS)
|
#if defined(LC_WINDOWS)
|
||||||
|
typedef HANDLE PLT_MUTEX;
|
||||||
|
typedef HANDLE PLT_EVENT;
|
||||||
typedef struct _PLT_THREAD {
|
typedef struct _PLT_THREAD {
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
int cancelled;
|
int cancelled;
|
||||||
DWORD tid;
|
DWORD tid;
|
||||||
HANDLE termRequested;
|
HANDLE termRequested;
|
||||||
|
PLT_EVENT insertedEvent;
|
||||||
|
|
||||||
struct _PLT_THREAD* next;
|
struct _PLT_THREAD* next;
|
||||||
} PLT_THREAD;
|
} PLT_THREAD;
|
||||||
typedef HANDLE PLT_MUTEX;
|
|
||||||
typedef HANDLE PLT_EVENT;
|
|
||||||
#elif defined (LC_POSIX)
|
#elif defined (LC_POSIX)
|
||||||
typedef struct _PLT_THREAD {
|
|
||||||
pthread_t thread;
|
|
||||||
int cancelled;
|
|
||||||
|
|
||||||
struct _PLT_THREAD* next;
|
|
||||||
} PLT_THREAD;
|
|
||||||
typedef pthread_mutex_t PLT_MUTEX;
|
typedef pthread_mutex_t PLT_MUTEX;
|
||||||
typedef struct _PLT_EVENT {
|
typedef struct _PLT_EVENT {
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
pthread_cond_t cond;
|
pthread_cond_t cond;
|
||||||
int signalled;
|
int signalled;
|
||||||
} PLT_EVENT;
|
} PLT_EVENT;
|
||||||
|
typedef struct _PLT_THREAD {
|
||||||
|
pthread_t thread;
|
||||||
|
int cancelled;
|
||||||
|
PLT_EVENT insertedEvent;
|
||||||
|
|
||||||
|
struct _PLT_THREAD* next;
|
||||||
|
} PLT_THREAD;
|
||||||
#else
|
#else
|
||||||
#error Unsupported platform
|
#error Unsupported platform
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user