Merge pull request #379 from magiconair/fix-host-boottime-race

Fix data race in host.BootTime
tags/v2.17.05 v2.17.05
shirou 8 years ago committed by GitHub
commit e30b7839cd

@ -6,10 +6,7 @@ import (
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
) )
var ( var invoke common.Invoker
invoke common.Invoker
cachedBootTime = uint64(0)
)
func init() { func init() {
invoke = common.Invoke{} invoke = common.Invoke{}

@ -11,6 +11,7 @@ import (
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"sync/atomic"
"time" "time"
"unsafe" "unsafe"
@ -72,9 +73,13 @@ func Info() (*InfoStat, error) {
return ret, nil return ret, nil
} }
// cachedBootTime must be accessed via atomic.Load/StoreUint64
var cachedBootTime uint64
func BootTime() (uint64, error) { func BootTime() (uint64, error) {
if cachedBootTime != 0 { t := atomic.LoadUint64(&cachedBootTime)
return cachedBootTime, nil if t != 0 {
return t, nil
} }
values, err := common.DoSysctrl("kern.boottime") values, err := common.DoSysctrl("kern.boottime")
if err != nil { if err != nil {
@ -86,9 +91,10 @@ func BootTime() (uint64, error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
cachedBootTime = uint64(boottime) t = uint64(boottime)
atomic.StoreUint64(&cachedBootTime, t)
return cachedBootTime, nil return t, nil
} }
func uptime(boot uint64) uint64 { func uptime(boot uint64) uint64 {

@ -11,6 +11,7 @@ import (
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"sync/atomic"
"time" "time"
"unsafe" "unsafe"
@ -68,9 +69,13 @@ func Info() (*InfoStat, error) {
return ret, nil return ret, nil
} }
// cachedBootTime must be accessed via atomic.Load/StoreUint64
var cachedBootTime uint64
func BootTime() (uint64, error) { func BootTime() (uint64, error) {
if cachedBootTime != 0 { t := atomic.LoadUint64(&cachedBootTime)
return cachedBootTime, nil if t != 0 {
return t, nil
} }
values, err := common.DoSysctrl("kern.boottime") values, err := common.DoSysctrl("kern.boottime")
if err != nil { if err != nil {
@ -83,9 +88,10 @@ func BootTime() (uint64, error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
cachedBootTime = boottime t = uint64(boottime)
atomic.StoreUint64(&cachedBootTime, t)
return boottime, nil return t, nil
} }
func uptime(boot uint64) uint64 { func uptime(boot uint64) uint64 {

@ -14,6 +14,7 @@ import (
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"sync/atomic"
"time" "time"
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
@ -85,10 +86,14 @@ func Info() (*InfoStat, error) {
return ret, nil return ret, nil
} }
// cachedBootTime must be accessed via atomic.Load/StoreUint64
var cachedBootTime uint64
// BootTime returns the system boot time expressed in seconds since the epoch. // BootTime returns the system boot time expressed in seconds since the epoch.
func BootTime() (uint64, error) { func BootTime() (uint64, error) {
if cachedBootTime != 0 { t := atomic.LoadUint64(&cachedBootTime)
return cachedBootTime, nil if t != 0 {
return t, nil
} }
filename := common.HostProc("stat") filename := common.HostProc("stat")
lines, err := common.ReadLines(filename) lines, err := common.ReadLines(filename)
@ -105,8 +110,9 @@ func BootTime() (uint64, error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
cachedBootTime = uint64(b) t = uint64(b)
return cachedBootTime, nil atomic.StoreUint64(&cachedBootTime, t)
return t, nil
} }
} }

@ -7,6 +7,7 @@ import (
"os" "os"
"runtime" "runtime"
"strings" "strings"
"sync/atomic"
"syscall" "syscall"
"time" "time"
"unsafe" "unsafe"
@ -135,16 +136,21 @@ func bootTime(up uint64) uint64 {
return uint64(time.Now().Unix()) - up return uint64(time.Now().Unix()) - up
} }
// cachedBootTime must be accessed via atomic.Load/StoreUint64
var cachedBootTime uint64
func BootTime() (uint64, error) { func BootTime() (uint64, error) {
if cachedBootTime != 0 { t := atomic.LoadUint64(&cachedBootTime)
return cachedBootTime, nil if t != 0 {
return t, nil
} }
up, err := Uptime() up, err := Uptime()
if err != nil { if err != nil {
return 0, err return 0, err
} }
cachedBootTime = bootTime(up) t = bootTime(up)
return cachedBootTime, nil atomic.StoreUint64(&cachedBootTime, t)
return t, nil
} }
func PlatformInformation() (platform string, family string, version string, err error) { func PlatformInformation() (platform string, family string, version string, err error) {

Loading…
Cancel
Save