Table.loop calls (*tableRevalidation).run without holding tab.mutex,
while doRefresh -> loadSeedNodes -> handleAddNode reaches the same
tableRevalidation state (nodeAdded -> list.push -> list.schedule) in a
separate goroutine under tab.mutex. The two paths race on
revalidationList.nextTime and list.nodes: the loop goroutine reads
nextTime in run, schedules (writes it) and iterates list.nodes via
list.get; the refresh goroutine appends to list.nodes and, on the first
push, writes nextTime.
Acquire tab.mutex for the full duration of run and document that
startRequest must be called with the lock held. Remove the now-redundant
internal lock/unlock pair in startRequest.
Add a regression test that triggers the race deterministically under
'go test -race'.
Closes#31460.