107 lines
2.1 KiB
Go
107 lines
2.1 KiB
Go
package pingtunnel
|
|
|
|
import (
|
|
"container/list"
|
|
"github.com/esrrhs/go-engine/src/rbuffergo"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type FrameMgr struct {
|
|
sendb *rbuffergo.RBuffergo
|
|
recvb *rbuffergo.RBuffergo
|
|
sendlock sync.Locker
|
|
recvlock sync.Locker
|
|
windowsize int
|
|
resend_timems int
|
|
win *list.List
|
|
sendid int
|
|
sendlist *list.List
|
|
}
|
|
|
|
func NewFrameMgr(buffersize int, windowsize int, resend_timems int) *FrameMgr {
|
|
|
|
sendb := rbuffergo.New(buffersize, false)
|
|
recvb := rbuffergo.New(buffersize, false)
|
|
|
|
fm := &FrameMgr{sendb: sendb, recvb: recvb,
|
|
sendlock: &sync.Mutex{}, recvlock: &sync.Mutex{},
|
|
windowsize: windowsize, win: list.New(), sendid: 0,
|
|
resend_timems: resend_timems, sendlist: list.New()}
|
|
|
|
return fm
|
|
}
|
|
|
|
func (fm *FrameMgr) GetSendBufferLeft() int {
|
|
left := fm.sendb.Capacity() - fm.sendb.Size()
|
|
return left
|
|
}
|
|
|
|
func (fm *FrameMgr) WriteSendBuffer(data []byte) {
|
|
fm.sendlock.Lock()
|
|
defer fm.sendlock.Unlock()
|
|
fm.sendb.Write(data)
|
|
}
|
|
|
|
func (fm *FrameMgr) Update() {
|
|
fm.cutSendBufferToWindow()
|
|
fm.calSendList()
|
|
}
|
|
|
|
func (fm *FrameMgr) cutSendBufferToWindow() {
|
|
fm.sendlock.Lock()
|
|
defer fm.sendlock.Unlock()
|
|
|
|
sendall := false
|
|
|
|
if fm.sendb.Size() < FRAME_MAX_SIZE {
|
|
sendall = true
|
|
}
|
|
|
|
for fm.sendb.Size() > FRAME_MAX_SIZE && fm.win.Len() < fm.windowsize {
|
|
f := Frame{Resend: false, Sendtime: 0,
|
|
Id: (int32)(fm.sendid),
|
|
Data: make([]byte, FRAME_MAX_SIZE)}
|
|
fm.sendb.Read(f.Data)
|
|
|
|
fm.sendid++
|
|
if fm.sendid > FRAME_MAX_ID {
|
|
fm.sendid = 0
|
|
}
|
|
|
|
fm.win.PushBack(f)
|
|
}
|
|
|
|
if sendall && fm.sendb.Size() > 0 && fm.win.Len() < fm.windowsize {
|
|
f := Frame{Resend: false, Sendtime: 0,
|
|
Id: (int32)(fm.sendid),
|
|
Data: make([]byte, fm.sendb.Size())}
|
|
fm.sendb.Read(f.Data)
|
|
|
|
fm.sendid++
|
|
if fm.sendid > FRAME_MAX_ID {
|
|
fm.sendid = 0
|
|
}
|
|
|
|
fm.win.PushBack(f)
|
|
}
|
|
}
|
|
|
|
func (fm *FrameMgr) calSendList() {
|
|
cur := time.Now().UnixNano()
|
|
|
|
fm.sendlist.Init()
|
|
|
|
for e := fm.win.Front(); e != nil; e = e.Next() {
|
|
f := e.Value.(Frame)
|
|
if f.Resend || cur-f.Sendtime > int64(fm.resend_timems*1000) {
|
|
f.Sendtime = cur
|
|
fm.sendlist.PushBack(&f)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (fm *FrameMgr) getSendList() *list.List {
|
|
return fm.sendlist
|
|
}
|