]> Kevux Git Server - fll/commitdiff
Bugfix: Problems exposed by f_thread unit tests.
authorKevin Day <thekevinday@gmail.com>
Fri, 1 Jul 2022 05:32:38 +0000 (00:32 -0500)
committerKevin Day <thekevinday@gmail.com>
Fri, 1 Jul 2022 05:32:38 +0000 (00:32 -0500)
Notable fixes:
- Rename f_thread_semaphore_file_create() to f_thread_semaphore_file_open().
- Rename f_thread_semaphore_file_delete() to f_thread_semaphore_file_close().
- Rename f_thread_semaphore_file_destroy() to f_thread_semaphore_file_delete().
- Have f_thread_semaphore_file_open() accept a double pointer for semaphore because sem_open() returns a pointer.
- Initializer f_thread_semaphore_t_initialize is on a union which is initialized differently from a normal digit.

level_0/f_thread/c/thread.c
level_0/f_thread/c/thread.h
level_0/f_thread/c/thread/semaphore.h

index 6d8b936b6b2ea6e08e705fe8300e87003b80e741..204f28c79a8655be75b023160d47ba408c50e3e8 100644 (file)
@@ -1549,174 +1549,178 @@ extern "C" {
   }
 #endif // _di_f_thread_mutex_lock_try_
 
-#ifndef _di_f_thread_semaphore_create_
-  f_status_t f_thread_semaphore_create(const bool shared, const unsigned int value, f_thread_semaphore_t * const semaphore) {
+#ifndef _di_f_thread_mutex_priority_ceiling_get_
+  f_status_t f_thread_mutex_priority_ceiling_get(f_thread_mutex_t * const mutex, int * const ceiling) {
     #ifndef _di_level_0_parameter_checking_
-      if (!semaphore) return F_status_set_error(F_parameter);
+      if (!mutex) return F_status_set_error(F_parameter);
+      if (!ceiling) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    if (sem_init(semaphore, shared, value) == -1) {
-      if (errno == EINVAL) return F_status_set_error(F_parameter);
-      if (errno == ENOSYS) return F_status_set_error(F_supported_not);
+    const int error = pthread_mutex_getprioceiling(mutex, ceiling);
+
+    if (error) {
+      if (error == EINVAL) return F_status_set_error(F_parameter);
+      if (error == EPERM) return F_status_set_error(F_prohibited);
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_semaphore_create_
+#endif // _di_f_thread_mutex_priority_ceiling_get_
 
-#ifndef _di_f_thread_semaphore_delete_
-  f_status_t f_thread_semaphore_delete(f_thread_semaphore_t *semaphore) {
+#ifndef _di_f_thread_mutex_priority_ceiling_set_
+  f_status_t f_thread_mutex_priority_ceiling_set(const int ceiling, f_thread_mutex_t * const mutex, int * const previous) {
     #ifndef _di_level_0_parameter_checking_
-      if (!semaphore) return F_status_set_error(F_parameter);
+      if (!mutex) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    return private_f_thread_semaphore_delete(semaphore);
+    const int error = pthread_mutex_setprioceiling(mutex, ceiling, previous);
+
+    if (error) {
+      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);
+      if (error == EPERM) return F_status_set_error(F_prohibited);
+
+      return F_status_set_error(F_failure);
+    }
+
+    return F_none;
   }
-#endif // _di_f_thread_semaphore_delete_
+#endif // _di_f_thread_mutex_priority_ceiling_set_
 
-#ifndef _di_f_thread_semaphore_file_create_
-  f_status_t f_thread_semaphore_file_create(const f_string_static_t name, const int flag, mode_t mode, unsigned int value, f_thread_semaphore_t *semaphore) {
+#ifndef _di_f_thread_mutex_unlock_
+  f_status_t f_thread_mutex_unlock(f_thread_mutex_t * const mutex) {
     #ifndef _di_level_0_parameter_checking_
-      if (!semaphore) return F_status_set_error(F_parameter);
+      if (!mutex) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    if (flag & O_CREAT) {
-      semaphore = sem_open(name.string, flag, mode, value);
-    }
-    else {
-      semaphore = sem_open(name.string, flag);
-    }
+    const int error = pthread_mutex_unlock(mutex);
 
-    if (semaphore == SEM_FAILED) {
-      if (errno == EACCES) return F_status_set_error(F_access_denied);
-      if (errno == EEXIST) return F_status_set_error(F_file_found);
-      if (errno == EINVAL) return F_status_set_error(F_parameter);
-      if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max);
-      if (errno == ENAMETOOLONG) return F_status_set_error(F_name_not);
-      if (errno == ENFILE) return F_status_set_error(F_file_open_max);
-      if (errno == ENOENT) return F_status_set_error(F_file_found_not);
-      if (errno == ENOMEM) return F_status_set_error(F_memory_not);
+    if (error) {
+      if (error == EAGAIN) return F_status_set_error(F_resource_not);
+      if (error == EBUSY) return F_status_set_error(F_busy);
+      if (error == EINVAL) return F_status_set_error(F_parameter);
+      if (error == EPERM) return F_status_set_error(F_prohibited);
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_semaphore_file_create_
+#endif // _di_f_thread_mutex_unlock_
 
-#ifndef _di_f_thread_semaphore_file_delete_
-  f_status_t f_thread_semaphore_file_delete(f_thread_semaphore_t *semaphore) {
+#ifndef _di_f_thread_once_
+  f_status_t f_thread_once(void (*routine) (void), f_thread_once_t * const once) {
     #ifndef _di_level_0_parameter_checking_
-      if (!semaphore) return F_status_set_error(F_parameter);
+      if (!routine) return F_status_set_error(F_parameter);
+      if (!once) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    if (sem_close(semaphore) == -1) {
-      if (errno == EINVAL) return F_status_set_error(F_parameter);
+    const int error = pthread_once(once, routine);
+
+    if (error) {
+      if (error == EINVAL) return F_status_set_error(F_parameter);
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_semaphore_file_delete_
+#endif // _di_f_thread_once_
 
-#ifndef _di_f_thread_semaphore_file_destroy_
-  f_status_t f_thread_semaphore_file_destroy(const f_string_static_t name) {
+#ifndef _di_f_thread_scheduler_parameter_get_
+  f_status_t f_thread_scheduler_parameter_get(const f_thread_id_t id, int * const policy, struct sched_param * const parameter) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!policy) return F_status_set_error(F_parameter);
+      if (!parameter) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
 
-    if (sem_unlink(name.string) == -1) {
-      if (errno == EACCES) return F_status_set_error(F_access_denied);
-      if (errno == EINVAL) return F_status_set_error(F_parameter);
-      if (errno == ENAMETOOLONG) return F_status_set_error(F_name_not);
-      if (errno == ENOENT) return F_file_found_not;
+    const int error = pthread_getschedparam(id, policy, parameter);
+
+    if (error) {
+      if (error == ENOTSUP) return F_status_set_error(F_supported_not);
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_semaphore_file_destroy_
+#endif // _di_f_thread_scheduler_parameter_get_
 
-#ifndef _di_f_thread_semaphore_lock_
-  f_status_t f_thread_semaphore_lock(f_thread_semaphore_t * const semaphore) {
+#ifndef _di_f_thread_scheduler_parameter_set_
+  f_status_t f_thread_scheduler_parameter_set(const f_thread_id_t id, const int policy, const struct sched_param * const parameter) {
     #ifndef _di_level_0_parameter_checking_
-      if (!semaphore) return F_status_set_error(F_parameter);
+      if (!parameter) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    if (sem_wait(semaphore) == -1) {
-      if (errno == EINTR) return F_status_set_error(F_interrupt);
-      if (errno == EINVAL) return F_status_set_error(F_parameter);
+    const int error = pthread_setschedparam(id, policy, parameter);
+
+    if (error) {
+      if (error == EINVAL) return F_status_set_error(F_parameter);
+      if (error == EPERM) return F_status_set_error(F_prohibited);
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_semaphore_lock_
+#endif // _di_f_thread_scheduler_parameter_set_
 
-#ifndef _di_f_thread_semaphore_lock_timed_
-  f_status_t f_thread_semaphore_lock_timed(const struct timespec * const timeout, f_thread_semaphore_t * const semaphore) {
-    #ifndef _di_level_0_parameter_checking_
-      if (!timeout) return F_status_set_error(F_parameter);
-      if (!semaphore) return F_status_set_error(F_parameter);
-    #endif // _di_level_0_parameter_checking_
+#ifndef _di_f_thread_scheduler_priority_set_
+  f_status_t f_thread_scheduler_priority_set(const f_thread_id_t id, const int priority) {
 
-    if (sem_timedwait(semaphore, timeout) == -1) {
-      if (errno == EINTR) return F_status_set_error(F_interrupt);
-      if (errno == EINVAL) return F_status_set_error(F_parameter);
-      if (errno == ETIMEDOUT) return F_time;
+    const int error = pthread_setschedprio(id, priority);
+
+    if (error) {
+      if (error == EINVAL) return F_status_set_error(F_parameter);
+      if (error == EPERM) return F_status_set_error(F_prohibited);
+      if (error == ESRCH) return F_status_set_error(F_found_not);
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_semaphore_lock_timed_
+#endif // _di_f_thread_scheduler_priority_set_
 
-#ifndef _di_f_thread_semaphore_lock_try_
-  f_status_t f_thread_semaphore_lock_try(f_thread_semaphore_t * const semaphore) {
+#ifndef _di_f_thread_semaphore_create_
+  f_status_t f_thread_semaphore_create(const bool shared, const unsigned int value, f_thread_semaphore_t * const semaphore) {
     #ifndef _di_level_0_parameter_checking_
       if (!semaphore) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    if (sem_trywait(semaphore) == -1) {
-      if (errno == EAGAIN) return F_status_set_error(F_resource_not);
-      if (errno == EINTR) return F_status_set_error(F_interrupt);
+    if (sem_init(semaphore, shared, value) == -1) {
       if (errno == EINVAL) return F_status_set_error(F_parameter);
+      if (errno == ENOSYS) return F_status_set_error(F_supported_not);
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_semaphore_lock_try_
+#endif // _di_f_thread_semaphore_create_
 
-#ifndef _di_f_thread_semaphore_unlock_
-  f_status_t f_thread_semaphore_unlock(f_thread_semaphore_t * const semaphore) {
+#ifndef _di_f_thread_semaphore_delete_
+  f_status_t f_thread_semaphore_delete(f_thread_semaphore_t *semaphore) {
     #ifndef _di_level_0_parameter_checking_
       if (!semaphore) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    if (sem_post(semaphore) == -1) {
-      if (errno == EOVERFLOW) return F_status_set_error(F_number_overflow);
-      if (errno == EINVAL) return F_status_set_error(F_parameter);
-
-      return F_status_set_error(F_failure);
-    }
-
-    return F_none;
+    return private_f_thread_semaphore_delete(semaphore);
   }
-#endif // _di_f_thread_semaphore_unlock_
+#endif // _di_f_thread_semaphore_delete_
 
-#ifndef _di_f_thread_semaphore_value_get_
-  f_status_t f_thread_semaphore_value_get(f_thread_semaphore_t * const semaphore, int * const value) {
+#ifndef _di_f_thread_semaphore_file_close_
+  f_status_t f_thread_semaphore_file_close(f_thread_semaphore_t *semaphore) {
     #ifndef _di_level_0_parameter_checking_
       if (!semaphore) return F_status_set_error(F_parameter);
-      if (!value) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    if (sem_getvalue(semaphore, value) == -1) {
+    if (sem_close(semaphore) == -1) {
       if (errno == EINVAL) return F_status_set_error(F_parameter);
 
       return F_status_set_error(F_failure);
@@ -1724,146 +1728,141 @@ extern "C" {
 
     return F_none;
   }
-#endif // _di_f_thread_semaphore_value_get_
-
-#ifndef _di_f_thread_mutex_priority_ceiling_get_
-  f_status_t f_thread_mutex_priority_ceiling_get(f_thread_mutex_t * const mutex, int * const ceiling) {
-    #ifndef _di_level_0_parameter_checking_
-      if (!mutex) return F_status_set_error(F_parameter);
-      if (!ceiling) return F_status_set_error(F_parameter);
-    #endif // _di_level_0_parameter_checking_
+#endif // _di_f_thread_semaphore_file_close_
 
-    const int error = pthread_mutex_getprioceiling(mutex, ceiling);
+#ifndef _di_f_thread_semaphore_file_delete_
+  f_status_t f_thread_semaphore_file_delete(const f_string_static_t name) {
 
-    if (error) {
-      if (error == EINVAL) return F_status_set_error(F_parameter);
-      if (error == EPERM) return F_status_set_error(F_prohibited);
+    if (sem_unlink(name.string) == -1) {
+      if (errno == EACCES) return F_status_set_error(F_access_denied);
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
+      if (errno == ENAMETOOLONG) return F_status_set_error(F_name_not);
+      if (errno == ENOENT) return F_file_found_not;
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_mutex_priority_ceiling_get_
+#endif // _di_f_thread_semaphore_file_delete_
 
-#ifndef _di_f_thread_mutex_priority_ceiling_set_
-  f_status_t f_thread_mutex_priority_ceiling_set(const int ceiling, f_thread_mutex_t * const mutex, int * const previous) {
+#ifndef _di_f_thread_semaphore_file_open_
+  f_status_t f_thread_semaphore_file_open(const f_string_static_t name, const int flag, const mode_t mode, unsigned int value, f_thread_semaphore_t **semaphore) {
     #ifndef _di_level_0_parameter_checking_
-      if (!mutex) return F_status_set_error(F_parameter);
+      if (!semaphore) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const int error = pthread_mutex_setprioceiling(mutex, ceiling, previous);
+    if (flag & O_CREAT) {
+      *semaphore = sem_open(name.string, flag, mode, value);
+    }
+    else {
+      *semaphore = sem_open(name.string, flag);
+    }
 
-    if (error) {
-      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);
-      if (error == EPERM) return F_status_set_error(F_prohibited);
+    if (*semaphore == SEM_FAILED) {
+      if (errno == EACCES) return F_status_set_error(F_access_denied);
+      if (errno == EEXIST) return F_status_set_error(F_file_found);
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
+      if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max);
+      if (errno == ENAMETOOLONG) return F_status_set_error(F_name_not);
+      if (errno == ENFILE) return F_status_set_error(F_file_open_max);
+      if (errno == ENOENT) return F_status_set_error(F_file_found_not);
+      if (errno == ENOMEM) return F_status_set_error(F_memory_not);
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_mutex_priority_ceiling_set_
+#endif // _di_f_thread_semaphore_file_open_
 
-#ifndef _di_f_thread_mutex_unlock_
-  f_status_t f_thread_mutex_unlock(f_thread_mutex_t * const mutex) {
+#ifndef _di_f_thread_semaphore_lock_
+  f_status_t f_thread_semaphore_lock(f_thread_semaphore_t * const semaphore) {
     #ifndef _di_level_0_parameter_checking_
-      if (!mutex) return F_status_set_error(F_parameter);
+      if (!semaphore) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const int error = pthread_mutex_unlock(mutex);
-
-    if (error) {
-      if (error == EAGAIN) return F_status_set_error(F_resource_not);
-      if (error == EBUSY) return F_status_set_error(F_busy);
-      if (error == EINVAL) return F_status_set_error(F_parameter);
-      if (error == EPERM) return F_status_set_error(F_prohibited);
+    if (sem_wait(semaphore) == -1) {
+      if (errno == EINTR) return F_status_set_error(F_interrupt);
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_mutex_unlock_
+#endif // _di_f_thread_semaphore_lock_
 
-#ifndef _di_f_thread_once_
-  f_status_t f_thread_once(void (*routine) (void), f_thread_once_t * const once) {
+#ifndef _di_f_thread_semaphore_lock_timed_
+  f_status_t f_thread_semaphore_lock_timed(const struct timespec * const timeout, f_thread_semaphore_t * const semaphore) {
     #ifndef _di_level_0_parameter_checking_
-      if (!routine) return F_status_set_error(F_parameter);
-      if (!once) return F_status_set_error(F_parameter);
+      if (!timeout) return F_status_set_error(F_parameter);
+      if (!semaphore) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const int error = pthread_once(once, routine);
-
-    if (error) {
-      if (error == EINVAL) return F_status_set_error(F_parameter);
+    if (sem_timedwait(semaphore, timeout) == -1) {
+      if (errno == EINTR) return F_status_set_error(F_interrupt);
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
+      if (errno == ETIMEDOUT) return F_time;
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_once_
+#endif // _di_f_thread_semaphore_lock_timed_
 
-#ifndef _di_f_thread_scheduler_parameter_get_
-  f_status_t f_thread_scheduler_parameter_get(const f_thread_id_t id, int * const policy, struct sched_param * const parameter) {
+#ifndef _di_f_thread_semaphore_lock_try_
+  f_status_t f_thread_semaphore_lock_try(f_thread_semaphore_t * const semaphore) {
     #ifndef _di_level_0_parameter_checking_
-      if (!policy) return F_status_set_error(F_parameter);
-      if (!parameter) return F_status_set_error(F_parameter);
+      if (!semaphore) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const int error = pthread_getschedparam(id, policy, parameter);
-
-    if (error) {
-      if (error == ENOTSUP) return F_status_set_error(F_supported_not);
+    if (sem_trywait(semaphore) == -1) {
+      if (errno == EAGAIN) return F_status_set_error(F_resource_not);
+      if (errno == EINTR) return F_status_set_error(F_interrupt);
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_scheduler_parameter_get_
+#endif // _di_f_thread_semaphore_lock_try_
 
-#ifndef _di_f_thread_scheduler_parameter_set_
-  f_status_t f_thread_scheduler_parameter_set(const f_thread_id_t id, const int policy, const struct sched_param * const parameter) {
+#ifndef _di_f_thread_semaphore_unlock_
+  f_status_t f_thread_semaphore_unlock(f_thread_semaphore_t * const semaphore) {
     #ifndef _di_level_0_parameter_checking_
-      if (!policy) return F_status_set_error(F_parameter);
-      if (!parameter) return F_status_set_error(F_parameter);
+      if (!semaphore) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    const int error = pthread_setschedparam(id, policy, parameter);
-
-    if (error) {
-      if (error == EINVAL) return F_status_set_error(F_parameter);
-      if (error == EPERM) return F_status_set_error(F_prohibited);
+    if (sem_post(semaphore) == -1) {
+      if (errno == EOVERFLOW) return F_status_set_error(F_number_overflow);
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_scheduler_parameter_set_
-
-#ifndef _di_f_thread_scheduler_priority_set_
-  f_status_t f_thread_scheduler_priority_set(const f_thread_id_t id, const int priority) {
+#endif // _di_f_thread_semaphore_unlock_
 
-    const int error = pthread_setschedprio(id, priority);
+#ifndef _di_f_thread_semaphore_value_get_
+  f_status_t f_thread_semaphore_value_get(f_thread_semaphore_t * const semaphore, int * const value) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!semaphore) return F_status_set_error(F_parameter);
+      if (!value) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
 
-    if (error) {
-      if (error == EINVAL) return F_status_set_error(F_parameter);
-      if (error == EPERM) return F_status_set_error(F_prohibited);
-      if (error == ESRCH) return F_status_set_error(F_found_not);
+    if (sem_getvalue(semaphore, value) == -1) {
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
 
       return F_status_set_error(F_failure);
     }
 
     return F_none;
   }
-#endif // _di_f_thread_scheduler_priority_set_
+#endif // _di_f_thread_semaphore_value_get_
 
 #ifndef _di_f_thread_signal_mask_
   f_status_t f_thread_signal_mask(const int how, const sigset_t *next, sigset_t * const current) {
@@ -1884,6 +1883,29 @@ extern "C" {
   }
 #endif // _di_f_thread_signal_mask_
 
+#if defined(_pthread_sigqueue_unsupported_) && !defined(_di_f_thread_signal_queue_)
+  f_status_t f_thread_signal_queue(const f_thread_id_t id, const int signal, const union sigval value) {
+
+    return F_status_set_error(F_implemented_not);
+  }
+#elif !defined(_di_f_thread_signal_queue_)
+  f_status_t f_thread_signal_queue(const f_thread_id_t id, const int signal, const union sigval value) {
+
+    const int error = pthread_sigqueue(id, signal, value);
+
+    if (error) {
+      if (error == EAGAIN) return F_status_set_error(F_resource_not);
+      if (error == ENOSYS) return F_status_set_error(F_supported_not);
+      if (error == EINVAL) return F_status_set_error(F_parameter);
+      if (error == ESRCH) return F_status_set_error(F_found_not);
+
+      return F_status_set_error(F_failure);
+    }
+
+    return F_none;
+  }
+#endif // defined(_pthread_sigqueue_unsupported_) && !defined(_di_f_thread_signal_queue_)
+
 #ifndef _di_f_thread_signal_write_
   f_status_t f_thread_signal_write(const f_thread_id_t id, const int signal) {
 
@@ -1909,29 +1931,6 @@ extern "C" {
   }
 #endif // _di_f_thread_signal_write_
 
-#if defined(_pthread_sigqueue_unsupported_) && !defined(_di_f_thread_signal_queue_)
-  f_status_t f_thread_signal_queue(const f_thread_id_t id, const int signal, const union sigval value) {
-
-    return F_status_set_error(F_implemented_not);
-  }
-#elif !defined(_di_f_thread_signal_queue_)
-  f_status_t f_thread_signal_queue(const f_thread_id_t id, const int signal, const union sigval value) {
-
-    const int error = pthread_sigqueue(id, signal, value);
-
-    if (error) {
-      if (error == EAGAIN) return F_status_set_error(F_resource_not);
-      if (error == ENOSYS) return F_status_set_error(F_supported_not);
-      if (error == EINVAL) return F_status_set_error(F_parameter);
-      if (error == ESRCH) return F_status_set_error(F_found_not);
-
-      return F_status_set_error(F_failure);
-    }
-
-    return F_none;
-  }
-#endif // defined(_pthread_sigqueue_unsupported_) && !defined(_di_f_thread_signal_queue_)
-
 #ifndef _di_f_thread_spin_create_
   f_status_t f_thread_spin_create(const int shared, f_thread_spin_t * const spin) {
     #ifndef _di_level_0_parameter_checking_
index e1f4d8f2fe2edff8d42e95da628271f7952d9fda..d5dda080f922baad20de6feb222429c897b8ecf9 100644 (file)
@@ -1120,7 +1120,7 @@ extern "C" {
  * Wait until condition is triggered, blocking until the timeout expires.
  *
  * This is a semi-blocking operation.
- * This will block until timeout and then no longer block.
+ * This blocks until timeout and then no longer block.
  *
  * @param wait
  *   The amount of time to wait for.
@@ -1281,7 +1281,7 @@ extern "C" {
  * Try to join the given thread to the current thread, blocking until the timeout expires.
  *
  * This is a semi-blocking operation.
- * This will block until timeout and then no longer block.
+ * This blocks until timeout and then no longer block.
  *
  * @param id
  *   The ID of the thread to wait for.
@@ -1944,155 +1944,155 @@ extern "C" {
 #endif // _di_f_thread_mutex_delete_
 
 /**
- * Lock the mutex.
- *
- * This is a blocking function.
+ * Get the mutex priority ceiling.
  *
  * @param mutex
  *   The thread mutex.
+ * @param ceiling
+ *   The priority ceiling.
  *
  * @return
  *   F_none on success.
  *
- *   F_deadlock (with error bit) if operation would cause a deadlock.
  *   F_parameter (with error bit) if a parameter is invalid.
- *   F_resource_not (with error bit) if max mutex locks is reached.
+ *   F_prohibited (with error bit) if not allowed to perform the operation.
  *
  *   F_failure (with error bit) on any other error.
  *
- * @see pthread_mutex_lock()
+ * @see pthread_mutex_getprioceiling()
  */
-#ifndef _di_f_thread_mutex_lock_
-  extern f_status_t f_thread_mutex_lock(f_thread_mutex_t * const mutex);
-#endif // _di_f_thread_mutex_lock_
+#ifndef _di_f_thread_mutex_priority_ceiling_get_
+  extern f_status_t f_thread_mutex_priority_ceiling_get(f_thread_mutex_t * const mutex, int * const ceiling);
+#endif // _di_f_thread_mutex_priority_ceiling_get_
 
 /**
- * Lock the mutex, waiting for a set period of time to get the lock if already locked.
- *
- * If the mutex is already locked and the timeout expires, then the lock attempt fails.
- *
- * This is a blocking function (until timeout expires).
+ * Set the mutex priority ceiling.
  *
- * @param timeout
- *   The timeout.
+ * @param ceiling
+ *   The priority ceiling.
  * @param mutex
  *   The thread mutex.
+ * @param previous
+ *   (optional) The previous priority ceiling.
+ *   Set to NULL to not use.
  *
  * @return
  *   F_none on success.
- *   F_time if the timeout was reached before obtaining the lock.
  *
  *   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_recover_not (with error bit) if the state protected by the mutex is not recoverable (for a "robust" mutex).
  *   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.
  *
- * @see pthread_mutex_timedlock()
+ * @see pthread_mutex_setprioceiling()
  */
-#ifndef _di_f_thread_mutex_lock_timed_
-  extern f_status_t f_thread_mutex_lock_timed(const struct timespec * const timeout, f_thread_mutex_t * const mutex);
-#endif // _di_f_thread_mutex_lock_timed_
+#ifndef _di_f_thread_mutex_priority_ceiling_set_
+  extern f_status_t f_thread_mutex_priority_ceiling_set(const int ceiling, f_thread_mutex_t * const mutex, int * const previous);
+#endif // _di_f_thread_mutex_priority_ceiling_set_
 
 /**
- * Try to lock the mutex.
- *
- * If mutex is already locked, return immediately.
- *
- * This is a non-blocking function.
+ * Unlock the mutex.
  *
  * @param mutex
  *   The thread mutex.
  *
  * @return
  *   F_none on success.
- *   F_busy on success, but the mutex is already locked.
  *
  *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_prohibited (with error bit) if not allowed to perform the operation (possibly because mutex is not owned by current thread).
  *   F_resource_not (with error bit) if max mutex locks is reached.
  *
  *   F_failure (with error bit) on any other error.
  *
- * @see pthread_mutex_trylock()
+ * @see pthread_mutex_unlock()
  */
-#ifndef _di_f_thread_mutex_lock_try_
-  extern f_status_t f_thread_mutex_lock_try(f_thread_mutex_t * const mutex);
-#endif // _di_f_thread_mutex_lock_try_
+#ifndef _di_f_thread_mutex_unlock_
+  extern f_status_t f_thread_mutex_unlock(f_thread_mutex_t * const mutex);
+#endif // _di_f_thread_mutex_unlock_
 
 /**
- * Get the mutex priority ceiling.
+ * Lock the mutex.
+ *
+ * This is a blocking function.
  *
  * @param mutex
  *   The thread mutex.
- * @param ceiling
- *   The priority ceiling.
  *
  * @return
  *   F_none on success.
  *
+ *   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_resource_not (with error bit) if max mutex locks is reached.
  *
  *   F_failure (with error bit) on any other error.
  *
- * @see pthread_mutex_getprioceiling()
+ * @see pthread_mutex_lock()
  */
-#ifndef _di_f_thread_mutex_priority_ceiling_get_
-  extern f_status_t f_thread_mutex_priority_ceiling_get(f_thread_mutex_t * const mutex, int * const ceiling);
-#endif // _di_f_thread_mutex_priority_ceiling_get_
+#ifndef _di_f_thread_mutex_lock_
+  extern f_status_t f_thread_mutex_lock(f_thread_mutex_t * const mutex);
+#endif // _di_f_thread_mutex_lock_
 
 /**
- * Set the mutex priority ceiling.
+ * Lock the mutex, waiting for a set period of time to get the lock if already locked.
  *
- * @param ceiling
- *   The priority ceiling.
+ * If the mutex is already locked and the timeout expires, then the lock attempt fails.
+ *
+ * This is a blocking function (until timeout expires).
+ *
+ * @param timeout
+ *   The timeout.
  * @param mutex
  *   The thread mutex.
- * @param previous
- *   (optional) The previous priority ceiling.
- *   Set to NULL to not use.
  *
  * @return
  *   F_none on success.
+ *   F_time if the timeout was reached before obtaining the lock.
  *
  *   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 (for a "robust" mutex).
+ *   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.
  *
- * @see pthread_mutex_setprioceiling()
+ * @see pthread_mutex_timedlock()
  */
-#ifndef _di_f_thread_mutex_priority_ceiling_set_
-  extern f_status_t f_thread_mutex_priority_ceiling_set(const int ceiling, f_thread_mutex_t * const mutex, int * const previous);
-#endif // _di_f_thread_mutex_priority_ceiling_set_
+#ifndef _di_f_thread_mutex_lock_timed_
+  extern f_status_t f_thread_mutex_lock_timed(const struct timespec * const timeout, f_thread_mutex_t * const mutex);
+#endif // _di_f_thread_mutex_lock_timed_
 
 /**
- * Unlock the mutex.
+ * Try to lock the mutex.
+ *
+ * If mutex is already locked, return immediately.
+ *
+ * This is a non-blocking function.
  *
  * @param mutex
  *   The thread mutex.
  *
  * @return
  *   F_none on success.
+ *   F_busy on success, but the mutex is already locked.
  *
  *   F_parameter (with error bit) if a parameter is invalid.
- *   F_prohibited (with error bit) if not allowed to perform the operation (possibly because mutex is not owned by current thread).
  *   F_resource_not (with error bit) if max mutex locks is reached.
  *
  *   F_failure (with error bit) on any other error.
  *
- * @see pthread_mutex_unlock()
+ * @see pthread_mutex_trylock()
  */
-#ifndef _di_f_thread_mutex_unlock_
-  extern f_status_t f_thread_mutex_unlock(f_thread_mutex_t * const mutex);
-#endif // _di_f_thread_mutex_unlock_
+#ifndef _di_f_thread_mutex_lock_try_
+  extern f_status_t f_thread_mutex_lock_try(f_thread_mutex_t * const mutex);
+#endif // _di_f_thread_mutex_lock_try_
 
 /**
  * Call the given routine only one time and never again.
@@ -2236,96 +2236,91 @@ extern "C" {
 #endif // _di_f_thread_semaphore_delete_
 
 /**
- * Create a thread (named) semaphore.
+ * Close a thread (named) semaphore file.
+ *
+ * A named semaphore should be deleted with f_thread_semephore_file_destroy().
  *
- * @param name
- *   The semaphore file name to create.
- * @param flag
- *   The file create/open flags.
- * @param mode
- *   (optional) The file permissions to assign the semaphore.
- *   Ignored if O_CREAT is not used in flag.
- *   Ignored if the named semaphore already exists.
- * @param value
- *   (optional) The value to initially assign the semaphore on creation.
- *   Ignored if O_CREAT is not used in flag.
- *   Ignored if the named semaphore already exists.
  * @param semaphore
- *   The thread semaphore.
+ *   The semaphore to delete.
  *
  * @return
  *   F_none on success.
  *
- *   F_access_denied (with error bit) on access denied.
- *   F_file_descriptor_max (with error bit) if max file descrriptors was reached.
- *   F_file_found (with error bit) if the file was found and both the O_CREAT and O_EXCL flags are set.
- *   F_file_open_max (with error bit) too many open files.
- *   F_file_found_not (with error bit) if the file was not found and the O_CREAT is not set.
- *   F_name_not (with error bit) if file name is too long.
  *   F_parameter (with error bit) if a parameter is invalid.
- *   F_supported_not (with error bit) if the system does not support the process shared semaphore (shared == true).
- *   F_memory_not (with error bit) if out of memory.
  *
  *   F_failure (with error bit) on any other error.
  *
- * @see sem_open()
+ * A named semaphore should be deleted with this function or with f_thread_semephore_file_destroy().
+ *
+ * @see sem_close()
  */
-#ifndef _di_f_thread_semaphore_file_create_
-  extern f_status_t f_thread_semaphore_file_create(const f_string_static_t name, const int flag, mode_t mode, unsigned int value, f_thread_semaphore_t *semaphore);
-#endif // _di_f_thread_semaphore_file_create_
+#ifndef _di_f_thread_semaphore_file_close_
+  extern f_status_t f_thread_semaphore_file_close(f_thread_semaphore_t *semaphore);
+#endif // _di_f_thread_semaphore_file_close_
 
 /**
  * Delete a thread (named) semaphore.
  *
- * A named semaphore should be deleted with this function or with f_thread_semephore_file_destroy().
+ * This deletes the semaphore file and all processes holding this semaphore will be forcibly closed.
  *
- * @param semaphore
- *   The semaphore to delete.
+ * @param name
+ *   The semaphore name to delete.
  *
  * @return
  *   F_none on success.
+ *   F_file_found_not the named file was not found.
  *
+ *   F_access_denied (with error bit) on access denied.
+ *   F_name_not (with error bit) if file name is too long.
  *   F_parameter (with error bit) if a parameter is invalid.
  *
  *   F_failure (with error bit) on any other error.
  *
- * A named semaphore should be deleted with this function or with f_thread_semephore_file_destroy().
- *
- * @see sem_close()
- *
- * @see f_thread_semaphore_file_destroy()
+ * @see sem_unlink()
  */
 #ifndef _di_f_thread_semaphore_file_delete_
-  extern f_status_t f_thread_semaphore_file_delete(f_thread_semaphore_t *semaphore);
+  extern f_status_t f_thread_semaphore_file_delete(const f_string_static_t name);
 #endif // _di_f_thread_semaphore_file_delete_
 
 /**
- * Destroy a thread (named) semaphore.
- *
- * This will immediately delete the semaphore file and all processes holding this semaphore will be forced to close.
- *
- * A named semaphore should be deleted with this function or with f_thread_semephore_file_delete().
+ * Open or create a thread (named) semaphore file.
  *
  * @param name
- *   The semaphore name to delete.
+ *   The semaphore file name to create.
+ * @param flag
+ *   The file create/open flags.
+ *   Pass the O_CREATE flag to create the semaphore file.
+ * @param mode
+ *   (optional) The file permissions to assign the semaphore.
+ *   Ignored if O_CREAT is not used in flag.
+ *   Ignored if the named semaphore already exists.
+ * @param value
+ *   (optional) The value to initially assign the semaphore on creation.
+ *   Ignored if O_CREAT is not used in flag.
+ *   Ignored if the named semaphore already exists.
+ * @param semaphore
+ *   The thread semaphore.
  *
  * @return
  *   F_none on success.
- *   F_file_found_not the named file was not found.
  *
  *   F_access_denied (with error bit) on access denied.
+ *   F_file_descriptor_max (with error bit) if max file descrriptors was reached.
+ *   F_file_found (with error bit) if the file was found and both the O_CREAT and O_EXCL flags are set.
+ *   F_file_open_max (with error bit) too many open files.
+ *   F_file_found_not (with error bit) if the file was not found and the O_CREAT is not set.
  *   F_name_not (with error bit) if file name is too long.
  *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_supported_not (with error bit) if the system does not support the process shared semaphore (shared == true).
+ *   F_memory_not (with error bit) if out of memory.
  *
  *   F_failure (with error bit) on any other error.
  *
- * @see sem_unlink()
- *
- * @see f_thread_semaphore_file_delete()
+ * @see sem_open()
  */
-#ifndef _di_f_thread_semaphore_file_destroy_
-  extern f_status_t f_thread_semaphore_file_destroy(const f_string_static_t name);
-#endif // _di_f_thread_semaphore_file_destroy_
+#ifndef _di_f_thread_semaphore_file_open_
+  extern f_status_t f_thread_semaphore_file_open(const f_string_static_t name, const int flag, const mode_t mode, unsigned int value, f_thread_semaphore_t **semaphore);
+#endif // _di_f_thread_semaphore_file_open_
 
 /**
  * Lock the semaphore.
@@ -2471,29 +2466,6 @@ extern "C" {
 #endif // _di_f_thread_signal_mask_
 
 /**
- * Send a signal to the given thread.
- *
- * @param id
- *   The ID of the thread to signal.
- * @param signal
- *   The signal to send to the thread.
- *   If 0 is used instead of a valid signal, then instead check to see if the thread exists.
- *
- * @return
- *   F_none on success and signal is not 0.
- *   F_found on success, signal is 0, and the thread by the given ID does exist.
- *
- *   F_found_not on success, signal is 0, and the thread by the given ID does not exist.
- *   F_found_not (with error bit) if no thread by the given ID was found (and signal is not 0).
- *   F_parameter (with error bit) if a parameter is invalid.
- *
- * @see pthread_kill()
- */
-#ifndef _di_f_thread_signal_write_
-  extern f_status_t f_thread_signal_write(const f_thread_id_t id, const int signal);
-#endif // _di_f_thread_signal_write_
-
-/**
  * Send the signal and value to the given thread.
  *
  * @param id
@@ -2520,6 +2492,29 @@ extern "C" {
 #endif // _di_f_thread_signal_queue_
 
 /**
+ * Send a signal to the given thread.
+ *
+ * @param id
+ *   The ID of the thread to signal.
+ * @param signal
+ *   The signal to send to the thread.
+ *   If 0 is used instead of a valid signal, then instead check to see if the thread exists.
+ *
+ * @return
+ *   F_none on success and signal is not 0.
+ *   F_found on success, signal is 0, and the thread by the given ID does exist.
+ *
+ *   F_found_not on success, signal is 0, and the thread by the given ID does not exist.
+ *   F_found_not (with error bit) if no thread by the given ID was found (and signal is not 0).
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see pthread_kill()
+ */
+#ifndef _di_f_thread_signal_write_
+  extern f_status_t f_thread_signal_write(const f_thread_id_t id, const int signal);
+#endif // _di_f_thread_signal_write_
+
+/**
  * Create a thread spin lock.
  *
  * @param shared
index 61e4b4bcf46d7e7e10013c662438bbffde70781e..c1b79a1378ecfce23a55009545087a76d914d722 100644 (file)
@@ -26,7 +26,7 @@ extern "C" {
 #ifndef _di_f_thread_semaphore_t_
   typedef sem_t f_thread_semaphore_t;
 
-  #define f_thread_semaphore_t_initialize 0
+  #define f_thread_semaphore_t_initialize { (long) 0 }
 
   #define macro_f_thread_semaphore_t_initialize(semaphore) semaphore