From 2fd39039ac990178d0d1bd175974b47ff8358faf Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Tue, 12 Aug 2025 19:20:31 -0500 Subject: [PATCH] Update: Add thread mutex attribute defines, update tests, and add missing error handling. Define `_di_f_thread_mutex_attribute_d_` such that the mutex attributes like `PTHREAD_MUTEX_NORMAL` have a mapped define. The mutex lock and try lock are no longer missing the handling of `ENOTRECOVERABLE` and `EOWNERDEAD` errors. --- build/disable/level_0/f_thread.h | 1 + build/stand_alone/byte_dump.config.h | 1 + build/stand_alone/example.config.h | 1 + build/stand_alone/fake.config.h | 1 + build/stand_alone/firewall.config.h | 1 + build/stand_alone/utf8.config.h | 1 + level_0/f_thread/c/thread.c | 4 ++++ level_0/f_thread/c/thread.h | 6 +++++- level_0/f_thread/c/thread/mutex_attribute.h | 14 ++++++++++++++ level_0/f_thread/tests/unit/c/test-thread-mutex_lock.c | 6 +++++- level_0/f_thread/tests/unit/c/test-thread-mutex_lock_try.c | 6 +++++- 11 files changed, 39 insertions(+), 3 deletions(-) diff --git a/build/disable/level_0/f_thread.h b/build/disable/level_0/f_thread.h index 1e977fd..2d23460 100644 --- a/build/disable/level_0/f_thread.h +++ b/build/disable/level_0/f_thread.h @@ -129,6 +129,7 @@ #define _di_f_thread_mutex_attribute_protocol_set_ #define _di_f_thread_mutex_attribute_shared_get_ #define _di_f_thread_mutex_attribute_shared_set_ +#define _di_f_thread_mutex_attribute_d_ #define _di_f_thread_mutex_attribute_t_ #define _di_f_thread_mutex_attribute_type_get_ #define _di_f_thread_mutex_attribute_type_set_ diff --git a/build/stand_alone/byte_dump.config.h b/build/stand_alone/byte_dump.config.h index b89882c..53265c6 100644 --- a/build/stand_alone/byte_dump.config.h +++ b/build/stand_alone/byte_dump.config.h @@ -1140,6 +1140,7 @@ #define _di_f_thread_mutex_attribute_protocol_set_ #define _di_f_thread_mutex_attribute_shared_get_ #define _di_f_thread_mutex_attribute_shared_set_ +#define _di_f_thread_mutex_attribute_d_ #define _di_f_thread_mutex_attribute_t_ #define _di_f_thread_mutex_attribute_type_get_ #define _di_f_thread_mutex_attribute_type_set_ diff --git a/build/stand_alone/example.config.h b/build/stand_alone/example.config.h index 4170ed5..e96aa97 100644 --- a/build/stand_alone/example.config.h +++ b/build/stand_alone/example.config.h @@ -1091,6 +1091,7 @@ #define _di_f_thread_mutex_attribute_protocol_set_ #define _di_f_thread_mutex_attribute_shared_get_ #define _di_f_thread_mutex_attribute_shared_set_ +#define _di_f_thread_mutex_attribute_d_ #define _di_f_thread_mutex_attribute_t_ #define _di_f_thread_mutex_attribute_type_get_ #define _di_f_thread_mutex_attribute_type_set_ diff --git a/build/stand_alone/fake.config.h b/build/stand_alone/fake.config.h index 3490d0e..5484633 100644 --- a/build/stand_alone/fake.config.h +++ b/build/stand_alone/fake.config.h @@ -1582,6 +1582,7 @@ #define _di_f_thread_mutex_attribute_protocol_set_ #define _di_f_thread_mutex_attribute_shared_get_ #define _di_f_thread_mutex_attribute_shared_set_ +#define _di_f_thread_mutex_attribute_d_ #define _di_f_thread_mutex_attribute_t_ #define _di_f_thread_mutex_attribute_type_get_ #define _di_f_thread_mutex_attribute_type_set_ diff --git a/build/stand_alone/firewall.config.h b/build/stand_alone/firewall.config.h index d3ff515..2e3c78b 100644 --- a/build/stand_alone/firewall.config.h +++ b/build/stand_alone/firewall.config.h @@ -1630,6 +1630,7 @@ #define _di_f_thread_mutex_attribute_protocol_set_ #define _di_f_thread_mutex_attribute_shared_get_ #define _di_f_thread_mutex_attribute_shared_set_ +#define _di_f_thread_mutex_attribute_d_ #define _di_f_thread_mutex_attribute_t_ #define _di_f_thread_mutex_attribute_type_get_ #define _di_f_thread_mutex_attribute_type_set_ diff --git a/build/stand_alone/utf8.config.h b/build/stand_alone/utf8.config.h index f360591..421882f 100644 --- a/build/stand_alone/utf8.config.h +++ b/build/stand_alone/utf8.config.h @@ -1158,6 +1158,7 @@ #define _di_f_thread_mutex_attribute_protocol_set_ #define _di_f_thread_mutex_attribute_shared_get_ #define _di_f_thread_mutex_attribute_shared_set_ +#define _di_f_thread_mutex_attribute_d_ #define _di_f_thread_mutex_attribute_t_ #define _di_f_thread_mutex_attribute_type_get_ #define _di_f_thread_mutex_attribute_type_set_ diff --git a/level_0/f_thread/c/thread.c b/level_0/f_thread/c/thread.c index 4f6bde1..aeed44b 100644 --- a/level_0/f_thread/c/thread.c +++ b/level_0/f_thread/c/thread.c @@ -1590,6 +1590,8 @@ extern "C" { if (error == EAGAIN) return F_status_set_error(F_resource_not); if (error == EDEADLK) return F_status_set_error(F_deadlock); if (error == EINVAL) return F_status_set_error(F_parameter); + if (error == ENOTRECOVERABLE) return F_status_set_error(F_recover_not); + if (error == EOWNERDEAD) return F_status_set_error(F_dead); return F_status_set_error(F_failure); } @@ -1634,6 +1636,8 @@ extern "C" { if (error == EAGAIN) return F_status_set_error(F_resource_not); if (error == EBUSY) return F_busy; if (error == EINVAL) return F_status_set_error(F_parameter); + if (error == ENOTRECOVERABLE) return F_status_set_error(F_recover_not); + if (error == EOWNERDEAD) return F_status_set_error(F_dead); return F_status_set_error(F_failure); } diff --git a/level_0/f_thread/c/thread.h b/level_0/f_thread/c/thread.h index a3b4a01..334c7cf 100644 --- a/level_0/f_thread/c/thread.h +++ b/level_0/f_thread/c/thread.h @@ -2215,8 +2215,10 @@ extern "C" { * @return * F_okay on success. * + * F_dead (with error bit) if the owning thread terminated while holding the mutex lock (thread is dead). * F_deadlock (with error bit) if operation would cause a deadlock. * F_parameter (with error bit) if a parameter is invalid. + * F_recover_not (with error bit) if the state protected by the mutex is not recoverable. * F_resource_not (with error bit) if max mutex locks is reached. * * F_failure (with error bit) on any other error. @@ -2247,12 +2249,12 @@ extern "C" { * F_okay on success. * F_time if the timeout was reached before obtaining the lock. * + * F_dead (with error bit) if the owning thread terminated while holding the mutex lock (thread is dead). * F_deadlock (with error bit) if operation would cause a deadlock. * F_parameter (with error bit) if a parameter is invalid. * F_prohibited (with error bit) if not allowed to perform the operation. * F_recover_not (with error bit) if the state protected by the mutex is not recoverable. * F_resource_not (with error bit) if max mutex locks is reached. - * F_dead (with error bit) if the owning thread terminated while holding the mutex lock (thread is dead). * * F_failure (with error bit) on any other error. * @@ -2278,7 +2280,9 @@ extern "C" { * F_okay on success. * F_busy on success, but the mutex is already locked. * + * F_dead (with error bit) if the owning thread terminated while holding the mutex lock (thread is dead). * F_parameter (with error bit) if a parameter is invalid. + * F_recover_not (with error bit) if the state protected by the mutex is not recoverable. * F_resource_not (with error bit) if max mutex locks is reached. * * F_failure (with error bit) on any other error. diff --git a/level_0/f_thread/c/thread/mutex_attribute.h b/level_0/f_thread/c/thread/mutex_attribute.h index 7beec57..dc6176d 100644 --- a/level_0/f_thread/c/thread/mutex_attribute.h +++ b/level_0/f_thread/c/thread/mutex_attribute.h @@ -17,6 +17,20 @@ extern "C" { #endif /** + * Mutex attribute defines. + * + * f_thread_mutex_attribute_*_d: + * - error_check: Handle deadlock and ownership detection and return on error. + * - normal: The normal mutex type (also the default type and is the POSIX standard compliant version of PTHREAD_MUTEX_DEFAULT). + * - recursive: Recursive lock (uses a count on locks, mutexs become unlocked when count is 0). + */ +#ifndef _di_f_thread_mutex_attribute_d_ + #define f_thread_mutex_attribute_error_check_d PTHREAD_MUTEX_ERRORCHECK + #define f_thread_mutex_attribute_normal_d PTHREAD_MUTEX_RECURSIVE + #define f_thread_mutex_attribute_recursive_d PTHREAD_MUTEX_NORMAL +#endif // _di_f_thread_mutex_attribute_d_ + +/** * A typedef representing pthread_mutex_attribute_t. */ #ifndef _di_f_thread_mutex_attribute_t_ diff --git a/level_0/f_thread/tests/unit/c/test-thread-mutex_lock.c b/level_0/f_thread/tests/unit/c/test-thread-mutex_lock.c index aacd97c..dbdf185 100644 --- a/level_0/f_thread/tests/unit/c/test-thread-mutex_lock.c +++ b/level_0/f_thread/tests/unit/c/test-thread-mutex_lock.c @@ -13,6 +13,8 @@ void test__f_thread_mutex_lock__fails(void **state) { EAGAIN, EDEADLK, EINVAL, + ENOTRECOVERABLE, + EOWNERDEAD, mock_errno_generic, }; @@ -20,10 +22,12 @@ void test__f_thread_mutex_lock__fails(void **state) { F_resource_not, F_deadlock, F_parameter, + F_recover_not, + F_dead, F_failure, }; - for (uint8_t i = 0; i < 4; ++i) { + for (uint8_t i = 0; i < 6; ++i) { will_return(__wrap_pthread_mutex_lock, true); will_return(__wrap_pthread_mutex_lock, errnos[i]); diff --git a/level_0/f_thread/tests/unit/c/test-thread-mutex_lock_try.c b/level_0/f_thread/tests/unit/c/test-thread-mutex_lock_try.c index a8479b5..48f3738 100644 --- a/level_0/f_thread/tests/unit/c/test-thread-mutex_lock_try.c +++ b/level_0/f_thread/tests/unit/c/test-thread-mutex_lock_try.c @@ -16,6 +16,8 @@ void test__f_thread_mutex_lock_try__fails(void **state) { EAGAIN, EBUSY, EINVAL, + ENOTRECOVERABLE, + EOWNERDEAD, mock_errno_generic, }; @@ -23,10 +25,12 @@ void test__f_thread_mutex_lock_try__fails(void **state) { F_status_set_error(F_resource_not), F_busy, F_status_set_error(F_parameter), + F_status_set_error(F_recover_not), + F_status_set_error(F_dead), F_status_set_error(F_failure), }; - for (uint8_t i = 0; i < 4; ++i) { + for (uint8_t i = 0; i < 6; ++i) { will_return(__wrap_pthread_mutex_trylock, true); will_return(__wrap_pthread_mutex_trylock, errnos[i]); -- 1.8.3.1