]> Kevux Git Server - controller/commit
Bugfix: Program deadlocks on entry error.
authorKevin Day <Kevin@kevux.org>
Thu, 13 Nov 2025 03:05:26 +0000 (21:05 -0600)
committerKevin Day <Kevin@kevux.org>
Thu, 13 Nov 2025 03:05:26 +0000 (21:05 -0600)
commit1317dd79d7af7ca388f5696a2d08b175fb532862
tree1d9b86faefefdd3a1bc5bcc66b437f71e962db65
parente05eac272572e86b391d3f43be7cd29bc56a7494
Bugfix: Program deadlocks on entry error.

The signal design by the standard libc signals and the stand pthread signals is rather lacking.

Sending a signal to the thread might cause it to deadlock because the signal handler is trying to exit but has locks and the cancellation function has called `f_thread_join()` on that signal handler thread.

First, switch to `f_thread_detach()` rather than join the thread.
This allows the signal thread to close gracefully without blocking the cancellation function.

A detached signal thread needs to know that once it is detached, it should not handle signals and should exit.
This is not straight-forward and pthreads fails to provide an easy way to do this.
(Where an easy way would be calling a function that gives the thread state of the current thread.)

The main signal ID could be checked for by getting the current thread ID and comparing the main signal ID to this current thread ID.
This works, but introduces bad threaded application practices.
The signal handler could read the main signal ID at any time before a potential change to it.
That is fine, it just missed the check in that case.
Still, this should be avoided as there could even be undefined behavior in this.

This takes an alternate approach of creating the `f_thread_attribute_t` and passing it to the thread.
The thread can then use this value to get the current detached state.
This should be much safer.

Due to the nature of threads detaching, this design requires that the `f_thread_attribute_t` to be de-allocated by the callback itself.

A new structure, called `controller_thread_arguments_t`, for passing this information to the thread is now provided.

The `f_thread_signal_write()` call handles certain libc functions but in other cases `f_thread_cancel()` should be called.
Add calls to `f_thread_cancel()` for any threads that have `f_thread_signal_write()` passed to it.
This helps ensure that both cancellation cases can be triggered.

These changes cause the interrupt behavior to be slightly different than previous operations.
I still plan on reviewing and determining how I want to make signal handling operate across the board for controller and init programs and for both entries and exits.
This behavior is therefore considered acceptable and provides a good chance to test out alternative approaches in practice rather than just in theory.
12 files changed:
data/build/stand_alone/config.h
sources/c/program/controller/init/signal.c
sources/c/program/controller/init/signal.h
sources/c/program/controller/main/common/type.h
sources/c/program/controller/main/common/type/instance.c
sources/c/program/controller/main/common/type/thread.h
sources/c/program/controller/main/print/debug/perform/pid.c
sources/c/program/controller/main/process.c
sources/c/program/controller/main/thread/entry.c
sources/c/program/controller/main/thread/instance.c
sources/c/program/controller/main/thread/signal.c
sources/c/program/controller/main/thread/signal.h