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,27 +229,25 @@ 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:
case windows.WAIT_OBJECT_0 + TUN_SIGNAL_DATA_AVAIL: return 0, errors.New("TUN closed")
// Data is available. case windows.WAIT_OBJECT_0 + TUN_SIGNAL_DATA_AVAIL:
case windows.WAIT_ABANDONED + TUN_SIGNAL_DATA_AVAIL: // Data is available.
// TUN stopped. Reopen it. case windows.WAIT_ABANDONED + TUN_SIGNAL_DATA_AVAIL:
tun.closeTUN() // TUN stopped. Reopen it.
continue tun.closeTUN()
case windows.WAIT_OBJECT_0 + TUN_SIGNAL_CLOSE, windows.WAIT_ABANDONED + TUN_SIGNAL_CLOSE: continue
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.