From 2323ca6c9ec3c8ee76b9acf13745b80b92952a6a Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 18 Mar 2019 23:47:45 +0100 Subject: Add struct, import caching, binop ops etc --- src/std/thread.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) (limited to 'src/std/thread.c') diff --git a/src/std/thread.c b/src/std/thread.c index 64a7f1b..ba67463 100644 --- a/src/std/thread.c +++ b/src/std/thread.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -48,12 +49,21 @@ int amal_thread_deinit(amal_thread *self) { if(self->cancellable) { r1 = pthread_cancel(self->thread_id); + /* thread deinit on a thread that has not been started shouldn't be an error */ + if(r1 == ESRCH) + r1 = 0; + if(r1 != 0) + amal_log_error("amal_thread_deinit: failed to cancel thread, error: %s", strerror(r1)); self->cancellable = bool_false; } + if(self->destroyable) { r2 = pthread_attr_destroy(&self->thread_attr); + if(r2 != 0) + amal_log_error("amal_thread_deinit: failed to destroy thread attributes, error: %s", strerror(r2)); self->destroyable = bool_false; } + return r1 != 0 ? r1 : r2; } @@ -73,20 +83,35 @@ int amal_thread_detach(amal_thread *self) { int amal_thread_join(amal_thread *self, void **result) { int result_err; int thread_type; - if((result_err = pthread_attr_getdetachstate(&self->thread_attr, &thread_type)) != 0) + + if((result_err = pthread_attr_getdetachstate(&self->thread_attr, &thread_type)) != 0) { + amal_log_error("amal_thread_join: failed to get detach state, error: %d", result_err); return result_err; - if(thread_type != PTHREAD_CREATE_JOINABLE) + } + + if(thread_type != PTHREAD_CREATE_JOINABLE) { + amal_log_error("amal_thread_join: thread not joinable type"); return AMAL_THREAD_NOT_JOINABLE; - if((result_err = pthread_join(self->thread_id, result)) != 0) + } + + if((result_err = pthread_join(self->thread_id, result)) != 0) { + /* Joining a thread that is not joinable shouldn't be an error */ + if(result_err == ESRCH) + goto cleanup; + amal_log_error("amal_thread_join: failed to join thread %llu, error: %s", self->thread_id, strerror(result_err)); return result_err == EINVAL ? AMAL_THREAD_NOT_JOINABLE : result_err; + } + + cleanup: self->cancellable = bool_false; return 0; } void amal_mutex_init(amal_mutex *self) { pthread_mutex_init(&self->mutex, NULL); - /* TODO: pthread_mutex_destroy in amal_mutex_deinit */ self->lock_identifier = NULL; + self->locked = bool_false; + self->owner_thread = 0; } void amal_mutex_deinit(amal_mutex *self) { @@ -105,6 +130,8 @@ int amal_mutex_lock(amal_mutex *self, const char *lock_identifier) { int result; result = pthread_mutex_lock(&self->mutex); self->lock_identifier = lock_identifier; + self->owner_thread = pthread_self(); + self->locked = bool_true; #ifdef AMAL_MUTEX_DEBUG if(result == 0 && self->lock_identifier) { amal_log_debug("amal_mutex_lock: mutex locked by thread %lu (%s), identification: %s", @@ -122,6 +149,10 @@ int amal_mutex_unlock(amal_mutex *self) { const char *identifier; identifier = self->lock_identifier; #endif + if(!self->locked || pthread_equal(self->owner_thread, pthread_self()) == 0) + return 0; + self->locked = bool_false; + self->owner_thread = 0; result = pthread_mutex_unlock(&self->mutex); #ifdef AMAL_MUTEX_DEBUG if(result == 0 && identifier) { -- cgit v1.2.3