mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-10-30 08:01:01 +00:00
fix some threading crashes
This commit is contained in:
parent
507f578dbb
commit
10ead40b5d
3 changed files with 31 additions and 27 deletions
|
|
@ -18,7 +18,7 @@ struct LoadingSegment {
|
||||||
extern struct LoadingSegment gCurrLoadingSegment;
|
extern struct LoadingSegment gCurrLoadingSegment;
|
||||||
|
|
||||||
#define LOADING_SCREEN_MUTEX(...) \
|
#define LOADING_SCREEN_MUTEX(...) \
|
||||||
if (!gCLIOpts.hideLoadingScreen && gLoadingThread.state != INVALID) { \
|
if (!gCLIOpts.hideLoadingScreen && gLoadingThread.state == RUNNING) { \
|
||||||
pthread_mutex_lock(&gLoadingThread.mutex); \
|
pthread_mutex_lock(&gLoadingThread.mutex); \
|
||||||
__VA_ARGS__; \
|
__VA_ARGS__; \
|
||||||
pthread_mutex_unlock(&gLoadingThread.mutex); \
|
pthread_mutex_unlock(&gLoadingThread.mutex); \
|
||||||
|
|
|
||||||
|
|
@ -6,19 +6,19 @@
|
||||||
int init_thread_handle(struct ThreadHandle *handle, void *(*entry)(void *), void *arg, void *sp, size_t sp_size) {
|
int init_thread_handle(struct ThreadHandle *handle, void *(*entry)(void *), void *arg, void *sp, size_t sp_size) {
|
||||||
int err1 = init_mutex(handle);
|
int err1 = init_mutex(handle);
|
||||||
int err2 = init_thread(handle, entry, arg, sp, sp_size);
|
int err2 = init_thread(handle, entry, arg, sp, sp_size);
|
||||||
|
|
||||||
return (err1 != 0 || err2 != 0);
|
return (err1 != 0 || err2 != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_thread_handle(struct ThreadHandle *handle) {
|
void free_thread_handle(struct ThreadHandle *handle) {
|
||||||
assert(handle != NULL);
|
assert(handle != NULL);
|
||||||
|
|
||||||
//int err = stop_thread(handle);
|
//int err = stop_thread(handle);
|
||||||
//assert(err == 0);
|
//assert(err == 0);
|
||||||
|
|
||||||
int err = destroy_mutex(handle);
|
int err = destroy_mutex(handle);
|
||||||
assert(err == 0);
|
assert(err == 0);
|
||||||
|
|
||||||
// Reset the memory of the thread handle, We no longer need the thread or mutex.
|
// Reset the memory of the thread handle, We no longer need the thread or mutex.
|
||||||
memset((void *)handle, 0, sizeof(struct ThreadHandle));
|
memset((void *)handle, 0, sizeof(struct ThreadHandle));
|
||||||
}
|
}
|
||||||
|
|
@ -26,18 +26,18 @@ void free_thread_handle(struct ThreadHandle *handle) {
|
||||||
// Optimally just call init_thread_handle instead.
|
// Optimally just call init_thread_handle instead.
|
||||||
int init_thread(struct ThreadHandle *handle, void *(*entry)(void *), void *arg, void *sp, size_t sp_size) {
|
int init_thread(struct ThreadHandle *handle, void *(*entry)(void *), void *arg, void *sp, size_t sp_size) {
|
||||||
assert(handle != NULL);
|
assert(handle != NULL);
|
||||||
|
|
||||||
// Setup our thread and create it.
|
// Setup our thread and create it.
|
||||||
pthread_attr_t thattr = { 0 };
|
pthread_attr_t thattr = { 0 };
|
||||||
|
|
||||||
// Initialize default attributes for a new thread.
|
// Initialize default attributes for a new thread.
|
||||||
int err = pthread_attr_init(&thattr);
|
int err = pthread_attr_init(&thattr);
|
||||||
assert(err == 0);
|
assert(err == 0);
|
||||||
|
|
||||||
// By default, We want the thread to be joinable.
|
// By default, We want the thread to be joinable.
|
||||||
err = pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
|
err = pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
|
||||||
assert(err == 0);
|
assert(err == 0);
|
||||||
|
|
||||||
// Set the stack if we have one specified, Otherwise we don't care.
|
// Set the stack if we have one specified, Otherwise we don't care.
|
||||||
// In truth, This honestly shouldn't be used on PC. But if somebody wants
|
// In truth, This honestly shouldn't be used on PC. But if somebody wants
|
||||||
// a really managed stack? This is possible.
|
// a really managed stack? This is possible.
|
||||||
|
|
@ -45,29 +45,33 @@ int init_thread(struct ThreadHandle *handle, void *(*entry)(void *), void *arg,
|
||||||
err = pthread_attr_setstack(&thattr, sp, sp_size);
|
err = pthread_attr_setstack(&thattr, sp, sp_size);
|
||||||
assert(err == 0);
|
assert(err == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create our thread.
|
// Create our thread.
|
||||||
int ret = pthread_create(&handle->thread, &thattr, entry, arg);
|
int ret = pthread_create(&handle->thread, &thattr, entry, arg);
|
||||||
|
|
||||||
// Destroy the thread attributes, They are no longer needed
|
// Destroy the thread attributes, They are no longer needed
|
||||||
err = pthread_attr_destroy(&thattr);
|
err = pthread_attr_destroy(&thattr);
|
||||||
assert(err == 0);
|
assert(err == 0);
|
||||||
|
|
||||||
handle->state = RUNNING;
|
handle->state = RUNNING;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int join_thread(struct ThreadHandle *handle) {
|
int join_thread(struct ThreadHandle *handle) {
|
||||||
assert(handle != NULL);
|
assert(handle != NULL);
|
||||||
|
|
||||||
|
handle->state = STOPPED;
|
||||||
|
|
||||||
// Join the thread and wait for it to finish.
|
// Join the thread and wait for it to finish.
|
||||||
return pthread_join(handle->thread, NULL);
|
return pthread_join(handle->thread, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int detach_thread(struct ThreadHandle *handle) {
|
int detach_thread(struct ThreadHandle *handle) {
|
||||||
assert(handle != NULL);
|
assert(handle != NULL);
|
||||||
|
|
||||||
|
handle->state = STOPPED;
|
||||||
|
|
||||||
// Detach the thread, it will no longer be joinable afterwards.
|
// Detach the thread, it will no longer be joinable afterwards.
|
||||||
return pthread_detach(handle->thread);
|
return pthread_detach(handle->thread);
|
||||||
}
|
}
|
||||||
|
|
@ -90,43 +94,43 @@ int stop_thread(struct ThreadHandle *handle) {
|
||||||
// Optimally just call init_thread_handle instead.
|
// Optimally just call init_thread_handle instead.
|
||||||
int init_mutex(struct ThreadHandle *handle) {
|
int init_mutex(struct ThreadHandle *handle) {
|
||||||
assert(handle != NULL);
|
assert(handle != NULL);
|
||||||
|
|
||||||
pthread_mutexattr_t mtattr;
|
pthread_mutexattr_t mtattr;
|
||||||
|
|
||||||
int err = pthread_mutexattr_init(&mtattr);
|
int err = pthread_mutexattr_init(&mtattr);
|
||||||
assert(err == 0);
|
assert(err == 0);
|
||||||
|
|
||||||
err = pthread_mutexattr_settype(&mtattr, PTHREAD_MUTEX_ERRORCHECK);
|
err = pthread_mutexattr_settype(&mtattr, PTHREAD_MUTEX_ERRORCHECK);
|
||||||
assert(err == 0);
|
assert(err == 0);
|
||||||
|
|
||||||
int ret = pthread_mutex_init(&handle->mutex, &mtattr);
|
int ret = pthread_mutex_init(&handle->mutex, &mtattr);
|
||||||
|
|
||||||
err = pthread_mutexattr_destroy(&mtattr);
|
err = pthread_mutexattr_destroy(&mtattr);
|
||||||
assert(err == 0);
|
assert(err == 0);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int destroy_mutex(struct ThreadHandle *handle) {
|
int destroy_mutex(struct ThreadHandle *handle) {
|
||||||
assert(handle != NULL);
|
assert(handle != NULL);
|
||||||
|
|
||||||
return pthread_mutex_destroy(&handle->mutex);
|
return pthread_mutex_destroy(&handle->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
int lock_mutex(struct ThreadHandle *handle) {
|
int lock_mutex(struct ThreadHandle *handle) {
|
||||||
assert(handle != NULL);
|
assert(handle != NULL);
|
||||||
|
|
||||||
return pthread_mutex_lock(&handle->mutex);
|
return pthread_mutex_lock(&handle->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
int trylock_mutex(struct ThreadHandle *handle) {
|
int trylock_mutex(struct ThreadHandle *handle) {
|
||||||
assert(handle != NULL);
|
assert(handle != NULL);
|
||||||
|
|
||||||
return pthread_mutex_trylock(&handle->mutex);
|
return pthread_mutex_trylock(&handle->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
int unlock_mutex(struct ThreadHandle *handle) {
|
int unlock_mutex(struct ThreadHandle *handle) {
|
||||||
assert(handle != NULL);
|
assert(handle != NULL);
|
||||||
|
|
||||||
return pthread_mutex_unlock(&handle->mutex);
|
return pthread_mutex_unlock(&handle->mutex);
|
||||||
}
|
}
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
// Macros
|
// Macros
|
||||||
#define MUTEX_LOCK(handle) if (handle.state != INVALID) { lock_mutex(&handle); }
|
#define MUTEX_LOCK(handle) if (handle.state == RUNNING) { lock_mutex(&handle); }
|
||||||
#define MUTEX_UNLOCK(handle) if (handle.state != INVALID) { unlock_mutex(&handle); }
|
#define MUTEX_UNLOCK(handle) if (handle.state == RUNNING) { unlock_mutex(&handle); }
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
enum ThreadState {
|
enum ThreadState {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue