mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 19:45:09 +00:00
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:
+8
-2
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user