fix: a clock that stalled on a re-plan, and a dialog that could not close
**The clock.** Trigger mode showed a blank plot and never latched when the session defined a math
channel, because such a session gives the model a plan *before* the stream's own signals are in it:
one derived channel, declared rate 0, so `plan_partition()`'s 1 kHz fallback is the interval those
early frames are stamped at -- 1300x too fast for a 1.3 MS/s stream -- and they have nowhere to go,
since the value loop skips derived channels. Relative mode then stamped a *position* times the plan's
*current* interval, so when the CONFIG's channels landed and the plan took the real rate (769 ns) the
same positions produced times 1300x *smaller* than what was already in the ring, and the monotonic
clamp held the clock at the old value for the rest of the run: one repeated stamp, `history=0`, no
latch, and a window the renderer cannot draw. The same family as the restarted-client poisoning
fixed in 620473a, through a different door. The filter's own output was finite and correct
throughout, and disabling the math channel only appeared to cure it because that is a structural
change which rebuilds the store -- the third time that channel has looked guilty while being a
bystander.
Relative mode now accumulates *seconds* (`rel_base_s_ += n * dt`), so a re-plan is a slope change and
the clock cannot jump backwards by construction; a frame is only stamped into a model that has a
*streamed* channel; and the epoch is adopted once per connection, with "unset" a state rather than
the value zero. A one-shot warning names the family if it returns: `the clock stalled at ...: N
samples stamped [a..b] are all behind it`.
**The dialog.** The Configurations window's Close button and the window-manager close both did
nothing: `close-request` was connected to a bare `void` lambda, and that signal is `gboolean` -- TRUE
means "handled" and suppresses the default handler that destroys the window, while `G_CALLBACK` is a
cast, so GTK read whatever the compiler left in the return register. A standalone GTK program of that
shape reproduces it: `void` handler -> `window_alive=1` after `gtk_window_close()`, `gboolean FALSE`
-> 0. The same audit found `gtk_window_present(GTK_WINDOW(...))` on an `AdwDialog`, a type assertion
and a no-op; it is `adw_dialog_present()` now. The menu row stays: it is the only way to switch or
save a configuration without restarting, and what made it look useless was that it could not close.
Verified: trigger mode with that session's graph reads `ring=[0.0058..0.2446] -> [0.0058..1.9969]`,
`history 0.237 -> 2.0 s`, `edge at 1.120 s, latched at 2.120 s`, `display=event(frozen) latches=1`,
`traceless paints 266` against 1519 before the fix. Baselines hold: 0 errors, the documented three
warnings, test-ui 13 ok, test-help green, `gtk warnings: 0`.
This commit is contained in:
1 parent
27c9b34277
commit
074cb611bc
9 files changed
+210
-34
No files matched your search
@@ -570,6 +570,18 @@ the stream's own clock. The packet counter says exactly how many samples each ga
|
||||
reserved hole is a precise arithmetic range. In stream mode the same hole is estimated from the
|
||||
declared cadence, which is the existing glitch-bridge mechanism reused.
|
||||
|
||||
**The relative clock is a time, not a position times a rate.** The buffer plan is rebuilt whenever
|
||||
the channel list changes — a CONFIG, an enable, a session's math channels — and the interval that
|
||||
plan declares is the **1 kHz fallback** until a *streamed* channel declares a rate. A clock
|
||||
recomputed as `position × interval` therefore jumped whenever the plan moved, and a plan that
|
||||
*shortened* the interval put every later stamp behind the one already written, where the frame
|
||||
loop's monotonic clamp held it for the rest of the run: `ring=[a..a]` standing still while `n`
|
||||
climbed, `history` never reaching the pre-window, no latch, and a blank plot in every mode. The
|
||||
clock is now accumulated in seconds — a plan change is a slope change — and a frame is only
|
||||
stamped into a model that has a **streamed** channel, so the fallback interval can never become a
|
||||
run's origin. The stall it used to cause is named in one line, once per connection:
|
||||
`[udpscope] warning: the clock stalled at ... s: N samples stamped [...] are all behind it`.
|
||||
|
||||
The history cost of relative mode is measured rather than computed:
|
||||
|
||||
| mode | retained span |
|
||||
|
||||
Reference in new issue
Block a user