From bbcfbd66002c4aa1b2d8fd7e10a71c930b66da49 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Sun, 15 Mar 2015 19:04:20 +0300 Subject: [PATCH] Keep TAP listener state and skip sinkReady step if necessary Signed-off-by: Sergey Matveev --- tap.go | 22 ++++++++++++---------- transport.go | 16 +++++++++++----- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/tap.go b/tap.go index 85926d7..4fee83a 100644 --- a/tap.go +++ b/tap.go @@ -26,11 +26,12 @@ import ( ) type TAP struct { - Name string - dev io.ReadWriter - buf []byte - sink chan []byte - ready chan struct{} + Name string + dev io.ReadWriter + buf []byte + sink chan []byte + ready chan struct{} + synced bool } func NewTAP(ifaceName string) (*TAP, error) { @@ -40,11 +41,12 @@ func NewTAP(ifaceName string) (*TAP, error) { return nil, err } tap := TAP{ - Name: ifaceName, - dev: tapRaw, - buf: make([]byte, maxIfacePktSize), - sink: make(chan []byte), - ready: make(chan struct{}), + Name: ifaceName, + dev: tapRaw, + buf: make([]byte, maxIfacePktSize), + sink: make(chan []byte), + ready: make(chan struct{}), + synced: false, } go func() { var n int diff --git a/transport.go b/transport.go index 8c5e8eb..d72fcc1 100644 --- a/transport.go +++ b/transport.go @@ -102,6 +102,7 @@ func TAPListen(ifaceName string) (*TAP, chan []byte, chan struct{}, chan struct{ sink := make(chan []byte) sinkReady := make(chan struct{}) sinkTerminate := make(chan struct{}) + sinkSkip := make(chan struct{}) go func() { heartbeat := time.Tick(heartbeatPeriodGet()) @@ -114,12 +115,10 @@ func TAPListen(ifaceName string) (*TAP, chan []byte, chan struct{}, chan struct{ case <-heartbeat: go func() { sink <- make([]byte, 0) }() continue + case <-sinkSkip: case <-sinkReady: - if exists { - exists = false - break - } tap.ready <- struct{}{} + tap.synced = true } HeartbeatCatched: select { @@ -129,12 +128,19 @@ func TAPListen(ifaceName string) (*TAP, chan []byte, chan struct{}, chan struct{ case <-sinkTerminate: break ListenCycle case pkt = <-tap.sink: + tap.synced = false sink <- pkt } } close(sink) + close(sinkReady) + close(sinkTerminate) }() - sinkReady <- struct{}{} + if exists && tap.synced { + sinkSkip <- struct{}{} + } else { + sinkReady <- struct{}{} + } return tap, sink, sinkReady, sinkTerminate, nil } -- 2.48.1