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