mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-26 04:47:35 +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
|
var
|
||||||
NowTick: QWord;
|
NowTick: QWord;
|
||||||
ElapsedTick: QWord;
|
ElapsedTick: QWord;
|
||||||
|
LastPktTick: QWord;
|
||||||
I: Integer;
|
I: Integer;
|
||||||
begin
|
begin
|
||||||
// «×» шапки пана: закрытие отложено сюда (нельзя free панель из её кнопки).
|
// «×» шапки пана: закрытие отложено сюда (нельзя free панель из её кнопки).
|
||||||
@@ -3438,8 +3439,12 @@ begin
|
|||||||
begin
|
begin
|
||||||
NowTick := GetTickCount64;
|
NowTick := GetTickCount64;
|
||||||
ElapsedTick := NowTick - FController.FRXStartTime;
|
ElapsedTick := NowTick - FController.FRXStartTime;
|
||||||
|
// Сетевой поток может обновить FRXLastPktTime на 1 ms ПОСЛЕ NowTick.
|
||||||
|
// QWord-вычитание в таком случае underflow'ится в огромное значение и
|
||||||
|
// давало ложный "Connection lost" при совершенно живом DDC-потоке.
|
||||||
|
LastPktTick := FController.FRXLastPktTime;
|
||||||
// Ждём первый пакет 5 секунд после старта
|
// Ждём первый пакет 5 секунд после старта
|
||||||
if (FController.FRXLastPktTime = 0) and (ElapsedTick > 5000) then
|
if (LastPktTick = 0) and (ElapsedTick > 5000) then
|
||||||
begin
|
begin
|
||||||
BtnStartStop.Caption := 'START';
|
BtnStartStop.Caption := 'START';
|
||||||
StyleButton(BtnStartStop, False);
|
StyleButton(BtnStartStop, False);
|
||||||
@@ -3451,7 +3456,8 @@ begin
|
|||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
// После первого пакета — следим чтобы поток не прерывался более 3 сек
|
// После первого пакета — следим чтобы поток не прерывался более 3 сек
|
||||||
if (FController.FRXLastPktTime > 0) and ((NowTick - FController.FRXLastPktTime) > 3000) then
|
if (LastPktTick > 0) and (NowTick >= LastPktTick) and
|
||||||
|
((NowTick - LastPktTick) > 3000) then
|
||||||
begin
|
begin
|
||||||
BtnStartStop.Caption := 'START';
|
BtnStartStop.Caption := 'START';
|
||||||
StyleButton(BtnStartStop, False);
|
StyleButton(BtnStartStop, False);
|
||||||
|
|||||||
Reference in New Issue
Block a user