[Client] Detect main-thread event loop stalls (#7155)

* [Client] Detect main-thread event loop stalls

LagMonitor ticks the GUI event loop every 500 ms and records gaps
beyond 2 s as stalls, warning with their duration and keeping a
bounded ring of recent records for diagnostics. Measurement uses a
monotonic QElapsedTimer so wall-clock steps and suspend do not
fabricate stalls. Recorded timestamps stay in wall time for
correlating with user reports.

Took 1 minute

Took 13 minutes


Took 2 minutes

* [Client] Rename LagMonitor constants to SCREAMING_SNAKE_CASE

Took 15 minutes

* [Client] Discard suspend-spanning gaps in LagMonitor

Windows counts sleep time in its monotonic clock, so a suspend would
fabricate one bogus stall per resume. Reset the clock on application
state changes and drop implausibly huge gaps; extract recordGap() for
testability.

Took 3 minutes

* [Client] Unit test LagMonitor stall recording

Drives recordGap() directly to cover the threshold, plausibility cap,
trim, and clear behavior without timing-dependent waits.

Took 36 seconds

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL 2026-08-23 00:53:40 +02:00 committed by GitHub
parent b91e872f5f
commit 88aa036f7e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 261 additions and 0 deletions

View file

@ -25,6 +25,7 @@
#ifndef WINDOW_H
#define WINDOW_H
#include "../client/lag_monitor.h"
#include "connection_controller/remote_connection_controller.h"
#include "widgets/dialogs/dlg_local_game_options.h"
@ -145,6 +146,7 @@ private:
WndSets *wndSets;
ConnectionController *connectionController;
LocalServer *localServer;
LagMonitor lagMonitor; ///< watches the main thread for event loop stalls
bool bHasActivated, askedForDbUpdater;
QProcess *cardUpdateProcess;
DlgViewLog *logviewDialog;