Rainer Weikusat
2020-06-03 22:08:11 UTC
Problem to be solved: A certain network accelarator card needs a user
mode driver running on Linux. For configuration, a script in a certain,
vendor-specific programming language needs to be run prior to other
applications trying to use the hardware.
The script can be executed once the driver process is ready to interface
with clients. This can be determined by calling the init function in a
loop until it returns a success status. This, starting of the user mode
driver process and possibly, of another loading the kernel part of this
driver, happens in a separate thread while the initial thread of the
management process accepts connections from prospective users of the
hardware on a UNIX stream socket.
There's a propietary interface library involved here which has to do
some cleanup tasks on process exit, Presumably, this happens via atexit
handlers. But this doesn't work anymore if the init function was called
from a different thread than the one causing the process to terminate:
Some SysV IPC shared memory segments otherwise hang around and have to
be removed manually before the user mode driver (process) can again
start successfully.
Something asynchronous could have done for the init here, but due to
time pressure, everything was to be kept as simple as possible. A forked
process couldn't have been used for the init because the driver process
needs to end up being a child of the management process.
Solution: Call the init routine from a process forked off by the init
thread and communicate the outcome back to the manager process via exit
status.
Of course, fork is alternatively "a totally useless adjunct to exec" or
"something nobody would ever need to use in a multithreaded process" ...
mode driver running on Linux. For configuration, a script in a certain,
vendor-specific programming language needs to be run prior to other
applications trying to use the hardware.
The script can be executed once the driver process is ready to interface
with clients. This can be determined by calling the init function in a
loop until it returns a success status. This, starting of the user mode
driver process and possibly, of another loading the kernel part of this
driver, happens in a separate thread while the initial thread of the
management process accepts connections from prospective users of the
hardware on a UNIX stream socket.
There's a propietary interface library involved here which has to do
some cleanup tasks on process exit, Presumably, this happens via atexit
handlers. But this doesn't work anymore if the init function was called
from a different thread than the one causing the process to terminate:
Some SysV IPC shared memory segments otherwise hang around and have to
be removed manually before the user mode driver (process) can again
start successfully.
Something asynchronous could have done for the init here, but due to
time pressure, everything was to be kept as simple as possible. A forked
process couldn't have been used for the init because the driver process
needs to end up being a child of the management process.
Solution: Call the init routine from a process forked off by the init
thread and communicate the outcome back to the manager process via exit
status.
Of course, fork is alternatively "a totally useless adjunct to exec" or
"something nobody would ever need to use in a multithreaded process" ...