buffer_pool.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. package quic
  2. import (
  3. "sync"
  4. "github.com/lucas-clemente/quic-go/internal/protocol"
  5. )
  6. type packetBuffer struct {
  7. Slice []byte
  8. // refCount counts how many packets the Slice is used in.
  9. // It doesn't support concurrent use.
  10. // It is > 1 when used for coalesced packet.
  11. refCount int
  12. }
  13. // Split increases the refCount.
  14. // It must be called when a packet buffer is used for more than one packet,
  15. // e.g. when splitting coalesced packets.
  16. func (b *packetBuffer) Split() {
  17. b.refCount++
  18. }
  19. // Release decreases the refCount.
  20. // It should be called when processing the packet is finished.
  21. // When the refCount reaches 0, the packet buffer is put back into the pool.
  22. func (b *packetBuffer) Release() {
  23. if cap(b.Slice) != int(protocol.MaxReceivePacketSize) {
  24. panic("putPacketBuffer called with packet of wrong size!")
  25. }
  26. b.refCount--
  27. if b.refCount < 0 {
  28. panic("negative packetBuffer refCount")
  29. }
  30. // only put the packetBuffer back if it's not used any more
  31. if b.refCount == 0 {
  32. bufferPool.Put(b)
  33. }
  34. }
  35. var bufferPool sync.Pool
  36. func getPacketBuffer() *packetBuffer {
  37. buf := bufferPool.Get().(*packetBuffer)
  38. buf.refCount = 1
  39. buf.Slice = buf.Slice[:protocol.MaxReceivePacketSize]
  40. return buf
  41. }
  42. func init() {
  43. bufferPool.New = func() interface{} {
  44. return &packetBuffer{
  45. Slice: make([]byte, 0, protocol.MaxReceivePacketSize),
  46. }
  47. }
  48. }