From b5155cf4c31ae96e04a977fc49375b3e625c5021 Mon Sep 17 00:00:00 2001 From: Simon Dick Date: Tue, 21 Jul 2026 20:02:59 +0100 Subject: [PATCH] GUI: open the window before the startup SNTP sync (#71) The startup sync ran between the passphrase requester and win_show, and it can block for a long time: gethostbyname() has no timeout under our control (a dead resolver can hang it for tens of seconds) plus up to 5s of UDP wait. With a TCP/IP stack up but the network dead, the requester closed and then nothing appeared - the parked "unlock then no window" symptom from #71, which reads as a crash. Reproduced deliberately under Copperline with a 30s stall injected at the sync site: old ordering shows a bare desktop at t=35s (gui-smoke's window assertion fails), new ordering has the window up and painted with the stall running behind it. The window is briefly unresponsive during a slow sync (amber/red LED, "------" codes) and the status line + LED refresh the moment the sync returns. CLI-forwarding semantics are unchanged: the public port still registers after the sync, so a CLI launched meanwhile falls back to its local path exactly as before. Docs: Troubleshooting gains a "window ignores clicks briefly" entry (replacing the invisible-hang failure mode); Time and Clock Sync notes the sync now happens right after the window opens. Co-Authored-By: Claude Fable 5 --- src/gui/main.c | 50 +++++++++++++++++++---------- userdocs/Time-and-Clock-Sync.md | 5 +-- userdocs/Troubleshooting-and-FAQ.md | 10 ++++++ 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/src/gui/main.c b/src/gui/main.c index 5aeec29..3f7c917 100644 --- a/src/gui/main.c +++ b/src/gui/main.c @@ -1751,23 +1751,6 @@ int main(int argc, char **argv) } clock_setup(&clk); - /* One SNTP sync at startup so the resident instance has accurate (green) time - * without a manual CLI SYNC. Server precedence mirrors the CLI: the TIMESERVER - * tooltype, then the saved "server" pref, then the default pool. Fails - * fast/quiet with no TCP/IP stack (or no response), leaving the persisted - * offset in place (clock_sntp_sync only updates clk on success). */ - { - STRPTR ts = ArgString((CONST_STRPTR *)tt, (CONST_STRPTR)"TIMESERVER", NULL); - char cfg[128]; - const char *server; - if (ts && ts[0]) server = (const char *)ts; - else if (prefs_get("server", cfg, sizeof cfg) == 0 && cfg[0]) server = cfg; - else server = "pool.ntp.org"; - if (clock_sntp_sync(&clk, server) == 0) { - prefs_set("server", server); - prefs_set_long("offset", clk.offset_seconds); - } - } naccounts = v.count; /* Idle auto-lock (encrypted vaults only): scrub + re-prompt after this many * idle seconds. Pref "idlelock" overrides; 0 disables. */ @@ -1807,6 +1790,39 @@ int main(int argc, char **argv) } } + /* One SNTP sync at startup so the resident instance has accurate (green) + * time without a manual CLI SYNC. Server precedence mirrors the CLI: the + * TIMESERVER tooltype, then the saved "server" pref, then the default + * pool. Fails fast/quiet with no TCP/IP stack (or no response), leaving + * the persisted offset in place (clock_sntp_sync only updates clk on + * success). + * + * Deliberately AFTER the window opens (#71): the sync blocks - up to + * SNTP_TIMEOUT_SECS on the UDP wait, and gethostbyname() can hang far + * longer against a dead resolver. Run before win_show, that stall sat + * between the passphrase requester closing and the window appearing, + * which reads as a crash/hang. Now the window is already up (painted, + * amber/red LED) and merely unresponsive for the duration; the status + * line + LED refresh the moment the sync returns. */ + { + STRPTR ts = ArgString((CONST_STRPTR *)tt, (CONST_STRPTR)"TIMESERVER", NULL); + char cfg[128]; + const char *server; + if (ts && ts[0]) server = (const char *)ts; + else if (prefs_get("server", cfg, sizeof cfg) == 0 && cfg[0]) server = cfg; + else server = "pool.ntp.org"; + if (clock_sntp_sync(&clk, server) == 0) { + prefs_set("server", server); + prefs_set_long("offset", clk.offset_seconds); + if (win) { /* went green - show it right away */ + clock_status_text(&clk, statbuf); + SetGadgetAttrs((struct Gadget *)gw.statobj, win, NULL, + GA_Text, (ULONG)statbuf, TAG_END); + led_draw(win, gw.statobj, clk.state); + } + } + } + /* Public port for CLI forwarding (Stage 3b), only if we're the resident one. * Single-instance itself is handled earlier (the Stage 3a broker's CBERR_DUP, * or the early FindPort check above for the no-commodities case, #64) - this diff --git a/userdocs/Time-and-Clock-Sync.md b/userdocs/Time-and-Clock-Sync.md index 49ffbac..d378830 100644 --- a/userdocs/Time-and-Clock-Sync.md +++ b/userdocs/Time-and-Clock-Sync.md @@ -38,8 +38,9 @@ If a TCP/IP stack is running (`bsdsocket.library` present — AmiTCP, Roadshow, Miami, an emulator's bsdsocket, …), AmiAuth can measure your clock's offset with a single small UDP exchange against an NTP server. Zero configuration. -- **GUI:** performs one SNTP sync automatically at startup, so a resident - commodity has verified (green) time for its whole session with no +- **GUI:** performs one SNTP sync automatically at startup (right after the + window opens — the clock LED goes green the moment it succeeds), so a + resident commodity has verified time for its whole session with no configuration. The server can be chosen with the `TIMESERVER` tooltype (see [Commodity and Tooltypes](Commodity-and-Tooltypes.md)); offline it fails quietly and falls back to the stored offset. diff --git a/userdocs/Troubleshooting-and-FAQ.md b/userdocs/Troubleshooting-and-FAQ.md index 158a6f5..bad0880 100644 --- a/userdocs/Troubleshooting-and-FAQ.md +++ b/userdocs/Troubleshooting-and-FAQ.md @@ -82,6 +82,16 @@ it. There is no software fix for this on classic AmigaOS: once a task has been killed outside its own control, it never gets the chance to unregister itself, and nothing else on the system can force that cleanup on its behalf. +### The window opens but ignores clicks for a few seconds after unlocking + +The automatic SNTP sync at startup blocks the GUI briefly: normally well +under a second, but with a TCP/IP stack running and the network down or the +DNS server unreachable it can take many seconds to give up. The window opens +first and stays visible the whole time (this used to look like a hang, with +no window at all until the sync timed out); the clock status line and LED +update the moment the sync finishes. If it bothers you regularly, take the +stack offline (the sync then skips instantly) or fix the name server. + ### The hotkey does nothing Another commodity may own the combination — check in Exchange, and change