Fix VirtualizationWithContext() race in linux

pull/951/head
Ryan Fitzpatrick 5 years ago
parent 42136c7364
commit 8046134504
No known key found for this signature in database
GPG Key ID: 9F7EB60FAB09FE12

@ -3,6 +3,7 @@ package host
import ( import (
"fmt" "fmt"
"os" "os"
"sync"
"testing" "testing"
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
@ -144,13 +145,24 @@ func TestTemperatureStat_String(t *testing.T) {
} }
func TestVirtualization(t *testing.T) { func TestVirtualization(t *testing.T) {
system, role, err := Virtualization() wg := sync.WaitGroup{}
skipIfNotImplementedErr(t, err) testCount := 10
if err != nil { wg.Add(testCount)
t.Errorf("Virtualization() failed, %v", err) for i := 0; i < testCount; i++ {
} go func(j int) {
system, role, err := Virtualization()
t.Logf("Virtualization(): %s, %s", system, role) wg.Done()
skipIfNotImplementedErr(t, err)
if err != nil {
t.Errorf("Virtualization() failed, %v", err)
}
if j == 9 {
t.Logf("Virtualization(): %s, %s", system, role)
}
}(i)
}
wg.Wait()
} }
func TestKernelVersion(t *testing.T) { func TestKernelVersion(t *testing.T) {

@ -10,6 +10,7 @@ import (
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
) )
@ -110,17 +111,50 @@ func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background()) return VirtualizationWithContext(context.Background())
} }
var virtualizationCache map[string]string type virtCache struct {
cache map[string]string
lock sync.Mutex
ok bool
}
func (v *virtCache) setValue(system, role string) {
v.lock.Lock()
defer v.lock.Unlock()
v.cache["system"] = system
v.cache["role"] = role
v.ok = true
}
func (v *virtCache) getValue() (string, string, bool) {
v.lock.Lock()
defer v.lock.Unlock()
return v.cache["system"], v.cache["role"], v.ok
}
var (
once sync.Once
virtualization *virtCache
)
func virtualizationCache() *virtCache {
once.Do(func() {
virtualization = &virtCache{
cache: make(map[string]string),
lock: sync.Mutex{},
ok: false,
}
})
return virtualization
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) { func VirtualizationWithContext(ctx context.Context) (string, string, error) {
// if cached already, return from cache // if cached already, return from cache
if virtualizationCache != nil { system, role, ok := virtualizationCache().getValue()
return virtualizationCache["system"], virtualizationCache["role"], nil if ok {
return system, role, nil
} }
var system string
var role string
filename := HostProc("xen") filename := HostProc("xen")
if PathExists(filename) { if PathExists(filename) {
system = "xen" system = "xen"
@ -240,11 +274,7 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) {
} }
// before returning for the first time, cache the system and role // before returning for the first time, cache the system and role
virtualizationCache = map[string]string{ virtualizationCache().setValue(system, role)
"system": system,
"role": role,
}
return system, role, nil return system, role, nil
} }

Loading…
Cancel
Save