fix(hpsdr): prevent false connection lost on tick race

The RX timeout check sampled GetTickCount64 on the UI thread while the UDP receive thread could update FRXLastPktTime a millisecond later. Both values are QWord, so subtracting the newer packet tick from the older UI tick underflowed to a very large value and falsely satisfied the 3-second timeout.

Snapshot the packet timestamp once for each timeout check and require NowTick >= LastPktTick before calculating the elapsed interval. The initial-packet timeout uses the same snapshot. This preserves real timeout detection while ignoring a packet timestamp that is marginally newer than the UI tick.

Diagnostics confirmed that DDC UDP packets, callbacks, and HP status remained continuous during the reported failures; the issue was local timeout arithmetic rather than network loss or radio stream interruption.
This commit is contained in:
2026-07-21 00:13:35 +03:00
parent c645b0d1e6
commit ced42fbac9
+8 -2
View File
@@ -3409,6 +3409,7 @@ procedure TMainForm.SpectrumTimerTick(Sender: TObject);
var
NowTick: QWord;
ElapsedTick: QWord;
LastPktTick: QWord;
I: Integer;
begin
// «×» шапки пана: закрытие отложено сюда (нельзя free панель из её кнопки).
@@ -3438,8 +3439,12 @@ begin
begin
NowTick := GetTickCount64;
ElapsedTick := NowTick - FController.FRXStartTime;
// Сетевой поток может обновить FRXLastPktTime на 1 ms ПОСЛЕ NowTick.
// QWord-вычитание в таком случае underflow'ится в огромное значение и
// давало ложный "Connection lost" при совершенно живом DDC-потоке.
LastPktTick := FController.FRXLastPktTime;
// Ждём первый пакет 5 секунд после старта
if (FController.FRXLastPktTime = 0) and (ElapsedTick > 5000) then
if (LastPktTick = 0) and (ElapsedTick > 5000) then
begin
BtnStartStop.Caption := 'START';
StyleButton(BtnStartStop, False);
@@ -3451,7 +3456,8 @@ begin
Exit;
end;
// После первого пакета — следим чтобы поток не прерывался более 3 сек
if (FController.FRXLastPktTime > 0) and ((NowTick - FController.FRXLastPktTime) > 3000) then
if (LastPktTick > 0) and (NowTick >= LastPktTick) and
((NowTick - LastPktTick) > 3000) then
begin
BtnStartStop.Caption := 'START';
StyleButton(BtnStartStop, False);