buffer_pool.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package quic
  2. import (
  3. "sync"
  4. "github.com/Psiphon-Labs/quic-go/internal/protocol"
  5. )
  6. type packetBuffer struct {
  7. Data []byte
  8. // refCount counts how many packets Data 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. // Decrement decrements the reference counter.
  20. // It doesn't put the buffer back into the pool.
  21. func (b *packetBuffer) Decrement() {
  22. b.refCount--
  23. if b.refCount < 0 {
  24. panic("negative packetBuffer refCount")
  25. }
  26. }
  27. // MaybeRelease puts the packet buffer back into the pool,
  28. // if the reference counter already reached 0.
  29. func (b *packetBuffer) MaybeRelease() {
  30. // only put the packetBuffer back if it's not used any more
  31. if b.refCount == 0 {
  32. b.putBack()
  33. }
  34. }
  35. // Release puts back the packet buffer into the pool.
  36. // It should be called when processing is definitely finished.
  37. func (b *packetBuffer) Release() {
  38. b.Decrement()
  39. if b.refCount != 0 {
  40. panic("packetBuffer refCount not zero")
  41. }
  42. b.putBack()
  43. }
  44. // Len returns the length of Data
  45. func (b *packetBuffer) Len() protocol.ByteCount { return protocol.ByteCount(len(b.Data)) }
  46. func (b *packetBuffer) Cap() protocol.ByteCount { return protocol.ByteCount(cap(b.Data)) }
  47. func (b *packetBuffer) putBack() {
  48. if cap(b.Data) == protocol.MaxPacketBufferSize {
  49. bufferPool.Put(b)
  50. return
  51. }
  52. if cap(b.Data) == protocol.MaxLargePacketBufferSize {
  53. largeBufferPool.Put(b)
  54. return
  55. }
  56. panic("putPacketBuffer called with packet of wrong size!")
  57. }
  58. var bufferPool, largeBufferPool sync.Pool
  59. func getPacketBuffer() *packetBuffer {
  60. buf := bufferPool.Get().(*packetBuffer)
  61. buf.refCount = 1
  62. buf.Data = buf.Data[:0]
  63. return buf
  64. }
  65. func getLargePacketBuffer() *packetBuffer {
  66. buf := largeBufferPool.Get().(*packetBuffer)
  67. buf.refCount = 1
  68. buf.Data = buf.Data[:0]
  69. return buf
  70. }
  71. func init() {
  72. bufferPool.New = func() any {
  73. return &packetBuffer{Data: make([]byte, 0, protocol.MaxPacketBufferSize)}
  74. }
  75. largeBufferPool.New = func() any {
  76. return &packetBuffer{Data: make([]byte, 0, protocol.MaxLargePacketBufferSize)}
  77. }
  78. }