aboutsummaryrefslogtreecommitdiff
path: root/src/net/interface.go
diff options
context:
space:
mode:
authorMichael Stapelberg <stapelberg@google.com>2018-11-02 11:23:54 +0100
committerMikio Hara <mikioh.public.networking@gmail.com>2018-11-06 00:05:32 +0000
commit9fc22d29092933460fe00bdaccea179f29e9960d (patch)
tree74b30bd25c397797fd3d4baa82aecf0ef89cf7f2 /src/net/interface.go
parent5848b6c9b854546473814c8752ee117a71bb8b54 (diff)
downloadgo-9fc22d29092933460fe00bdaccea179f29e9960d.tar.xz
net: update zoneCache on cache misses to cover appearing interfaces
performance differences are in measurement noise as per benchcmp: benchmark old ns/op new ns/op delta BenchmarkUDP6LinkLocalUnicast-12 5012 5009 -0.06% Fixes #28535 Change-Id: Id022e2ed089ce8388a2398e755848ec94e77e653 Reviewed-on: https://go-review.googlesource.com/c/146941 Run-TryBot: Mikio Hara <mikioh.public.networking@gmail.com> Reviewed-by: Mikio Hara <mikioh.public.networking@gmail.com>
Diffstat (limited to 'src/net/interface.go')
-rw-r--r--src/net/interface.go40
1 files changed, 30 insertions, 10 deletions
diff --git a/src/net/interface.go b/src/net/interface.go
index 375a4568e3..46b0400f2f 100644
--- a/src/net/interface.go
+++ b/src/net/interface.go
@@ -102,7 +102,7 @@ func Interfaces() ([]Interface, error) {
return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
}
if len(ift) != 0 {
- zoneCache.update(ift)
+ zoneCache.update(ift, false)
}
return ift, nil
}
@@ -159,7 +159,7 @@ func InterfaceByName(name string) (*Interface, error) {
return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
}
if len(ift) != 0 {
- zoneCache.update(ift)
+ zoneCache.update(ift, false)
}
for _, ifi := range ift {
if name == ifi.Name {
@@ -187,18 +187,21 @@ var zoneCache = ipv6ZoneCache{
toName: make(map[int]string),
}
-func (zc *ipv6ZoneCache) update(ift []Interface) {
+// update refreshes the network interface information if the cache was last
+// updated more than 1 minute ago, or if force is set. It returns whether the
+// cache was updated.
+func (zc *ipv6ZoneCache) update(ift []Interface, force bool) (updated bool) {
zc.Lock()
defer zc.Unlock()
now := time.Now()
- if zc.lastFetched.After(now.Add(-60 * time.Second)) {
- return
+ if !force && zc.lastFetched.After(now.Add(-60*time.Second)) {
+ return false
}
zc.lastFetched = now
if len(ift) == 0 {
var err error
if ift, err = interfaceTable(0); err != nil {
- return
+ return false
}
}
zc.toIndex = make(map[string]int, len(ift))
@@ -209,16 +212,25 @@ func (zc *ipv6ZoneCache) update(ift []Interface) {
zc.toName[ifi.Index] = ifi.Name
}
}
+ return true
}
func (zc *ipv6ZoneCache) name(index int) string {
if index == 0 {
return ""
}
- zoneCache.update(nil)
+ updated := zoneCache.update(nil, false)
zoneCache.RLock()
- defer zoneCache.RUnlock()
name, ok := zoneCache.toName[index]
+ zoneCache.RUnlock()
+ if !ok {
+ if !updated {
+ zoneCache.update(nil, true)
+ zoneCache.RLock()
+ name, ok = zoneCache.toName[index]
+ zoneCache.RUnlock()
+ }
+ }
if !ok {
name = uitoa(uint(index))
}
@@ -229,10 +241,18 @@ func (zc *ipv6ZoneCache) index(name string) int {
if name == "" {
return 0
}
- zoneCache.update(nil)
+ updated := zoneCache.update(nil, false)
zoneCache.RLock()
- defer zoneCache.RUnlock()
index, ok := zoneCache.toIndex[name]
+ zoneCache.RUnlock()
+ if !ok {
+ if !updated {
+ zoneCache.update(nil, true)
+ zoneCache.RLock()
+ index, ok = zoneCache.toIndex[name]
+ zoneCache.RUnlock()
+ }
+ }
if !ok {
index, _, _ = dtoi(name)
}