|  | @@ -146,7 +146,7 @@ type KCP struct {
 | 
	
		
			
				|  |  |  	ts_probe, probe_wait                   uint32
 | 
	
		
			
				|  |  |  	dead_link, incr                        uint32
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	snd_queue []*Segment
 | 
	
		
			
				|  |  | +	snd_queue *SendingQueue
 | 
	
		
			
				|  |  |  	rcv_queue []*Segment
 | 
	
		
			
				|  |  |  	snd_buf   []*Segment
 | 
	
		
			
				|  |  |  	rcv_buf   *ReceivingWindow
 | 
	
	
		
			
				|  | @@ -161,7 +161,7 @@ type KCP struct {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // NewKCP create a new kcp control object, 'conv' must equal in two endpoint
 | 
	
		
			
				|  |  |  // from the same connection.
 | 
	
		
			
				|  |  | -func NewKCP(conv uint32, mtu uint32, sendingWindowSize uint32, receivingWindowSize uint32, output Output) *KCP {
 | 
	
		
			
				|  |  | +func NewKCP(conv uint32, mtu uint32, sendingWindowSize uint32, receivingWindowSize uint32, sendingQueueSize uint32, output Output) *KCP {
 | 
	
		
			
				|  |  |  	kcp := new(KCP)
 | 
	
		
			
				|  |  |  	kcp.conv = conv
 | 
	
		
			
				|  |  |  	kcp.snd_wnd = sendingWindowSize
 | 
	
	
		
			
				|  | @@ -177,6 +177,7 @@ func NewKCP(conv uint32, mtu uint32, sendingWindowSize uint32, receivingWindowSi
 | 
	
		
			
				|  |  |  	kcp.dead_link = IKCP_DEADLINK
 | 
	
		
			
				|  |  |  	kcp.output = output
 | 
	
		
			
				|  |  |  	kcp.rcv_buf = NewReceivingWindow(receivingWindowSize)
 | 
	
		
			
				|  |  | +	kcp.snd_queue = NewSendingQueue(sendingQueueSize)
 | 
	
		
			
				|  |  |  	return kcp
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -232,26 +233,8 @@ func (kcp *KCP) DumpReceivingBuf() {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // Send is user/upper level send, returns below zero for error
 | 
	
		
			
				|  |  |  func (kcp *KCP) Send(buffer []byte) int {
 | 
	
		
			
				|  |  | -	var count int
 | 
	
		
			
				|  |  | -	if len(buffer) == 0 {
 | 
	
		
			
				|  |  | -		return -1
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if len(buffer) < int(kcp.mss) {
 | 
	
		
			
				|  |  | -		count = 1
 | 
	
		
			
				|  |  | -	} else {
 | 
	
		
			
				|  |  | -		count = (len(buffer) + int(kcp.mss) - 1) / int(kcp.mss)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if count > 255 {
 | 
	
		
			
				|  |  | -		return -2
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if count == 0 {
 | 
	
		
			
				|  |  | -		count = 1
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	for i := 0; i < count; i++ {
 | 
	
		
			
				|  |  | +	nBytes := 0
 | 
	
		
			
				|  |  | +	for len(buffer) > 0 && !kcp.snd_queue.IsFull() {
 | 
	
		
			
				|  |  |  		var size int
 | 
	
		
			
				|  |  |  		if len(buffer) > int(kcp.mss) {
 | 
	
		
			
				|  |  |  			size = int(kcp.mss)
 | 
	
	
		
			
				|  | @@ -260,11 +243,11 @@ func (kcp *KCP) Send(buffer []byte) int {
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  		seg := NewSegment()
 | 
	
		
			
				|  |  |  		seg.data.Append(buffer[:size])
 | 
	
		
			
				|  |  | -		seg.frg = uint32(count - i - 1)
 | 
	
		
			
				|  |  | -		kcp.snd_queue = append(kcp.snd_queue, seg)
 | 
	
		
			
				|  |  | +		kcp.snd_queue.Push(seg)
 | 
	
		
			
				|  |  |  		buffer = buffer[size:]
 | 
	
		
			
				|  |  | +		nBytes += size
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	return 0
 | 
	
		
			
				|  |  | +	return nBytes
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // https://tools.ietf.org/html/rfc6298
 | 
	
	
		
			
				|  | @@ -572,12 +555,8 @@ func (kcp *KCP) flush() {
 | 
	
		
			
				|  |  |  		cwnd = _imin_(kcp.cwnd, cwnd)
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	count = 0
 | 
	
		
			
				|  |  | -	for k := range kcp.snd_queue {
 | 
	
		
			
				|  |  | -		if _itimediff(kcp.snd_nxt, cwnd) >= 0 {
 | 
	
		
			
				|  |  | -			break
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		newseg := kcp.snd_queue[k]
 | 
	
		
			
				|  |  | +	for !kcp.snd_queue.IsEmpty() && _itimediff(kcp.snd_nxt, cwnd) < 0 {
 | 
	
		
			
				|  |  | +		newseg := kcp.snd_queue.Pop()
 | 
	
		
			
				|  |  |  		newseg.conv = kcp.conv
 | 
	
		
			
				|  |  |  		newseg.cmd = IKCP_CMD_PUSH
 | 
	
		
			
				|  |  |  		newseg.wnd = seg.wnd
 | 
	
	
		
			
				|  | @@ -589,9 +568,7 @@ func (kcp *KCP) flush() {
 | 
	
		
			
				|  |  |  		newseg.xmit = 0
 | 
	
		
			
				|  |  |  		kcp.snd_buf = append(kcp.snd_buf, newseg)
 | 
	
		
			
				|  |  |  		kcp.snd_nxt++
 | 
	
		
			
				|  |  | -		count++
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	kcp.snd_queue = kcp.snd_queue[count:]
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	// calculate resent
 | 
	
		
			
				|  |  |  	resent := uint32(kcp.fastresend)
 | 
	
	
		
			
				|  | @@ -774,14 +751,11 @@ func (kcp *KCP) NoDelay(interval uint32, resend int, congestionControl bool) int
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // WaitSnd gets how many packet is waiting to be sent
 | 
	
		
			
				|  |  |  func (kcp *KCP) WaitSnd() uint32 {
 | 
	
		
			
				|  |  | -	return uint32(len(kcp.snd_buf) + len(kcp.snd_queue))
 | 
	
		
			
				|  |  | +	return uint32(len(kcp.snd_buf)) + kcp.snd_queue.Len()
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func (this *KCP) ClearSendQueue() {
 | 
	
		
			
				|  |  | -	for _, seg := range this.snd_queue {
 | 
	
		
			
				|  |  | -		seg.Release()
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	this.snd_queue = nil
 | 
	
		
			
				|  |  | +	this.snd_queue.Clear()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	for _, seg := range this.snd_buf {
 | 
	
		
			
				|  |  |  		seg.Release()
 |