You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
v2ray-core/transport/internet/kcp/buffer.go

103 lines
1.6 KiB

package kcp
import (
"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
}