Fix race condition in ReadPacket
This commit is contained in:
parent
e9e3fbf0c1
commit
6516c2d8f1
1 changed files with 9 additions and 2 deletions
|
|
@ -395,15 +395,16 @@ retry:
|
||||||
|
|
||||||
func (t *NativeTun) ReadPacket() ([]byte, func(), error) {
|
func (t *NativeTun) ReadPacket() ([]byte, func(), error) {
|
||||||
t.running.Add(1)
|
t.running.Add(1)
|
||||||
defer t.running.Done()
|
|
||||||
retry:
|
retry:
|
||||||
if t.close.Load() == 1 {
|
if t.close.Load() == 1 {
|
||||||
|
t.running.Done()
|
||||||
return nil, nil, os.ErrClosed
|
return nil, nil, os.ErrClosed
|
||||||
}
|
}
|
||||||
start := nanotime()
|
start := nanotime()
|
||||||
shouldSpin := t.rate.current.Load() >= spinloopRateThreshold && uint64(start-t.rate.nextStartTime.Load()) <= rateMeasurementGranularity*2
|
shouldSpin := t.rate.current.Load() >= spinloopRateThreshold && uint64(start-t.rate.nextStartTime.Load()) <= rateMeasurementGranularity*2
|
||||||
for {
|
for {
|
||||||
if t.close.Load() == 1 {
|
if t.close.Load() == 1 {
|
||||||
|
t.running.Done()
|
||||||
return nil, nil, os.ErrClosed
|
return nil, nil, os.ErrClosed
|
||||||
}
|
}
|
||||||
packet, err := t.session.ReceivePacket()
|
packet, err := t.session.ReceivePacket()
|
||||||
|
|
@ -411,7 +412,10 @@ retry:
|
||||||
case nil:
|
case nil:
|
||||||
packetSize := len(packet)
|
packetSize := len(packet)
|
||||||
t.rate.update(uint64(packetSize))
|
t.rate.update(uint64(packetSize))
|
||||||
return packet, func() { t.session.ReleaseReceivePacket(packet) }, nil
|
return packet, func() {
|
||||||
|
t.session.ReleaseReceivePacket(packet)
|
||||||
|
t.running.Done()
|
||||||
|
}, nil
|
||||||
case windows.ERROR_NO_MORE_ITEMS:
|
case windows.ERROR_NO_MORE_ITEMS:
|
||||||
if !shouldSpin || uint64(nanotime()-start) >= spinloopDuration {
|
if !shouldSpin || uint64(nanotime()-start) >= spinloopDuration {
|
||||||
windows.WaitForSingleObject(t.readWait, windows.INFINITE)
|
windows.WaitForSingleObject(t.readWait, windows.INFINITE)
|
||||||
|
|
@ -420,10 +424,13 @@ retry:
|
||||||
procyield(1)
|
procyield(1)
|
||||||
continue
|
continue
|
||||||
case windows.ERROR_HANDLE_EOF:
|
case windows.ERROR_HANDLE_EOF:
|
||||||
|
t.running.Done()
|
||||||
return nil, nil, os.ErrClosed
|
return nil, nil, os.ErrClosed
|
||||||
case windows.ERROR_INVALID_DATA:
|
case windows.ERROR_INVALID_DATA:
|
||||||
|
t.running.Done()
|
||||||
return nil, nil, errors.New("send ring corrupt")
|
return nil, nil, errors.New("send ring corrupt")
|
||||||
}
|
}
|
||||||
|
t.running.Done()
|
||||||
return nil, nil, fmt.Errorf("read failed: %w", err)
|
return nil, nil, fmt.Errorf("read failed: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue