Skip to content

Commit

Permalink
Fix data race in host.BootTime
Browse files Browse the repository at this point in the history
  • Loading branch information
magiconair committed Jun 1, 2017
1 parent 3e0b91b commit a9e803e
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 20 deletions.
5 changes: 1 addition & 4 deletions host/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import (
"github.com/shirou/gopsutil/internal/common"
)

var (
invoke common.Invoker
cachedBootTime = uint64(0)
)
var invoke common.Invoker

func init() {
invoke = common.Invoke{}
Expand Down
14 changes: 10 additions & 4 deletions host/host_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"runtime"
"strconv"
"strings"
"sync/atomic"
"time"
"unsafe"

Expand Down Expand Up @@ -72,9 +73,13 @@ func Info() (*InfoStat, error) {
return ret, nil
}

// cachedBootTime must be accessed via atomic.Load/StoreUint64
var cachedBootTime uint64

func BootTime() (uint64, error) {
if cachedBootTime != 0 {
return cachedBootTime, nil
t := atomic.LoadUint64(&cachedBootTime)
if t != 0 {
return t, nil
}
values, err := common.DoSysctrl("kern.boottime")
if err != nil {
Expand All @@ -86,9 +91,10 @@ func BootTime() (uint64, error) {
if err != nil {
return 0, err
}
cachedBootTime = uint64(boottime)
t = uint64(boottime)
atomic.StoreUint64(&cachedBootTime, t)

return cachedBootTime, nil
return t, nil
}

func uptime(boot uint64) uint64 {
Expand Down
14 changes: 10 additions & 4 deletions host/host_freebsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"runtime"
"strconv"
"strings"
"sync/atomic"
"time"
"unsafe"

Expand Down Expand Up @@ -68,9 +69,13 @@ func Info() (*InfoStat, error) {
return ret, nil
}

// cachedBootTime must be accessed via atomic.Load/StoreUint64
var cachedBootTime uint64

func BootTime() (uint64, error) {
if cachedBootTime != 0 {
return cachedBootTime, nil
t := atomic.LoadUint64(&cachedBootTime)
if t != 0 {
return t, nil
}
values, err := common.DoSysctrl("kern.boottime")
if err != nil {
Expand All @@ -83,9 +88,10 @@ func BootTime() (uint64, error) {
if err != nil {
return 0, err
}
cachedBootTime = boottime
t = uint64(boottime)
atomic.StoreUint64(&cachedBootTime, t)

return boottime, nil
return t, nil
}

func uptime(boot uint64) uint64 {
Expand Down
14 changes: 10 additions & 4 deletions host/host_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"runtime"
"strconv"
"strings"
"sync/atomic"
"time"

"github.com/shirou/gopsutil/internal/common"
Expand Down Expand Up @@ -85,10 +86,14 @@ func Info() (*InfoStat, error) {
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.
func BootTime() (uint64, error) {
if cachedBootTime != 0 {
return cachedBootTime, nil
t := atomic.LoadUint64(&cachedBootTime)
if t != 0 {
return t, nil
}
filename := common.HostProc("stat")
lines, err := common.ReadLines(filename)
Expand All @@ -105,8 +110,9 @@ func BootTime() (uint64, error) {
if err != nil {
return 0, err
}
cachedBootTime = uint64(b)
return cachedBootTime, nil
t = uint64(b)
atomic.StoreUint64(&cachedBootTime, t)
return t, nil
}
}

Expand Down
14 changes: 10 additions & 4 deletions host/host_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"runtime"
"strings"
"sync/atomic"
"syscall"
"time"
"unsafe"
Expand Down Expand Up @@ -135,16 +136,21 @@ func bootTime(up uint64) uint64 {
return uint64(time.Now().Unix()) - up
}

// cachedBootTime must be accessed via atomic.Load/StoreUint64
var cachedBootTime uint64

func BootTime() (uint64, error) {
if cachedBootTime != 0 {
return cachedBootTime, nil
t := atomic.LoadUint64(&cachedBootTime)
if t != 0 {
return t, nil
}
up, err := Uptime()
if err != nil {
return 0, err
}
cachedBootTime = bootTime(up)
return cachedBootTime, nil
t = bootTime(up)
atomic.StoreUint64(&cachedBootTime, t)
return t, nil
}

func PlatformInformation() (platform string, family string, version string, err error) {
Expand Down

0 comments on commit a9e803e

Please sign in to comment.