wgengine/tstun: move sync.Pool to package global

sync.Pools should almost always be packate globals, even though in this
case we only have exactly 1 TUN device anyway, so it matters less.
Still, it's unusual to see a Pool that's not a package global, so move it.
reviewable/pr596/r1
Brad Fitzpatrick 4 years ago
parent 318751c486
commit a89d610a3d

@ -45,6 +45,11 @@ var (
errOffsetTooSmall = errors.New("offset smaller than PacketStartOffset") errOffsetTooSmall = errors.New("offset smaller than PacketStartOffset")
) )
// parsedPacketPool holds a pool of ParsedPacket structs for use in filtering.
// This is needed because escape analysis cannot see that parsed packets
// do not escape through {Pre,Post}Filter{In,Out}.
var parsedPacketPool = sync.Pool{New: func() interface{} { return new(packet.ParsedPacket) }}
// FilterFunc is a packet-filtering function with access to the TUN device. // FilterFunc is a packet-filtering function with access to the TUN device.
// It must not hold onto the packet struct, as its backing storage will be reused. // It must not hold onto the packet struct, as its backing storage will be reused.
type FilterFunc func(*packet.ParsedPacket, *TUN) filter.Response type FilterFunc func(*packet.ParsedPacket, *TUN) filter.Response
@ -66,10 +71,6 @@ type TUN struct {
buffer [maxBufferSize]byte buffer [maxBufferSize]byte
// bufferConsumed synchronizes access to buffer (shared by Read and poll). // bufferConsumed synchronizes access to buffer (shared by Read and poll).
bufferConsumed chan struct{} bufferConsumed chan struct{}
// parsedPacketPool holds a pool of ParsedPacket structs for use in filtering.
// This is needed because escape analysis cannot see that parsed packets
// do not escape through {Pre,Post}Filter{In,Out}.
parsedPacketPool sync.Pool // of *packet.ParsedPacket
// closed signals poll (by closing) when the device is closed. // closed signals poll (by closing) when the device is closed.
closed chan struct{} closed chan struct{}
@ -121,10 +122,6 @@ func WrapTUN(logf logger.Logf, tdev tun.Device) *TUN {
filterFlags: filter.LogAccepts | filter.LogDrops, filterFlags: filter.LogAccepts | filter.LogDrops,
} }
tun.parsedPacketPool.New = func() interface{} {
return new(packet.ParsedPacket)
}
go tun.poll() go tun.poll()
// The buffer starts out consumed. // The buffer starts out consumed.
tun.bufferConsumed <- struct{}{} tun.bufferConsumed <- struct{}{}
@ -208,8 +205,8 @@ func (t *TUN) poll() {
} }
func (t *TUN) filterOut(buf []byte) filter.Response { func (t *TUN) filterOut(buf []byte) filter.Response {
p := t.parsedPacketPool.Get().(*packet.ParsedPacket) p := parsedPacketPool.Get().(*packet.ParsedPacket)
defer t.parsedPacketPool.Put(p) defer parsedPacketPool.Put(p)
p.Decode(buf) p.Decode(buf)
if t.PreFilterOut != nil { if t.PreFilterOut != nil {
@ -287,8 +284,8 @@ func (t *TUN) Read(buf []byte, offset int) (int, error) {
} }
func (t *TUN) filterIn(buf []byte) filter.Response { func (t *TUN) filterIn(buf []byte) filter.Response {
p := t.parsedPacketPool.Get().(*packet.ParsedPacket) p := parsedPacketPool.Get().(*packet.ParsedPacket)
defer t.parsedPacketPool.Put(p) defer parsedPacketPool.Put(p)
p.Decode(buf) p.Decode(buf)
if t.PreFilterIn != nil { if t.PreFilterIn != nil {

Loading…
Cancel
Save