Give up and exit after 30 seconds of no sample data, rather than just warning and continuing.
background & discussion: https://discussions.flightaware.com/t/cpu-hikes-crash-dump1090-fa/74759
The scenario this addresses is:
* Hardware wedges, USB bulk endpoint stops providing data
* librtlsdr remains in rtlsdr_read_async() waiting for either USB data which never arrives,
or a cancellation via _a different thread_ calling rtlsdr_cancel_async().
* main thread notices the lack of SDR data and complains
* something external e.g. piaware tries a restart and sends SIGTERM
* the signal handler sets Modes.exit = 1; the main thread starts waiting for receive thread termination
* because we're never getting callbacks from rtlsdr_read_async(), we never call rtlsdr_cancel_async
* dump1090 hangs waiting on receive thread termination
To fix this, add a sdrStop() handler function where the general contract is "make the receive thread terminate".
In the rtlsdr case, this calls rtlsdr_cancel_async directly, which will make rtlsdr_read_async() return even
if the hardware is stuck.
The main thread then calls sdrStop() before waiting for receive thread termination.
Also, as discussed in the thread above, there's not really much point in continuing to run if the SDR
has wedged, so bail out after 30 seconds of no sample data.
Also, if pthread_timedjoin_np is available, use it in preference to pthread_join so that we do not wait
indefinitely for the receive thread on shutdown. If the join times out, give up and abort() as we can't
safely continue a clean shutdown while the receive thread is running.
This reinstates the fastpath in the 2.4MHz demodulator that
aborts message demodulation early if the DF bits don't match a message
type that we know how to decode, or stops early if the DF bits can
only correspond to a short 56-bit message.
Do this in a more general form where we test against a set of valid
DF values, rather than a switch/case. Then populate the sets based on
the current error-correction settings (e.g. if we are allowed to repair
DF damage with 1 bit error correction, then a DF17 message could appear
with any of DF=17, DF=16, DF=19, DF=21, DF=25, or DF=1 and still be
correctable to a valid DF17 message)
In the default case this produces a small CPU improvement as short
messages might be able to stop earlier and a few DF values can be ignored
early. With --no-fix-df it produces a larger improvement as relatively few
DF values are valid in that mode.
To further reduce CPU, the default behaviour has changed to _not_
decode DF24 messages (Comm-D ELM messages). These are rarely seen in
the wild and dump1090 can't do anything useful with them. Disabling
them allows us to further reduce the set of valid DF values as they
effectively use all DF values from 24..31, 25% of all possible values.
To re-enable DF24 decoding, use the new `--enable-df24` option.
Finally, avoid doing some CRC calculations twice. This was only happening
once per valid decoded message, not per demodulation attempt, so it's not
such a large win.
Usually, all message candidates are speculatively corrected as if
they were DF11/17/18, even if the DF field has a different value. This
allows correction of messages when there is correctable damage to the
DF field.
However, running every message candidate through a couple of CRC checks
is expensive, CPU-wise, when decoding messages off the air, as there are
a large number of message candidates that are actually just junk data, and
computing CRCs for all of those adds up. The --no-fix-df option allows
disabling this sort of correction. The tradeoff is that messages with
damage to the DF field will not be corrected.