wintun: Check for user close in read loop regardless the load

Do the WaitForSingleObject() always to provide high-load responsiveness.

Reorder events so TUN_SIGNAL_CLOSE has priority over
TUN_SIGNAL_DATA_AVAIL, to provide high-load responsiveness at all.

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2019-02-08 08:48:35 +01:00
parent b13739ada2
commit 5981d5cacf

View file

@ -22,10 +22,10 @@ const (
)
const (
TUN_SIGNAL_DATA_AVAIL = 0
TUN_SIGNAL_CLOSE = 1
TUN_SIGNAL_CLOSE = iota
TUN_SIGNAL_DATA_AVAIL
TUN_SIGNAL_MAX = 2
TUN_SIGNAL_MAX
)
type tunPacket struct {
@ -229,28 +229,26 @@ func (tun *nativeTun) Read(buff []byte, offset int) (int, error) {
}
}
if tun.rdBuff.numPackets < TUN_MAX_PACKET_EXCHANGE || !tun.rdBuff.left {
// Buffer was not full. Wait for the interface data or user close.
// Wait for user close or interface data.
r, err := windows.WaitForMultipleObjects(tun.signals[:], false, windows.INFINITE)
if err != nil {
return 0, errors.New("Waiting for data failed: " + err.Error())
}
switch r {
case windows.WAIT_OBJECT_0 + TUN_SIGNAL_CLOSE, windows.WAIT_ABANDONED + TUN_SIGNAL_CLOSE:
return 0, errors.New("TUN closed")
case windows.WAIT_OBJECT_0 + TUN_SIGNAL_DATA_AVAIL:
// Data is available.
case windows.WAIT_ABANDONED + TUN_SIGNAL_DATA_AVAIL:
// TUN stopped. Reopen it.
tun.closeTUN()
continue
case windows.WAIT_OBJECT_0 + TUN_SIGNAL_CLOSE, windows.WAIT_ABANDONED + TUN_SIGNAL_CLOSE:
return 0, errors.New("TUN closed")
case windows.WAIT_TIMEOUT:
// Congratulations, we reached infinity. Let's do it again! :)
continue
default:
return 0, errors.New("unexpected result from WaitForMultipleObjects")
}
}
// Fill queue.
data := (*[TUN_EXCHANGE_BUFFER_SIZE]byte)(unsafe.Pointer(&tun.rdBuff))