all: cut bloat found in the pike audit

Dead, vestigial, and over-built code with no behavior change (except the
bool-vocabulary trim, a deliberate behavior tightening):

- httpdl: drop the vestigial sort+copy in validSegs (work-stealing was
  removed in 270812d, so segments always tile [0,total) ascending now);
  validate order in place, which also rejects a scrambled sidecar. Inline
  the endOff() accessor to s.end.
- cli: shrink the boolean vocabulary to true/false, which is all that's
  accepted. The invented yes/no/1/0/on/off spellings are gone, so e.g.
  --enable-dht=yes (or yes in got.conf) is now a usage error.
- download: remove the dead, never-called Stat.Done() method.
- progress: drop speed(), a pure alias of humanSize; call humanSize directly.
- main: replace the jobsHolder mutex box with atomic.Pointer[[]job] for the
  forced-exit session save; the capability stays, the lock and type go.
- bt: collapse isAddrInUse's X||X (missinggo.IsAddrInUse is that exact
  string match); drop the now-unused missinggo import (tidy -> indirect).
- option: note that prealloc and falloc are identical here.
This commit is contained in:
2026-06-21 15:45:56 +09:00
parent 3eb2d5ffcb
commit 10672f3816
14 changed files with 47 additions and 75 deletions

41
main.go
View File

@@ -17,7 +17,7 @@ import (
"sort"
"strconv"
"strings"
"sync"
"sync/atomic"
"syscall"
"time"
@@ -94,8 +94,12 @@ func run(args []string) int {
t := time.AfterFunc(time.Duration(stop)*time.Second, cancel)
defer t.Stop()
}
jobsRef := &jobsHolder{}
go handleSignals(cancel, sessionFile, jobsRef)
var jobsRef atomic.Pointer[[]job]
// publish snapshots the slice header (j is a by-value copy) and stores a
// pointer to it, so the signal handler can read the current jobs lock-free
// without racing the `jobs = append(...)` reassignment in the follow pass.
publish := func(j []job) { jobsRef.Store(&j) }
go handleSignals(cancel, sessionFile, &jobsRef)
eng := download.NewEngine(opts.Int("max-concurrent-downloads"))
@@ -111,7 +115,7 @@ func run(args []string) int {
close(uiDone)
}
jobsRef.set(jobs)
publish(jobs)
results := runJobs(ctx, eng, jobs)
// --follow-torrent: a .torrent fetched over HTTP becomes a BitTorrent
@@ -125,7 +129,7 @@ func run(args []string) int {
// Index space, so the sort below restores input order deterministically.
nInitial := len(jobs)
jobs = append(jobs, follow...)
jobsRef.set(jobs)
publish(jobs)
followResults := runJobs(ctx, eng, follow)
for i := range followResults {
followResults[i].Index += nInitial
@@ -153,25 +157,6 @@ func run(args []string) int {
return report(results)
}
// jobsHolder lets the signal handler reach the latest job list for a
// best-effort session save on a forced (second-Ctrl-C) exit.
type jobsHolder struct {
mu sync.Mutex
jobs []job
}
func (h *jobsHolder) set(jobs []job) {
h.mu.Lock()
h.jobs = jobs
h.mu.Unlock()
}
func (h *jobsHolder) get() []job {
h.mu.Lock()
defer h.mu.Unlock()
return h.jobs
}
// job pairs a download with the source string that produced it, so we can write
// the still-unfinished ones back to a session file.
type job struct {
@@ -810,14 +795,18 @@ func progressNote(s download.Stat) string {
// TERM) cancels the graceful context so run() can wind down and save normally;
// a second forces exit, but first writes the session best-effort so the resume
// list survives a force-quit.
func handleSignals(cancel context.CancelFunc, sessionFile string, jobs *jobsHolder) {
func handleSignals(cancel context.CancelFunc, sessionFile string, jobs *atomic.Pointer[[]job]) {
sig := make(chan os.Signal, 2)
signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
<-sig // first: cancel the graceful context
cancel()
<-sig // second: force exit
if sessionFile != "" {
if err := saveSession(sessionFile, jobs.get()); err != nil {
var js []job // nil until the first publish; saveSession handles an empty list
if p := jobs.Load(); p != nil {
js = *p
}
if err := saveSession(sessionFile, js); err != nil {
fmt.Fprintln(os.Stderr, "got:", err)
}
}