| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 | package kcpimport (	"sync"	"github.com/v2ray/v2ray-core/common/alloc")const (	NumDistro  = 5	DistroSize = 1600)type Buffer struct {	sync.Mutex	buffer *alloc.Buffer	next     int	released int	hold     bool	distro   [NumDistro]*alloc.Buffer}func NewBuffer() *Buffer {	b := &Buffer{		next:     0,		released: 0,		hold:     true,		buffer:   alloc.NewBuffer(),	}	for idx := range b.distro {		content := b.buffer.Value[idx*DistroSize : (idx+1)*DistroSize]		b.distro[idx] = alloc.CreateBuffer(content, b)	}	return b}func (this *Buffer) IsEmpty() bool {	this.Lock()	defer this.Unlock()	return this.next == NumDistro}func (this *Buffer) Allocate() *alloc.Buffer {	this.Lock()	defer this.Unlock()	if this.next == NumDistro {		return nil	}	b := this.distro[this.next]	this.next++	return b}func (this *Buffer) Free(b *alloc.Buffer) {	this.Lock()	defer this.Unlock()	this.released++	if !this.hold && this.released == this.next {		this.ReleaseBuffer()	}}func (this *Buffer) Release() {	this.Lock()	defer this.Unlock()	if this.next == this.released {		this.ReleaseBuffer()	}	this.hold = false}func (this *Buffer) ReleaseBuffer() {	this.buffer.Release()	this.buffer = nil	for idx := range this.distro {		this.distro[idx] = nil	}}var (	globalBuffer       *Buffer	globalBufferAccess sync.Mutex)func AllocateBuffer() *alloc.Buffer {	globalBufferAccess.Lock()	defer globalBufferAccess.Unlock()	if globalBuffer == nil {		globalBuffer = NewBuffer()	}	b := globalBuffer.Allocate()	if globalBuffer.IsEmpty() {		globalBuffer.Release()		globalBuffer = nil	}	return b}
 |