httpdl: drop work-stealing segment pool for one worker per segment
The pool let an idle worker steal the back half of a slower in-flight segment, behind a mutex that also serialized every advance. At the default -x 1 it never fired, and it carried the trickiest invariant in the tree (minSplit >= readBuf keeps an owner's in-flight write out of the stolen tail). makeSegments already caps the segment count at the connection count, so the segments map one-to-one onto workers: give each its own goroutine, advance written with a plain atomic add, and snapshot the fixed slice with no lock. pool/newPool/acquire/steal/advance and the seg.owned field all go away. Net -156 lines. Behaviour at the user's flags is unchanged, except a slow mirror's tail segment is no longer rebalanced onto idle connections.
This commit is contained in:
@@ -28,10 +28,10 @@ type segState struct {
|
||||
|
||||
func controlPath(out string) string { return out + ".got" }
|
||||
|
||||
// snapshot builds a control record from the live segments. Callers hold the
|
||||
// pool lock (see pool.snapshot) so the slice and each segment's frontier are
|
||||
// stable for the read.
|
||||
func snapshot(url string, total int64, etag, lastmod string, segs []*seg) control {
|
||||
// snapshot builds a control record from the live segments. The segment slice is
|
||||
// fixed once the file is divided and each segment's frontier is owned by one
|
||||
// worker, so reading written atomically gives a consistent record with no lock.
|
||||
func snapshot(url string, total int64, etag, lastmod string, segs []seg) control {
|
||||
c := control{URL: url, Total: total, ETag: etag, LastModified: lastmod, Segs: make([]segState, len(segs))}
|
||||
for i := range segs {
|
||||
c.Segs[i] = segState{segs[i].start, segs[i].endOff(), atomic.LoadInt64(&segs[i].written)}
|
||||
|
||||
Reference in New Issue
Block a user