|  | @@ -58,6 +58,7 @@ func (this *ReceivingWindow) Advance() {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  type ReceivingQueue struct {
 | 
	
		
			
				|  |  | +	sync.Mutex
 | 
	
		
			
				|  |  |  	closed  bool
 | 
	
		
			
				|  |  |  	cache   *alloc.Buffer
 | 
	
		
			
				|  |  |  	queue   chan *alloc.Buffer
 | 
	
	
		
			
				|  | @@ -114,6 +115,9 @@ L:
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func (this *ReceivingQueue) Put(payload *alloc.Buffer) bool {
 | 
	
		
			
				|  |  | +	this.Lock()
 | 
	
		
			
				|  |  | +	defer this.Unlock()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	if this.closed {
 | 
	
		
			
				|  |  |  		payload.Release()
 | 
	
		
			
				|  |  |  		return false
 | 
	
	
		
			
				|  | @@ -133,6 +137,9 @@ func (this *ReceivingQueue) SetReadDeadline(t time.Time) error {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func (this *ReceivingQueue) Close() {
 | 
	
		
			
				|  |  | +	this.Lock()
 | 
	
		
			
				|  |  | +	defer this.Unlock()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	if this.closed {
 | 
	
		
			
				|  |  |  		return
 | 
	
		
			
				|  |  |  	}
 | 
	
	
		
			
				|  | @@ -141,6 +148,7 @@ func (this *ReceivingQueue) Close() {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  type AckList struct {
 | 
	
		
			
				|  |  | +	sync.Mutex
 | 
	
		
			
				|  |  |  	writer     SegmentWriter
 | 
	
		
			
				|  |  |  	timestamps []uint32
 | 
	
		
			
				|  |  |  	numbers    []uint32
 | 
	
	
		
			
				|  | @@ -157,12 +165,18 @@ func NewACKList(writer SegmentWriter) *AckList {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func (this *AckList) Add(number uint32, timestamp uint32) {
 | 
	
		
			
				|  |  | +	this.Lock()
 | 
	
		
			
				|  |  | +	defer this.Unlock()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	this.timestamps = append(this.timestamps, timestamp)
 | 
	
		
			
				|  |  |  	this.numbers = append(this.numbers, number)
 | 
	
		
			
				|  |  |  	this.nextFlush = append(this.nextFlush, 0)
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func (this *AckList) Clear(una uint32) {
 | 
	
		
			
				|  |  | +	this.Lock()
 | 
	
		
			
				|  |  | +	defer this.Unlock()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	count := 0
 | 
	
		
			
				|  |  |  	for i := 0; i < len(this.numbers); i++ {
 | 
	
		
			
				|  |  |  		if this.numbers[i] >= una {
 | 
	
	
		
			
				|  | @@ -181,33 +195,35 @@ func (this *AckList) Clear(una uint32) {
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -func (this *AckList) Flush(current uint32) {
 | 
	
		
			
				|  |  | +func (this *AckList) Flush(current uint32, rto uint32) {
 | 
	
		
			
				|  |  |  	seg := new(AckSegment)
 | 
	
		
			
				|  |  | +	this.Lock()
 | 
	
		
			
				|  |  |  	for i := 0; i < len(this.numbers); i++ {
 | 
	
		
			
				|  |  |  		if this.nextFlush[i] <= current {
 | 
	
		
			
				|  |  |  			seg.Count++
 | 
	
		
			
				|  |  |  			seg.NumberList = append(seg.NumberList, this.numbers[i])
 | 
	
		
			
				|  |  |  			seg.TimestampList = append(seg.TimestampList, this.timestamps[i])
 | 
	
		
			
				|  |  | -			this.nextFlush[i] = current + 100
 | 
	
		
			
				|  |  | +			this.nextFlush[i] = current + rto/2
 | 
	
		
			
				|  |  |  			if seg.Count == 128 {
 | 
	
		
			
				|  |  |  				break
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | +	this.Unlock()
 | 
	
		
			
				|  |  |  	if seg.Count > 0 {
 | 
	
		
			
				|  |  |  		this.writer.Write(seg)
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  type ReceivingWorker struct {
 | 
	
		
			
				|  |  | -	sync.Mutex
 | 
	
		
			
				|  |  | -	kcp        *KCP
 | 
	
		
			
				|  |  | -	queue      *ReceivingQueue
 | 
	
		
			
				|  |  | -	window     *ReceivingWindow
 | 
	
		
			
				|  |  | -	acklist    *AckList
 | 
	
		
			
				|  |  | -	updated    bool
 | 
	
		
			
				|  |  | -	nextNumber uint32
 | 
	
		
			
				|  |  | -	windowSize uint32
 | 
	
		
			
				|  |  | +	kcp         *KCP
 | 
	
		
			
				|  |  | +	queue       *ReceivingQueue
 | 
	
		
			
				|  |  | +	window      *ReceivingWindow
 | 
	
		
			
				|  |  | +	windowMutex sync.Mutex
 | 
	
		
			
				|  |  | +	acklist     *AckList
 | 
	
		
			
				|  |  | +	updated     bool
 | 
	
		
			
				|  |  | +	nextNumber  uint32
 | 
	
		
			
				|  |  | +	windowSize  uint32
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func NewReceivingWorker(kcp *KCP) *ReceivingWorker {
 | 
	
	
		
			
				|  | @@ -223,9 +239,6 @@ func NewReceivingWorker(kcp *KCP) *ReceivingWorker {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func (this *ReceivingWorker) ProcessSendingNext(number uint32) {
 | 
	
		
			
				|  |  | -	this.Lock()
 | 
	
		
			
				|  |  | -	defer this.Unlock()
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  	this.acklist.Clear(number)
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -237,23 +250,22 @@ func (this *ReceivingWorker) ProcessSegment(seg *DataSegment) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	this.ProcessSendingNext(seg.SendingNext)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	this.Lock()
 | 
	
		
			
				|  |  |  	this.acklist.Add(number, seg.Timestamp)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +	this.windowMutex.Lock()
 | 
	
		
			
				|  |  |  	idx := number - this.nextNumber
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	if !this.window.Set(idx, seg) {
 | 
	
		
			
				|  |  |  		seg.Release()
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	this.Unlock()
 | 
	
		
			
				|  |  | +	this.windowMutex.Unlock()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	this.DumpWindow()
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // @Private
 | 
	
		
			
				|  |  |  func (this *ReceivingWorker) DumpWindow() {
 | 
	
		
			
				|  |  | -	this.Lock()
 | 
	
		
			
				|  |  | -	defer this.Unlock()
 | 
	
		
			
				|  |  | +	this.windowMutex.Lock()
 | 
	
		
			
				|  |  | +	defer this.windowMutex.Unlock()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	for {
 | 
	
		
			
				|  |  |  		seg := this.window.RemoveFirst()
 | 
	
	
		
			
				|  | @@ -278,17 +290,11 @@ func (this *ReceivingWorker) Read(b []byte) (int, error) {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func (this *ReceivingWorker) SetReadDeadline(t time.Time) {
 | 
	
		
			
				|  |  | -	this.Lock()
 | 
	
		
			
				|  |  | -	defer this.Unlock()
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  	this.queue.SetReadDeadline(t)
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func (this *ReceivingWorker) Flush() {
 | 
	
		
			
				|  |  | -	this.Lock()
 | 
	
		
			
				|  |  | -	defer this.Unlock()
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	this.acklist.Flush(this.kcp.current)
 | 
	
		
			
				|  |  | +	this.acklist.Flush(this.kcp.current, this.kcp.rx_rto)
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func (this *ReceivingWorker) Write(seg ISegment) {
 | 
	
	
		
			
				|  | @@ -304,9 +310,6 @@ func (this *ReceivingWorker) Write(seg ISegment) {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func (this *ReceivingWorker) CloseRead() {
 | 
	
		
			
				|  |  | -	this.Lock()
 | 
	
		
			
				|  |  | -	defer this.Unlock()
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  	this.queue.Close()
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 |