This attempts to solve the problem where, if the rotator is actively
rotating and the program is killed, the LabJack will not be reset and
the rotator will keep running. We install various signal handlers to
try to catch common cases (ctrl+c, terminal getting closed out from
under us). There are still ways to end the process that leave the
LabJack running (such as if it crashes, though there are currently no
known crashes), but I don't think it's possible to completely avoid
that.
The posix signal handling story is a bit ugly. Trying to do pretty much
anything in the asynchronous signal handlers will cause undefined
behavior. Acquiring a mutex and joining a thread are right at the top
of the very long list of things that you cannot do safely in an async
signal handler. One potential solution to this problem is to replace
locks with atomics, which isn't appropriate for our use case (we have
to make sure the controller thread actually has shut down the LabJack
before exiting the process). The other well-known solution is to
manually create a thread that listens for signals synchronously, and
this is the approach taken here.
After having done this, I had the thought that because we are linking
libc anyway, an `atexit` handler might work, but I don't actually know
if it would, and I don't think it's worthwhile to do the work at this
point.