From fea2cc6839ec3ee17940a2dea69622dc6f4deabf Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Wed, 16 Sep 2026 21:35:55 -0400 Subject: fix: unify crafting ingredient resolution; fix superheat alternatives, quantity gates, and dropped combine byproducts --- internal/game/quit_state_race_test.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 internal/game/quit_state_race_test.go (limited to 'internal/game/quit_state_race_test.go') diff --git a/internal/game/quit_state_race_test.go b/internal/game/quit_state_race_test.go new file mode 100644 index 0000000..68f4770 --- /dev/null +++ b/internal/game/quit_state_race_test.go @@ -0,0 +1,32 @@ +package game + +// Regression: network input may arrive on a connection goroutine at any +// moment, including while the tick-driven logout countdown (owner goroutine) +// transitions the session to the character menu. The dispatch read +// sess.State as a plain field, which the race detector flagged; the state is +// now an atomic on net.Session. This test drives both sides concurrently and +// must run clean under -race. + +import ( + "testing" + "time" +) + +func TestInputDuringLogoutCountdownIsRaceFree(t *testing.T) { + h := newHarness(t) + h.seedAccount("alice") + h.seedCharacter("alice", "alice") + sess, _ := h.connect("alice") + + h.g.RunOnOwner(func() { + h.g.beginQuitCountdown(sess) + }) + + // Pump input while the countdown ticks toward the state change to the + // character menu (and past it, when the countdown completes early). + deadline := time.Now().Add(100 * time.Millisecond) + for time.Now().Before(deadline) { + h.g.HandleSessionOnOwner(sess, "notacommand") + } + h.barrier() +} -- cgit v1.2.3